Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / upb / upb / sink.h
1 /*
2 ** upb::Sink (upb_sink)
3 ** upb::BytesSink (upb_bytessink)
4 **
5 ** A upb_sink is an object that binds a upb_handlers object to some runtime
6 ** state.  It is the object that can actually receive data via the upb_handlers
7 ** interface.
8 **
9 ** Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or
10 ** thread-safe.  You can create as many of them as you want, but each one may
11 ** only be used in a single thread at a time.
12 **
13 ** If we compare with class-based OOP, a you can think of a upb_def as an
14 ** abstract base class, a upb_handlers as a concrete derived class, and a
15 ** upb_sink as an object (class instance).
16 */
17
18 #ifndef UPB_SINK_H
19 #define UPB_SINK_H
20
21 #include "upb/handlers.h"
22
23 #include "upb/port_def.inc"
24
25 #ifdef __cplusplus
26 namespace upb {
27 class BytesSink;
28 class Sink;
29 }
30 #endif
31
32 /* upb_sink *******************************************************************/
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 typedef struct {
39   const upb_handlers *handlers;
40   void *closure;
41 } upb_sink;
42
43 #define PUTVAL(type, ctype)                                           \
44   UPB_INLINE bool upb_sink_put##type(upb_sink s, upb_selector_t sel,  \
45                                      ctype val) {                     \
46     typedef upb_##type##_handlerfunc functype;                        \
47     functype *func;                                                   \
48     const void *hd;                                                   \
49     if (!s.handlers) return true;                                     \
50     func = (functype *)upb_handlers_gethandler(s.handlers, sel, &hd); \
51     if (!func) return true;                                           \
52     return func(s.closure, hd, val);                                  \
53   }
54
55 PUTVAL(int32,  int32_t)
56 PUTVAL(int64,  int64_t)
57 PUTVAL(uint32, uint32_t)
58 PUTVAL(uint64, uint64_t)
59 PUTVAL(float,  float)
60 PUTVAL(double, double)
61 PUTVAL(bool,   bool)
62 #undef PUTVAL
63
64 UPB_INLINE void upb_sink_reset(upb_sink *s, const upb_handlers *h, void *c) {
65   s->handlers = h;
66   s->closure = c;
67 }
68
69 UPB_INLINE size_t upb_sink_putstring(upb_sink s, upb_selector_t sel,
70                                      const char *buf, size_t n,
71                                      const upb_bufhandle *handle) {
72   typedef upb_string_handlerfunc func;
73   func *handler;
74   const void *hd;
75   if (!s.handlers) return n;
76   handler = (func *)upb_handlers_gethandler(s.handlers, sel, &hd);
77
78   if (!handler) return n;
79   return handler(s.closure, hd, buf, n, handle);
80 }
81
82 UPB_INLINE bool upb_sink_putunknown(upb_sink s, const char *buf, size_t n) {
83   typedef upb_unknown_handlerfunc func;
84   func *handler;
85   const void *hd;
86   if (!s.handlers) return true;
87   handler =
88       (func *)upb_handlers_gethandler(s.handlers, UPB_UNKNOWN_SELECTOR, &hd);
89
90   if (!handler) return n;
91   return handler(s.closure, hd, buf, n);
92 }
93
94 UPB_INLINE bool upb_sink_startmsg(upb_sink s) {
95   typedef upb_startmsg_handlerfunc func;
96   func *startmsg;
97   const void *hd;
98   if (!s.handlers) return true;
99   startmsg =
100       (func *)upb_handlers_gethandler(s.handlers, UPB_STARTMSG_SELECTOR, &hd);
101
102   if (!startmsg) return true;
103   return startmsg(s.closure, hd);
104 }
105
106 UPB_INLINE bool upb_sink_endmsg(upb_sink s, upb_status *status) {
107   typedef upb_endmsg_handlerfunc func;
108   func *endmsg;
109   const void *hd;
110   if (!s.handlers) return true;
111   endmsg =
112       (func *)upb_handlers_gethandler(s.handlers, UPB_ENDMSG_SELECTOR, &hd);
113
114   if (!endmsg) return true;
115   return endmsg(s.closure, hd, status);
116 }
117
118 UPB_INLINE bool upb_sink_startseq(upb_sink s, upb_selector_t sel,
119                                   upb_sink *sub) {
120   typedef upb_startfield_handlerfunc func;
121   func *startseq;
122   const void *hd;
123   sub->closure = s.closure;
124   sub->handlers = s.handlers;
125   if (!s.handlers) return true;
126   startseq = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
127
128   if (!startseq) return true;
129   sub->closure = startseq(s.closure, hd);
130   return sub->closure ? true : false;
131 }
132
133 UPB_INLINE bool upb_sink_endseq(upb_sink s, upb_selector_t sel) {
134   typedef upb_endfield_handlerfunc func;
135   func *endseq;
136   const void *hd;
137   if (!s.handlers) return true;
138   endseq = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
139
140   if (!endseq) return true;
141   return endseq(s.closure, hd);
142 }
143
144 UPB_INLINE bool upb_sink_startstr(upb_sink s, upb_selector_t sel,
145                                   size_t size_hint, upb_sink *sub) {
146   typedef upb_startstr_handlerfunc func;
147   func *startstr;
148   const void *hd;
149   sub->closure = s.closure;
150   sub->handlers = s.handlers;
151   if (!s.handlers) return true;
152   startstr = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
153
154   if (!startstr) return true;
155   sub->closure = startstr(s.closure, hd, size_hint);
156   return sub->closure ? true : false;
157 }
158
159 UPB_INLINE bool upb_sink_endstr(upb_sink s, upb_selector_t sel) {
160   typedef upb_endfield_handlerfunc func;
161   func *endstr;
162   const void *hd;
163   if (!s.handlers) return true;
164   endstr = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
165
166   if (!endstr) return true;
167   return endstr(s.closure, hd);
168 }
169
170 UPB_INLINE bool upb_sink_startsubmsg(upb_sink s, upb_selector_t sel,
171                                      upb_sink *sub) {
172   typedef upb_startfield_handlerfunc func;
173   func *startsubmsg;
174   const void *hd;
175   sub->closure = s.closure;
176   if (!s.handlers) {
177     sub->handlers = NULL;
178     return true;
179   }
180   sub->handlers = upb_handlers_getsubhandlers_sel(s.handlers, sel);
181   startsubmsg = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
182
183   if (!startsubmsg) return true;
184   sub->closure = startsubmsg(s.closure, hd);
185   return sub->closure ? true : false;
186 }
187
188 UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_selector_t sel) {
189   typedef upb_endfield_handlerfunc func;
190   func *endsubmsg;
191   const void *hd;
192   if (!s.handlers) return true;
193   endsubmsg = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
194
195   if (!endsubmsg) return s.closure;
196   return endsubmsg(s.closure, hd);
197 }
198
199 #ifdef __cplusplus
200 }  /* extern "C" */
201
202 /* A upb::Sink is an object that binds a upb::Handlers object to some runtime
203  * state.  It represents an endpoint to which data can be sent.
204  *
205  * TODO(haberman): right now all of these functions take selectors.  Should they
206  * take selectorbase instead?
207  *
208  * ie. instead of calling:
209  *   sink->StartString(FOO_FIELD_START_STRING, ...)
210  * a selector base would let you say:
211  *   sink->StartString(FOO_FIELD, ...)
212  *
213  * This would make call sites a little nicer and require emitting fewer selector
214  * definitions in .h files.
215  *
216  * But the current scheme has the benefit that you can retrieve a function
217  * pointer for any handler with handlers->GetHandler(selector), without having
218  * to have a separate GetHandler() function for each handler type.  The JIT
219  * compiler uses this.  To accommodate we'd have to expose a separate
220  * GetHandler() for every handler type.
221  *
222  * Also to ponder: selectors right now are independent of a specific Handlers
223  * instance.  In other words, they allocate a number to every possible handler
224  * that *could* be registered, without knowing anything about what handlers
225  * *are* registered.  That means that using selectors as table offsets prohibits
226  * us from compacting the handler table at Freeze() time.  If the table is very
227  * sparse, this could be wasteful.
228  *
229  * Having another selector-like thing that is specific to a Handlers instance
230  * would allow this compacting, but then it would be impossible to write code
231  * ahead-of-time that can be bound to any Handlers instance at runtime.  For
232  * example, a .proto file parser written as straight C will not know what
233  * Handlers it will be bound to, so when it calls sink->StartString() what
234  * selector will it pass?  It needs a selector like we have today, that is
235  * independent of any particular upb::Handlers.
236  *
237  * Is there a way then to allow Handlers table compaction? */
238 class upb::Sink {
239  public:
240   /* Constructor with no initialization; must be Reset() before use. */
241   Sink() {}
242
243   Sink(const Sink&) = default;
244   Sink& operator=(const Sink&) = default;
245
246   Sink(const upb_sink& sink) : sink_(sink) {}
247   Sink &operator=(const upb_sink &sink) {
248     sink_ = sink;
249     return *this;
250   }
251
252   upb_sink sink() { return sink_; }
253
254   /* Constructs a new sink for the given frozen handlers and closure.
255    *
256    * TODO: once the Handlers know the expected closure type, verify that T
257    * matches it. */
258   template <class T> Sink(const upb_handlers* handlers, T* closure) {
259     Reset(handlers, closure);
260   }
261
262   upb_sink* ptr() { return &sink_; }
263
264   /* Resets the value of the sink. */
265   template <class T> void Reset(const upb_handlers* handlers, T* closure) {
266     upb_sink_reset(&sink_, handlers, closure);
267   }
268
269   /* Returns the top-level object that is bound to this sink.
270    *
271    * TODO: once the Handlers know the expected closure type, verify that T
272    * matches it. */
273   template <class T> T* GetObject() const {
274     return static_cast<T*>(sink_.closure);
275   }
276
277   /* Functions for pushing data into the sink.
278    *
279    * These return false if processing should stop (either due to error or just
280    * to suspend).
281    *
282    * These may not be called from within one of the same sink's handlers (in
283    * other words, handlers are not re-entrant). */
284
285   /* Should be called at the start and end of every message; both the top-level
286    * message and submessages.  This means that submessages should use the
287    * following sequence:
288    *   sink->StartSubMessage(startsubmsg_selector);
289    *   sink->StartMessage();
290    *   // ...
291    *   sink->EndMessage(&status);
292    *   sink->EndSubMessage(endsubmsg_selector); */
293   bool StartMessage() { return upb_sink_startmsg(sink_); }
294   bool EndMessage(upb_status *status) {
295     return upb_sink_endmsg(sink_, status);
296   }
297
298   /* Putting of individual values.  These work for both repeated and
299    * non-repeated fields, but for repeated fields you must wrap them in
300    * calls to StartSequence()/EndSequence(). */
301   bool PutInt32(HandlersPtr::Selector s, int32_t val) {
302     return upb_sink_putint32(sink_, s, val);
303   }
304
305   bool PutInt64(HandlersPtr::Selector s, int64_t val) {
306     return upb_sink_putint64(sink_, s, val);
307   }
308
309   bool PutUInt32(HandlersPtr::Selector s, uint32_t val) {
310     return upb_sink_putuint32(sink_, s, val);
311   }
312
313   bool PutUInt64(HandlersPtr::Selector s, uint64_t val) {
314     return upb_sink_putuint64(sink_, s, val);
315   }
316
317   bool PutFloat(HandlersPtr::Selector s, float val) {
318     return upb_sink_putfloat(sink_, s, val);
319   }
320
321   bool PutDouble(HandlersPtr::Selector s, double val) {
322     return upb_sink_putdouble(sink_, s, val);
323   }
324
325   bool PutBool(HandlersPtr::Selector s, bool val) {
326     return upb_sink_putbool(sink_, s, val);
327   }
328
329   /* Putting of string/bytes values.  Each string can consist of zero or more
330    * non-contiguous buffers of data.
331    *
332    * For StartString(), the function will write a sink for the string to "sub."
333    * The sub-sink must be used for any/all PutStringBuffer() calls. */
334   bool StartString(HandlersPtr::Selector s, size_t size_hint, Sink* sub) {
335     upb_sink sub_c;
336     bool ret = upb_sink_startstr(sink_, s, size_hint, &sub_c);
337     *sub = sub_c;
338     return ret;
339   }
340
341   size_t PutStringBuffer(HandlersPtr::Selector s, const char *buf, size_t len,
342                          const upb_bufhandle *handle) {
343     return upb_sink_putstring(sink_, s, buf, len, handle);
344   }
345
346   bool EndString(HandlersPtr::Selector s) {
347     return upb_sink_endstr(sink_, s);
348   }
349
350   /* For submessage fields.
351    *
352    * For StartSubMessage(), the function will write a sink for the string to
353    * "sub." The sub-sink must be used for any/all handlers called within the
354    * submessage. */
355   bool StartSubMessage(HandlersPtr::Selector s, Sink* sub) {
356     upb_sink sub_c;
357     bool ret = upb_sink_startsubmsg(sink_, s, &sub_c);
358     *sub = sub_c;
359     return ret;
360   }
361
362   bool EndSubMessage(HandlersPtr::Selector s) {
363     return upb_sink_endsubmsg(sink_, s);
364   }
365
366   /* For repeated fields of any type, the sequence of values must be wrapped in
367    * these calls.
368    *
369    * For StartSequence(), the function will write a sink for the string to
370    * "sub." The sub-sink must be used for any/all handlers called within the
371    * sequence. */
372   bool StartSequence(HandlersPtr::Selector s, Sink* sub) {
373     upb_sink sub_c;
374     bool ret = upb_sink_startseq(sink_, s, &sub_c);
375     *sub = sub_c;
376     return ret;
377   }
378
379   bool EndSequence(HandlersPtr::Selector s) {
380     return upb_sink_endseq(sink_, s);
381   }
382
383   /* Copy and assign specifically allowed.
384    * We don't even bother making these members private because so many
385    * functions need them and this is mainly just a dumb data container anyway.
386    */
387
388  private:
389   upb_sink sink_;
390 };
391
392 #endif  /* __cplusplus */
393
394 /* upb_bytessink **************************************************************/
395
396 typedef struct {
397   const upb_byteshandler *handler;
398   void *closure;
399 } upb_bytessink ;
400
401 UPB_INLINE void upb_bytessink_reset(upb_bytessink* s, const upb_byteshandler *h,
402                                     void *closure) {
403   s->handler = h;
404   s->closure = closure;
405 }
406
407 UPB_INLINE bool upb_bytessink_start(upb_bytessink s, size_t size_hint,
408                                     void **subc) {
409   typedef upb_startstr_handlerfunc func;
410   func *start;
411   *subc = s.closure;
412   if (!s.handler) return true;
413   start = (func *)s.handler->table[UPB_STARTSTR_SELECTOR].func;
414
415   if (!start) return true;
416   *subc = start(s.closure,
417                 s.handler->table[UPB_STARTSTR_SELECTOR].attr.handler_data,
418                 size_hint);
419   return *subc != NULL;
420 }
421
422 UPB_INLINE size_t upb_bytessink_putbuf(upb_bytessink s, void *subc,
423                                        const char *buf, size_t size,
424                                        const upb_bufhandle* handle) {
425   typedef upb_string_handlerfunc func;
426   func *putbuf;
427   if (!s.handler) return true;
428   putbuf = (func *)s.handler->table[UPB_STRING_SELECTOR].func;
429
430   if (!putbuf) return true;
431   return putbuf(subc, s.handler->table[UPB_STRING_SELECTOR].attr.handler_data,
432                 buf, size, handle);
433 }
434
435 UPB_INLINE bool upb_bytessink_end(upb_bytessink s) {
436   typedef upb_endfield_handlerfunc func;
437   func *end;
438   if (!s.handler) return true;
439   end = (func *)s.handler->table[UPB_ENDSTR_SELECTOR].func;
440
441   if (!end) return true;
442   return end(s.closure,
443              s.handler->table[UPB_ENDSTR_SELECTOR].attr.handler_data);
444 }
445
446 #ifdef __cplusplus
447
448 class upb::BytesSink {
449  public:
450   BytesSink() {}
451
452   BytesSink(const BytesSink&) = default;
453   BytesSink& operator=(const BytesSink&) = default;
454
455   BytesSink(const upb_bytessink& sink) : sink_(sink) {}
456   BytesSink &operator=(const upb_bytessink &sink) {
457     sink_ = sink;
458     return *this;
459   }
460
461   upb_bytessink sink() { return sink_; }
462
463   /* Constructs a new sink for the given frozen handlers and closure.
464    *
465    * TODO(haberman): once the Handlers know the expected closure type, verify
466    * that T matches it. */
467   template <class T> BytesSink(const upb_byteshandler* handler, T* closure) {
468     upb_bytessink_reset(sink_, handler, closure);
469   }
470
471   /* Resets the value of the sink. */
472   template <class T> void Reset(const upb_byteshandler* handler, T* closure) {
473     upb_bytessink_reset(&sink_, handler, closure);
474   }
475
476   bool Start(size_t size_hint, void **subc) {
477     return upb_bytessink_start(sink_, size_hint, subc);
478   }
479
480   size_t PutBuffer(void *subc, const char *buf, size_t len,
481                    const upb_bufhandle *handle) {
482     return upb_bytessink_putbuf(sink_, subc, buf, len, handle);
483   }
484
485   bool End() {
486     return upb_bytessink_end(sink_);
487   }
488
489  private:
490   upb_bytessink sink_;
491 };
492
493 #endif  /* __cplusplus */
494
495 /* upb_bufsrc *****************************************************************/
496
497 #ifdef __cplusplus
498 extern "C" {
499 #endif
500
501 bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink);
502
503 #ifdef __cplusplus
504 }  /* extern "C" */
505
506 namespace upb {
507 template <class T> bool PutBuffer(const T& str, BytesSink sink) {
508   return upb_bufsrc_putbuf(str.data(), str.size(), sink.sink());
509 }
510 }
511
512 #endif  /* __cplusplus */
513
514 #include "upb/port_undef.inc"
515
516 #endif