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
PUTVAL(int32,int32_t)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
upb_sink_putstring(upb_sink s,upb_selector_t sel,const char * buf,size_t n,const upb_bufhandle * handle)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
upb_sink_putunknown(upb_sink s,const char * buf,size_t n)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
upb_sink_startmsg(upb_sink s)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
upb_sink_endmsg(upb_sink s,upb_status * status)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
upb_sink_startseq(upb_sink s,upb_selector_t sel,upb_sink * sub)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
upb_sink_endseq(upb_sink s,upb_selector_t sel)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
upb_sink_startstr(upb_sink s,upb_selector_t sel,size_t size_hint,upb_sink * sub)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
upb_sink_endstr(upb_sink s,upb_selector_t sel)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
upb_sink_startsubmsg(upb_sink s,upb_selector_t sel,upb_sink * sub)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
upb_sink_endsubmsg(upb_sink s,upb_sink sub,upb_selector_t sel)188 UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_sink sub,
189 upb_selector_t sel) {
190 typedef upb_endfield_handlerfunc func;
191 func *endsubmsg;
192 const void *hd;
193 if (!s.handlers) return true;
194 endsubmsg = (func*)upb_handlers_gethandler(s.handlers, sel, &hd);
195
196 if (!endsubmsg) return true;
197 return endsubmsg(sub.closure, hd);
198 }
199
200 #ifdef __cplusplus
201 } /* extern "C" */
202
203 /* A upb::Sink is an object that binds a upb::Handlers object to some runtime
204 * state. It represents an endpoint to which data can be sent.
205 *
206 * TODO(haberman): right now all of these functions take selectors. Should they
207 * take selectorbase instead?
208 *
209 * ie. instead of calling:
210 * sink->StartString(FOO_FIELD_START_STRING, ...)
211 * a selector base would let you say:
212 * sink->StartString(FOO_FIELD, ...)
213 *
214 * This would make call sites a little nicer and require emitting fewer selector
215 * definitions in .h files.
216 *
217 * But the current scheme has the benefit that you can retrieve a function
218 * pointer for any handler with handlers->GetHandler(selector), without having
219 * to have a separate GetHandler() function for each handler type. The JIT
220 * compiler uses this. To accommodate we'd have to expose a separate
221 * GetHandler() for every handler type.
222 *
223 * Also to ponder: selectors right now are independent of a specific Handlers
224 * instance. In other words, they allocate a number to every possible handler
225 * that *could* be registered, without knowing anything about what handlers
226 * *are* registered. That means that using selectors as table offsets prohibits
227 * us from compacting the handler table at Freeze() time. If the table is very
228 * sparse, this could be wasteful.
229 *
230 * Having another selector-like thing that is specific to a Handlers instance
231 * would allow this compacting, but then it would be impossible to write code
232 * ahead-of-time that can be bound to any Handlers instance at runtime. For
233 * example, a .proto file parser written as straight C will not know what
234 * Handlers it will be bound to, so when it calls sink->StartString() what
235 * selector will it pass? It needs a selector like we have today, that is
236 * independent of any particular upb::Handlers.
237 *
238 * Is there a way then to allow Handlers table compaction? */
239 class upb::Sink {
240 public:
241 /* Constructor with no initialization; must be Reset() before use. */
Sink()242 Sink() {}
243
244 Sink(const Sink&) = default;
245 Sink& operator=(const Sink&) = default;
246
Sink(const upb_sink & sink)247 Sink(const upb_sink& sink) : sink_(sink) {}
248 Sink &operator=(const upb_sink &sink) {
249 sink_ = sink;
250 return *this;
251 }
252
sink()253 upb_sink sink() { return sink_; }
254
255 /* Constructs a new sink for the given frozen handlers and closure.
256 *
257 * TODO: once the Handlers know the expected closure type, verify that T
258 * matches it. */
Sink(const upb_handlers * handlers,T * closure)259 template <class T> Sink(const upb_handlers* handlers, T* closure) {
260 Reset(handlers, closure);
261 }
262
ptr()263 upb_sink* ptr() { return &sink_; }
264
265 /* Resets the value of the sink. */
Reset(const upb_handlers * handlers,T * closure)266 template <class T> void Reset(const upb_handlers* handlers, T* closure) {
267 upb_sink_reset(&sink_, handlers, closure);
268 }
269
270 /* Returns the top-level object that is bound to this sink.
271 *
272 * TODO: once the Handlers know the expected closure type, verify that T
273 * matches it. */
GetObject()274 template <class T> T* GetObject() const {
275 return static_cast<T*>(sink_.closure);
276 }
277
278 /* Functions for pushing data into the sink.
279 *
280 * These return false if processing should stop (either due to error or just
281 * to suspend).
282 *
283 * These may not be called from within one of the same sink's handlers (in
284 * other words, handlers are not re-entrant). */
285
286 /* Should be called at the start and end of every message; both the top-level
287 * message and submessages. This means that submessages should use the
288 * following sequence:
289 * sink->StartSubMessage(startsubmsg_selector);
290 * sink->StartMessage();
291 * // ...
292 * sink->EndMessage(&status);
293 * sink->EndSubMessage(endsubmsg_selector); */
StartMessage()294 bool StartMessage() { return upb_sink_startmsg(sink_); }
EndMessage(upb_status * status)295 bool EndMessage(upb_status *status) {
296 return upb_sink_endmsg(sink_, status);
297 }
298
299 /* Putting of individual values. These work for both repeated and
300 * non-repeated fields, but for repeated fields you must wrap them in
301 * calls to StartSequence()/EndSequence(). */
PutInt32(HandlersPtr::Selector s,int32_t val)302 bool PutInt32(HandlersPtr::Selector s, int32_t val) {
303 return upb_sink_putint32(sink_, s, val);
304 }
305
PutInt64(HandlersPtr::Selector s,int64_t val)306 bool PutInt64(HandlersPtr::Selector s, int64_t val) {
307 return upb_sink_putint64(sink_, s, val);
308 }
309
PutUInt32(HandlersPtr::Selector s,uint32_t val)310 bool PutUInt32(HandlersPtr::Selector s, uint32_t val) {
311 return upb_sink_putuint32(sink_, s, val);
312 }
313
PutUInt64(HandlersPtr::Selector s,uint64_t val)314 bool PutUInt64(HandlersPtr::Selector s, uint64_t val) {
315 return upb_sink_putuint64(sink_, s, val);
316 }
317
PutFloat(HandlersPtr::Selector s,float val)318 bool PutFloat(HandlersPtr::Selector s, float val) {
319 return upb_sink_putfloat(sink_, s, val);
320 }
321
PutDouble(HandlersPtr::Selector s,double val)322 bool PutDouble(HandlersPtr::Selector s, double val) {
323 return upb_sink_putdouble(sink_, s, val);
324 }
325
PutBool(HandlersPtr::Selector s,bool val)326 bool PutBool(HandlersPtr::Selector s, bool val) {
327 return upb_sink_putbool(sink_, s, val);
328 }
329
330 /* Putting of string/bytes values. Each string can consist of zero or more
331 * non-contiguous buffers of data.
332 *
333 * For StartString(), the function will write a sink for the string to "sub."
334 * The sub-sink must be used for any/all PutStringBuffer() calls. */
StartString(HandlersPtr::Selector s,size_t size_hint,Sink * sub)335 bool StartString(HandlersPtr::Selector s, size_t size_hint, Sink* sub) {
336 upb_sink sub_c;
337 bool ret = upb_sink_startstr(sink_, s, size_hint, &sub_c);
338 *sub = sub_c;
339 return ret;
340 }
341
PutStringBuffer(HandlersPtr::Selector s,const char * buf,size_t len,const upb_bufhandle * handle)342 size_t PutStringBuffer(HandlersPtr::Selector s, const char *buf, size_t len,
343 const upb_bufhandle *handle) {
344 return upb_sink_putstring(sink_, s, buf, len, handle);
345 }
346
EndString(HandlersPtr::Selector s)347 bool EndString(HandlersPtr::Selector s) {
348 return upb_sink_endstr(sink_, s);
349 }
350
351 /* For submessage fields.
352 *
353 * For StartSubMessage(), the function will write a sink for the string to
354 * "sub." The sub-sink must be used for any/all handlers called within the
355 * submessage. */
StartSubMessage(HandlersPtr::Selector s,Sink * sub)356 bool StartSubMessage(HandlersPtr::Selector s, Sink* sub) {
357 upb_sink sub_c;
358 bool ret = upb_sink_startsubmsg(sink_, s, &sub_c);
359 *sub = sub_c;
360 return ret;
361 }
362
EndSubMessage(HandlersPtr::Selector s,Sink sub)363 bool EndSubMessage(HandlersPtr::Selector s, Sink sub) {
364 return upb_sink_endsubmsg(sink_, sub.sink_, s);
365 }
366
367 /* For repeated fields of any type, the sequence of values must be wrapped in
368 * these calls.
369 *
370 * For StartSequence(), the function will write a sink for the string to
371 * "sub." The sub-sink must be used for any/all handlers called within the
372 * sequence. */
StartSequence(HandlersPtr::Selector s,Sink * sub)373 bool StartSequence(HandlersPtr::Selector s, Sink* sub) {
374 upb_sink sub_c;
375 bool ret = upb_sink_startseq(sink_, s, &sub_c);
376 *sub = sub_c;
377 return ret;
378 }
379
EndSequence(HandlersPtr::Selector s)380 bool EndSequence(HandlersPtr::Selector s) {
381 return upb_sink_endseq(sink_, s);
382 }
383
384 /* Copy and assign specifically allowed.
385 * We don't even bother making these members private because so many
386 * functions need them and this is mainly just a dumb data container anyway.
387 */
388
389 private:
390 upb_sink sink_;
391 };
392
393 #endif /* __cplusplus */
394
395 /* upb_bytessink **************************************************************/
396
397 typedef struct {
398 const upb_byteshandler *handler;
399 void *closure;
400 } upb_bytessink ;
401
upb_bytessink_reset(upb_bytessink * s,const upb_byteshandler * h,void * closure)402 UPB_INLINE void upb_bytessink_reset(upb_bytessink* s, const upb_byteshandler *h,
403 void *closure) {
404 s->handler = h;
405 s->closure = closure;
406 }
407
upb_bytessink_start(upb_bytessink s,size_t size_hint,void ** subc)408 UPB_INLINE bool upb_bytessink_start(upb_bytessink s, size_t size_hint,
409 void **subc) {
410 typedef upb_startstr_handlerfunc func;
411 func *start;
412 *subc = s.closure;
413 if (!s.handler) return true;
414 start = (func *)s.handler->table[UPB_STARTSTR_SELECTOR].func;
415
416 if (!start) return true;
417 *subc = start(s.closure,
418 s.handler->table[UPB_STARTSTR_SELECTOR].attr.handler_data,
419 size_hint);
420 return *subc != NULL;
421 }
422
upb_bytessink_putbuf(upb_bytessink s,void * subc,const char * buf,size_t size,const upb_bufhandle * handle)423 UPB_INLINE size_t upb_bytessink_putbuf(upb_bytessink s, void *subc,
424 const char *buf, size_t size,
425 const upb_bufhandle* handle) {
426 typedef upb_string_handlerfunc func;
427 func *putbuf;
428 if (!s.handler) return true;
429 putbuf = (func *)s.handler->table[UPB_STRING_SELECTOR].func;
430
431 if (!putbuf) return true;
432 return putbuf(subc, s.handler->table[UPB_STRING_SELECTOR].attr.handler_data,
433 buf, size, handle);
434 }
435
upb_bytessink_end(upb_bytessink s)436 UPB_INLINE bool upb_bytessink_end(upb_bytessink s) {
437 typedef upb_endfield_handlerfunc func;
438 func *end;
439 if (!s.handler) return true;
440 end = (func *)s.handler->table[UPB_ENDSTR_SELECTOR].func;
441
442 if (!end) return true;
443 return end(s.closure,
444 s.handler->table[UPB_ENDSTR_SELECTOR].attr.handler_data);
445 }
446
447 #ifdef __cplusplus
448
449 class upb::BytesSink {
450 public:
BytesSink()451 BytesSink() {}
452
453 BytesSink(const BytesSink&) = default;
454 BytesSink& operator=(const BytesSink&) = default;
455
BytesSink(const upb_bytessink & sink)456 BytesSink(const upb_bytessink& sink) : sink_(sink) {}
457 BytesSink &operator=(const upb_bytessink &sink) {
458 sink_ = sink;
459 return *this;
460 }
461
sink()462 upb_bytessink sink() { return sink_; }
463
464 /* Constructs a new sink for the given frozen handlers and closure.
465 *
466 * TODO(haberman): once the Handlers know the expected closure type, verify
467 * that T matches it. */
BytesSink(const upb_byteshandler * handler,T * closure)468 template <class T> BytesSink(const upb_byteshandler* handler, T* closure) {
469 upb_bytessink_reset(sink_, handler, closure);
470 }
471
472 /* Resets the value of the sink. */
Reset(const upb_byteshandler * handler,T * closure)473 template <class T> void Reset(const upb_byteshandler* handler, T* closure) {
474 upb_bytessink_reset(&sink_, handler, closure);
475 }
476
Start(size_t size_hint,void ** subc)477 bool Start(size_t size_hint, void **subc) {
478 return upb_bytessink_start(sink_, size_hint, subc);
479 }
480
PutBuffer(void * subc,const char * buf,size_t len,const upb_bufhandle * handle)481 size_t PutBuffer(void *subc, const char *buf, size_t len,
482 const upb_bufhandle *handle) {
483 return upb_bytessink_putbuf(sink_, subc, buf, len, handle);
484 }
485
End()486 bool End() {
487 return upb_bytessink_end(sink_);
488 }
489
490 private:
491 upb_bytessink sink_;
492 };
493
494 #endif /* __cplusplus */
495
496 /* upb_bufsrc *****************************************************************/
497
498 #ifdef __cplusplus
499 extern "C" {
500 #endif
501
502 bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink);
503
504 #ifdef __cplusplus
505 } /* extern "C" */
506
507 namespace upb {
PutBuffer(const T & str,BytesSink sink)508 template <class T> bool PutBuffer(const T& str, BytesSink sink) {
509 return upb_bufsrc_putbuf(str.data(), str.size(), sink.sink());
510 }
511 }
512
513 #endif /* __cplusplus */
514
515 #include "upb/port_undef.inc"
516
517 #endif
518