• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** upb::Handlers (upb_handlers)
3 **
4 ** A upb_handlers is like a virtual table for a upb_msgdef.  Each field of the
5 ** message can have associated functions that will be called when we are
6 ** parsing or visiting a stream of data.  This is similar to how handlers work
7 ** in SAX (the Simple API for XML).
8 **
9 ** The handlers have no idea where the data is coming from, so a single set of
10 ** handlers could be used with two completely different data sources (for
11 ** example, a parser and a visitor over in-memory objects).  This decoupling is
12 ** the most important feature of upb, because it allows parsers and serializers
13 ** to be highly reusable.
14 **
15 ** This is a mixed C/C++ interface that offers a full API to both languages.
16 ** See the top-level README for more information.
17 */
18 
19 #ifndef UPB_HANDLERS_H
20 #define UPB_HANDLERS_H
21 
22 #include "upb/def.h"
23 #include "upb/table.int.h"
24 
25 #include "upb/port_def.inc"
26 
27 #ifdef __cplusplus
28 #include "upb/def.hpp"
29 namespace upb {
30 class HandlersPtr;
31 class HandlerCache;
32 template <class T> class Handler;
33 template <class T> struct CanonicalType;
34 }  /* namespace upb */
35 #endif
36 
37 
38 /* The maximum depth that the handler graph can have.  This is a resource limit
39  * for the C stack since we sometimes need to recursively traverse the graph.
40  * Cycles are ok; the traversal will stop when it detects a cycle, but we must
41  * hit the cycle before the maximum depth is reached.
42  *
43  * If having a single static limit is too inflexible, we can add another variant
44  * of Handlers::Freeze that allows specifying this as a parameter. */
45 #define UPB_MAX_HANDLER_DEPTH 64
46 
47 /* All the different types of handlers that can be registered.
48  * Only needed for the advanced functions in upb::Handlers. */
49 typedef enum {
50   UPB_HANDLER_INT32,
51   UPB_HANDLER_INT64,
52   UPB_HANDLER_UINT32,
53   UPB_HANDLER_UINT64,
54   UPB_HANDLER_FLOAT,
55   UPB_HANDLER_DOUBLE,
56   UPB_HANDLER_BOOL,
57   UPB_HANDLER_STARTSTR,
58   UPB_HANDLER_STRING,
59   UPB_HANDLER_ENDSTR,
60   UPB_HANDLER_STARTSUBMSG,
61   UPB_HANDLER_ENDSUBMSG,
62   UPB_HANDLER_STARTSEQ,
63   UPB_HANDLER_ENDSEQ
64 } upb_handlertype_t;
65 
66 #define UPB_HANDLER_MAX (UPB_HANDLER_ENDSEQ+1)
67 
68 #define UPB_BREAK NULL
69 
70 /* A convenient definition for when no closure is needed. */
71 extern char _upb_noclosure;
72 #define UPB_NO_CLOSURE &_upb_noclosure
73 
74 /* A selector refers to a specific field handler in the Handlers object
75  * (for example: the STARTSUBMSG handler for field "field15"). */
76 typedef int32_t upb_selector_t;
77 
78 /* Static selectors for upb::Handlers. */
79 #define UPB_STARTMSG_SELECTOR 0
80 #define UPB_ENDMSG_SELECTOR 1
81 #define UPB_UNKNOWN_SELECTOR 2
82 #define UPB_STATIC_SELECTOR_COUNT 3  /* Warning: also in upb/def.c. */
83 
84 /* Static selectors for upb::BytesHandler. */
85 #define UPB_STARTSTR_SELECTOR 0
86 #define UPB_STRING_SELECTOR 1
87 #define UPB_ENDSTR_SELECTOR 2
88 
89 #ifdef __cplusplus
UniquePtrForType()90 template<class T> const void *UniquePtrForType() {
91   static const char ch = 0;
92   return &ch;
93 }
94 #endif
95 
96 /* upb_handlers ************************************************************/
97 
98 /* Handler attributes, to be registered with the handler itself. */
99 typedef struct {
100   const void *handler_data;
101   const void *closure_type;
102   const void *return_closure_type;
103   bool alwaysok;
104 } upb_handlerattr;
105 
106 #define UPB_HANDLERATTR_INIT {NULL, NULL, NULL, false}
107 
108 /* Bufhandle, data passed along with a buffer to indicate its provenance. */
109 struct upb_bufhandle {
110   /* The beginning of the buffer.  This may be different than the pointer
111    * passed to a StringBuf handler because the handler may receive data
112    * that is from the middle or end of a larger buffer. */
113   const char *buf;
114 
115   /* The offset within the attached object where this buffer begins.  Only
116    * meaningful if there is an attached object. */
117   size_t objofs;
118 
119   /* The attached object (if any) and a pointer representing its type. */
120   const void *obj;
121   const void *objtype;
122 
123 #ifdef __cplusplus
124   template <class T>
SetAttachedObjectupb_bufhandle125   void SetAttachedObject(const T* _obj) {
126     obj = _obj;
127     objtype = UniquePtrForType<T>();
128   }
129 
130   template <class T>
GetAttachedObjectupb_bufhandle131   const T *GetAttachedObject() const {
132     return objtype == UniquePtrForType<T>() ? static_cast<const T *>(obj)
133                                             : NULL;
134   }
135 #endif
136 };
137 
138 typedef struct upb_bufhandle upb_bufhandle;
139 
140 #define UPB_BUFHANDLE_INIT {NULL, 0, NULL, NULL}
141 
142 /* Handler function typedefs. */
143 typedef void upb_handlerfree(void *d);
144 typedef bool upb_unknown_handlerfunc(void *c, const void *hd, const char *buf,
145                                      size_t n);
146 typedef bool upb_startmsg_handlerfunc(void *c, const void*);
147 typedef bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status);
148 typedef void* upb_startfield_handlerfunc(void *c, const void *hd);
149 typedef bool upb_endfield_handlerfunc(void *c, const void *hd);
150 typedef bool upb_int32_handlerfunc(void *c, const void *hd, int32_t val);
151 typedef bool upb_int64_handlerfunc(void *c, const void *hd, int64_t val);
152 typedef bool upb_uint32_handlerfunc(void *c, const void *hd, uint32_t val);
153 typedef bool upb_uint64_handlerfunc(void *c, const void *hd, uint64_t val);
154 typedef bool upb_float_handlerfunc(void *c, const void *hd, float val);
155 typedef bool upb_double_handlerfunc(void *c, const void *hd, double val);
156 typedef bool upb_bool_handlerfunc(void *c, const void *hd, bool val);
157 typedef void *upb_startstr_handlerfunc(void *c, const void *hd,
158                                        size_t size_hint);
159 typedef size_t upb_string_handlerfunc(void *c, const void *hd, const char *buf,
160                                       size_t n, const upb_bufhandle* handle);
161 
162 struct upb_handlers;
163 typedef struct upb_handlers upb_handlers;
164 
165 #ifdef __cplusplus
166 extern "C" {
167 #endif
168 
169 /* Mutating accessors. */
170 const upb_status *upb_handlers_status(upb_handlers *h);
171 void upb_handlers_clearerr(upb_handlers *h);
172 const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
173 bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree);
174 bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
175                              const upb_handlerattr *attr);
176 bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
177                               const upb_handlerattr *attr);
178 bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
179                             const upb_handlerattr *attr);
180 bool upb_handlers_setint32(upb_handlers *h, const upb_fielddef *f,
181                            upb_int32_handlerfunc *func,
182                            const upb_handlerattr *attr);
183 bool upb_handlers_setint64(upb_handlers *h, const upb_fielddef *f,
184                            upb_int64_handlerfunc *func,
185                            const upb_handlerattr *attr);
186 bool upb_handlers_setuint32(upb_handlers *h, const upb_fielddef *f,
187                             upb_uint32_handlerfunc *func,
188                             const upb_handlerattr *attr);
189 bool upb_handlers_setuint64(upb_handlers *h, const upb_fielddef *f,
190                             upb_uint64_handlerfunc *func,
191                             const upb_handlerattr *attr);
192 bool upb_handlers_setfloat(upb_handlers *h, const upb_fielddef *f,
193                            upb_float_handlerfunc *func,
194                            const upb_handlerattr *attr);
195 bool upb_handlers_setdouble(upb_handlers *h, const upb_fielddef *f,
196                             upb_double_handlerfunc *func,
197                             const upb_handlerattr *attr);
198 bool upb_handlers_setbool(upb_handlers *h, const upb_fielddef *f,
199                           upb_bool_handlerfunc *func,
200                           const upb_handlerattr *attr);
201 bool upb_handlers_setstartstr(upb_handlers *h, const upb_fielddef *f,
202                               upb_startstr_handlerfunc *func,
203                               const upb_handlerattr *attr);
204 bool upb_handlers_setstring(upb_handlers *h, const upb_fielddef *f,
205                             upb_string_handlerfunc *func,
206                             const upb_handlerattr *attr);
207 bool upb_handlers_setendstr(upb_handlers *h, const upb_fielddef *f,
208                             upb_endfield_handlerfunc *func,
209                             const upb_handlerattr *attr);
210 bool upb_handlers_setstartseq(upb_handlers *h, const upb_fielddef *f,
211                               upb_startfield_handlerfunc *func,
212                               const upb_handlerattr *attr);
213 bool upb_handlers_setstartsubmsg(upb_handlers *h, const upb_fielddef *f,
214                                  upb_startfield_handlerfunc *func,
215                                  const upb_handlerattr *attr);
216 bool upb_handlers_setendsubmsg(upb_handlers *h, const upb_fielddef *f,
217                                upb_endfield_handlerfunc *func,
218                                const upb_handlerattr *attr);
219 bool upb_handlers_setendseq(upb_handlers *h, const upb_fielddef *f,
220                             upb_endfield_handlerfunc *func,
221                             const upb_handlerattr *attr);
222 
223 /* Read-only accessors. */
224 const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
225                                                 const upb_fielddef *f);
226 const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
227                                                     upb_selector_t sel);
228 upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s,
229                                   const void **handler_data);
230 bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t s,
231                           upb_handlerattr *attr);
232 
233 /* "Static" methods */
234 upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f);
235 bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
236                               upb_selector_t *s);
upb_handlers_getendselector(upb_selector_t start)237 UPB_INLINE upb_selector_t upb_handlers_getendselector(upb_selector_t start) {
238   return start + 1;
239 }
240 
241 #ifdef __cplusplus
242 }  /* extern "C" */
243 
244 namespace upb {
245 typedef upb_handlers Handlers;
246 }
247 
248 /* Convenience macros for creating a Handler object that is wrapped with a
249  * type-safe wrapper function that converts the "void*" parameters/returns
250  * of the underlying C API into nice C++ function.
251  *
252  * Sample usage:
253  *   void OnValue1(MyClosure* c, const MyHandlerData* d, int32_t val) {
254  *     // do stuff ...
255  *   }
256  *
257  *   // Handler that doesn't need any data bound to it.
258  *   void OnValue2(MyClosure* c, int32_t val) {
259  *     // do stuff ...
260  *   }
261  *
262  *   // Handler that returns bool so it can return failure if necessary.
263  *   bool OnValue3(MyClosure* c, int32_t val) {
264  *     // do stuff ...
265  *     return ok;
266  *   }
267  *
268  *   // Member function handler.
269  *   class MyClosure {
270  *    public:
271  *     void OnValue(int32_t val) {
272  *       // do stuff ...
273  *     }
274  *   };
275  *
276  *   // Takes ownership of the MyHandlerData.
277  *   handlers->SetInt32Handler(f1, UpbBind(OnValue1, new MyHandlerData(...)));
278  *   handlers->SetInt32Handler(f2, UpbMakeHandler(OnValue2));
279  *   handlers->SetInt32Handler(f1, UpbMakeHandler(OnValue3));
280  *   handlers->SetInt32Handler(f2, UpbMakeHandler(&MyClosure::OnValue));
281  */
282 
283 /* In C++11, the "template" disambiguator can appear even outside templates,
284  * so all calls can safely use this pair of macros. */
285 
286 #define UpbMakeHandler(f) upb::MatchFunc(f).template GetFunc<f>()
287 
288 /* We have to be careful to only evaluate "d" once. */
289 #define UpbBind(f, d) upb::MatchFunc(f).template GetFunc<f>((d))
290 
291 /* Handler: a struct that contains the (handler, data, deleter) tuple that is
292  * used to register all handlers.  Users can Make() these directly but it's
293  * more convenient to use the UpbMakeHandler/UpbBind macros above. */
294 template <class T> class upb::Handler {
295  public:
296   /* The underlying, handler function signature that upb uses internally. */
297   typedef T FuncPtr;
298 
299   /* Intentionally implicit. */
300   template <class F> Handler(F func);
~Handler()301   ~Handler() { UPB_ASSERT(registered_); }
302 
303   void AddCleanup(upb_handlers* h) const;
handler()304   FuncPtr handler() const { return handler_; }
attr()305   const upb_handlerattr& attr() const { return attr_; }
306 
307  private:
308   Handler(const Handler&) = delete;
309   Handler& operator=(const Handler&) = delete;
310 
311   FuncPtr handler_;
312   mutable upb_handlerattr attr_;
313   mutable bool registered_;
314   void *cleanup_data_;
315   upb_handlerfree *cleanup_func_;
316 };
317 
318 /* A upb::Handlers object represents the set of handlers associated with a
319  * message in the graph of messages.  You can think of it as a big virtual
320  * table with functions corresponding to all the events that can fire while
321  * parsing or visiting a message of a specific type.
322  *
323  * Any handlers that are not set behave as if they had successfully consumed
324  * the value.  Any unset Start* handlers will propagate their closure to the
325  * inner frame.
326  *
327  * The easiest way to create the *Handler objects needed by the Set* methods is
328  * with the UpbBind() and UpbMakeHandler() macros; see below. */
329 class upb::HandlersPtr {
330  public:
HandlersPtr(upb_handlers * ptr)331   HandlersPtr(upb_handlers* ptr) : ptr_(ptr) {}
332 
ptr()333   upb_handlers* ptr() const { return ptr_; }
334 
335   typedef upb_selector_t Selector;
336   typedef upb_handlertype_t Type;
337 
338   typedef Handler<void *(*)(void *, const void *)> StartFieldHandler;
339   typedef Handler<bool (*)(void *, const void *)> EndFieldHandler;
340   typedef Handler<bool (*)(void *, const void *)> StartMessageHandler;
341   typedef Handler<bool (*)(void *, const void *, upb_status *)>
342       EndMessageHandler;
343   typedef Handler<void *(*)(void *, const void *, size_t)> StartStringHandler;
344   typedef Handler<size_t (*)(void *, const void *, const char *, size_t,
345                              const upb_bufhandle *)>
346       StringHandler;
347 
348   template <class T> struct ValueHandler {
349     typedef Handler<bool(*)(void *, const void *, T)> H;
350   };
351 
352   typedef ValueHandler<int32_t>::H     Int32Handler;
353   typedef ValueHandler<int64_t>::H     Int64Handler;
354   typedef ValueHandler<uint32_t>::H    UInt32Handler;
355   typedef ValueHandler<uint64_t>::H    UInt64Handler;
356   typedef ValueHandler<float>::H       FloatHandler;
357   typedef ValueHandler<double>::H      DoubleHandler;
358   typedef ValueHandler<bool>::H        BoolHandler;
359 
360   /* Any function pointer can be converted to this and converted back to its
361    * correct type. */
362   typedef void GenericFunction();
363 
364   typedef void HandlersCallback(const void *closure, upb_handlers *h);
365 
366   /* Returns the msgdef associated with this handlers object. */
message_def()367   MessageDefPtr message_def() const {
368     return MessageDefPtr(upb_handlers_msgdef(ptr()));
369   }
370 
371   /* Adds the given pointer and function to the list of cleanup functions that
372    * will be run when these handlers are freed.  If this pointer has previously
373    * been registered, the function returns false and does nothing. */
AddCleanup(void * ptr,upb_handlerfree * cleanup)374   bool AddCleanup(void *ptr, upb_handlerfree *cleanup) {
375     return upb_handlers_addcleanup(ptr_, ptr, cleanup);
376   }
377 
378   /* Sets the startmsg handler for the message, which is defined as follows:
379    *
380    *   bool startmsg(MyType* closure) {
381    *     // Called when the message begins.  Returns true if processing should
382    *     // continue.
383    *     return true;
384    *   }
385    */
SetStartMessageHandler(const StartMessageHandler & h)386   bool SetStartMessageHandler(const StartMessageHandler &h) {
387     h.AddCleanup(ptr());
388     return upb_handlers_setstartmsg(ptr(), h.handler(), &h.attr());
389   }
390 
391   /* Sets the endmsg handler for the message, which is defined as follows:
392    *
393    *   bool endmsg(MyType* closure, upb_status *status) {
394    *     // Called when processing of this message ends, whether in success or
395    *     // failure.  "status" indicates the final status of processing, and
396    *     // can also be modified in-place to update the final status.
397    *   }
398    */
SetEndMessageHandler(const EndMessageHandler & h)399   bool SetEndMessageHandler(const EndMessageHandler& h) {
400     h.AddCleanup(ptr());
401     return upb_handlers_setendmsg(ptr(), h.handler(), &h.attr());
402   }
403 
404   /* Sets the value handler for the given field, which is defined as follows
405    * (this is for an int32 field; other field types will pass their native
406    * C/C++ type for "val"):
407    *
408    *   bool OnValue(MyClosure* c, const MyHandlerData* d, int32_t val) {
409    *     // Called when the field's value is encountered.  "d" contains
410    *     // whatever data was bound to this field when it was registered.
411    *     // Returns true if processing should continue.
412    *     return true;
413    *   }
414    *
415    *   handers->SetInt32Handler(f, UpbBind(OnValue, new MyHandlerData(...)));
416    *
417    * The value type must exactly match f->type().
418    * For example, a handler that takes an int32_t parameter may only be used for
419    * fields of type UPB_TYPE_INT32 and UPB_TYPE_ENUM.
420    *
421    * Returns false if the handler failed to register; in this case the cleanup
422    * handler (if any) will be called immediately.
423    */
SetInt32Handler(FieldDefPtr f,const Int32Handler & h)424   bool SetInt32Handler(FieldDefPtr f, const Int32Handler &h) {
425     h.AddCleanup(ptr());
426     return upb_handlers_setint32(ptr(), f.ptr(), h.handler(), &h.attr());
427   }
428 
SetInt64Handler(FieldDefPtr f,const Int64Handler & h)429   bool SetInt64Handler (FieldDefPtr f,  const Int64Handler& h) {
430     h.AddCleanup(ptr());
431     return upb_handlers_setint64(ptr(), f.ptr(), h.handler(), &h.attr());
432   }
433 
SetUInt32Handler(FieldDefPtr f,const UInt32Handler & h)434   bool SetUInt32Handler(FieldDefPtr f, const UInt32Handler& h) {
435     h.AddCleanup(ptr());
436     return upb_handlers_setuint32(ptr(), f.ptr(), h.handler(), &h.attr());
437   }
438 
SetUInt64Handler(FieldDefPtr f,const UInt64Handler & h)439   bool SetUInt64Handler(FieldDefPtr f, const UInt64Handler& h) {
440     h.AddCleanup(ptr());
441     return upb_handlers_setuint64(ptr(), f.ptr(), h.handler(), &h.attr());
442   }
443 
SetFloatHandler(FieldDefPtr f,const FloatHandler & h)444   bool SetFloatHandler (FieldDefPtr f,  const FloatHandler& h) {
445     h.AddCleanup(ptr());
446     return upb_handlers_setfloat(ptr(), f.ptr(), h.handler(), &h.attr());
447   }
448 
SetDoubleHandler(FieldDefPtr f,const DoubleHandler & h)449   bool SetDoubleHandler(FieldDefPtr f, const DoubleHandler& h) {
450     h.AddCleanup(ptr());
451     return upb_handlers_setdouble(ptr(), f.ptr(), h.handler(), &h.attr());
452   }
453 
SetBoolHandler(FieldDefPtr f,const BoolHandler & h)454   bool SetBoolHandler(FieldDefPtr f, const BoolHandler &h) {
455     h.AddCleanup(ptr());
456     return upb_handlers_setbool(ptr(), f.ptr(), h.handler(), &h.attr());
457   }
458 
459   /* Like the previous, but templated on the type on the value (ie. int32).
460    * This is mostly useful to call from other templates.  To call this you must
461    * specify the template parameter explicitly, ie:
462    *   h->SetValueHandler<T>(f, UpbBind(MyHandler<T>, MyData)); */
463   template <class T>
464   bool SetValueHandler(
465       FieldDefPtr f,
466       const typename ValueHandler<typename CanonicalType<T>::Type>::H &handler);
467 
468   /* Sets handlers for a string field, which are defined as follows:
469    *
470    *   MySubClosure* startstr(MyClosure* c, const MyHandlerData* d,
471    *                          size_t size_hint) {
472    *     // Called when a string value begins.  The return value indicates the
473    *     // closure for the string.  "size_hint" indicates the size of the
474    *     // string if it is known, however if the string is length-delimited
475    *     // and the end-of-string is not available size_hint will be zero.
476    *     // This case is indistinguishable from the case where the size is
477    *     // known to be zero.
478    *     //
479    *     // TODO(haberman): is it important to distinguish these cases?
480    *     // If we had ssize_t as a type we could make -1 "unknown", but
481    *     // ssize_t is POSIX (not ANSI) and therefore less portable.
482    *     // In practice I suspect it won't be important to distinguish.
483    *     return closure;
484    *   }
485    *
486    *   size_t str(MyClosure* closure, const MyHandlerData* d,
487    *              const char *str, size_t len) {
488    *     // Called for each buffer of string data; the multiple physical buffers
489    *     // are all part of the same logical string.  The return value indicates
490    *     // how many bytes were consumed.  If this number is less than "len",
491    *     // this will also indicate that processing should be halted for now,
492    *     // like returning false or UPB_BREAK from any other callback.  If
493    *     // number is greater than "len", the excess bytes will be skipped over
494    *     // and not passed to the callback.
495    *     return len;
496    *   }
497    *
498    *   bool endstr(MyClosure* c, const MyHandlerData* d) {
499    *     // Called when a string value ends.  Return value indicates whether
500    *     // processing should continue.
501    *     return true;
502    *   }
503    */
SetStartStringHandler(FieldDefPtr f,const StartStringHandler & h)504   bool SetStartStringHandler(FieldDefPtr f, const StartStringHandler &h) {
505     h.AddCleanup(ptr());
506     return upb_handlers_setstartstr(ptr(), f.ptr(), h.handler(), &h.attr());
507   }
508 
SetStringHandler(FieldDefPtr f,const StringHandler & h)509   bool SetStringHandler(FieldDefPtr f, const StringHandler& h) {
510     h.AddCleanup(ptr());
511     return upb_handlers_setstring(ptr(), f.ptr(), h.handler(), &h.attr());
512   }
513 
SetEndStringHandler(FieldDefPtr f,const EndFieldHandler & h)514   bool SetEndStringHandler(FieldDefPtr f, const EndFieldHandler& h) {
515     h.AddCleanup(ptr());
516     return upb_handlers_setendstr(ptr(), f.ptr(), h.handler(), &h.attr());
517   }
518 
519   /* Sets the startseq handler, which is defined as follows:
520    *
521    *   MySubClosure *startseq(MyClosure* c, const MyHandlerData* d) {
522    *     // Called when a sequence (repeated field) begins.  The returned
523    *     // pointer indicates the closure for the sequence (or UPB_BREAK
524    *     // to interrupt processing).
525    *     return closure;
526    *   }
527    *
528    *   h->SetStartSequenceHandler(f, UpbBind(startseq, new MyHandlerData(...)));
529    *
530    * Returns "false" if "f" does not belong to this message or is not a
531    * repeated field.
532    */
SetStartSequenceHandler(FieldDefPtr f,const StartFieldHandler & h)533   bool SetStartSequenceHandler(FieldDefPtr f, const StartFieldHandler &h) {
534     h.AddCleanup(ptr());
535     return upb_handlers_setstartseq(ptr(), f.ptr(), h.handler(), &h.attr());
536   }
537 
538   /* Sets the startsubmsg handler for the given field, which is defined as
539    * follows:
540    *
541    *   MySubClosure* startsubmsg(MyClosure* c, const MyHandlerData* d) {
542    *     // Called when a submessage begins.  The returned pointer indicates the
543    *     // closure for the sequence (or UPB_BREAK to interrupt processing).
544    *     return closure;
545    *   }
546    *
547    *   h->SetStartSubMessageHandler(f, UpbBind(startsubmsg,
548    *                                           new MyHandlerData(...)));
549    *
550    * Returns "false" if "f" does not belong to this message or is not a
551    * submessage/group field.
552    */
SetStartSubMessageHandler(FieldDefPtr f,const StartFieldHandler & h)553   bool SetStartSubMessageHandler(FieldDefPtr f, const StartFieldHandler& h) {
554     h.AddCleanup(ptr());
555     return upb_handlers_setstartsubmsg(ptr(), f.ptr(), h.handler(), &h.attr());
556   }
557 
558   /* Sets the endsubmsg handler for the given field, which is defined as
559    * follows:
560    *
561    *   bool endsubmsg(MyClosure* c, const MyHandlerData* d) {
562    *     // Called when a submessage ends.  Returns true to continue processing.
563    *     return true;
564    *   }
565    *
566    * Returns "false" if "f" does not belong to this message or is not a
567    * submessage/group field.
568    */
SetEndSubMessageHandler(FieldDefPtr f,const EndFieldHandler & h)569   bool SetEndSubMessageHandler(FieldDefPtr f, const EndFieldHandler &h) {
570     h.AddCleanup(ptr());
571     return upb_handlers_setendsubmsg(ptr(), f.ptr(), h.handler(), &h.attr());
572   }
573 
574   /* Starts the endsubseq handler for the given field, which is defined as
575    * follows:
576    *
577    *   bool endseq(MyClosure* c, const MyHandlerData* d) {
578    *     // Called when a sequence ends.  Returns true continue processing.
579    *     return true;
580    *   }
581    *
582    * Returns "false" if "f" does not belong to this message or is not a
583    * repeated field.
584    */
SetEndSequenceHandler(FieldDefPtr f,const EndFieldHandler & h)585   bool SetEndSequenceHandler(FieldDefPtr f, const EndFieldHandler &h) {
586     h.AddCleanup(ptr());
587     return upb_handlers_setendseq(ptr(), f.ptr(), h.handler(), &h.attr());
588   }
589 
590  private:
591   upb_handlers* ptr_;
592 };
593 
594 #endif  /* __cplusplus */
595 
596 /* upb_handlercache ***********************************************************/
597 
598 /* A upb_handlercache lazily builds and caches upb_handlers.  You pass it a
599  * function (with optional closure) that can build handlers for a given
600  * message on-demand, and the cache maintains a map of msgdef->handlers. */
601 
602 #ifdef __cplusplus
603 extern "C" {
604 #endif
605 
606 struct upb_handlercache;
607 typedef struct upb_handlercache upb_handlercache;
608 
609 typedef void upb_handlers_callback(const void *closure, upb_handlers *h);
610 
611 upb_handlercache *upb_handlercache_new(upb_handlers_callback *callback,
612                                        const void *closure);
613 void upb_handlercache_free(upb_handlercache *cache);
614 const upb_handlers *upb_handlercache_get(upb_handlercache *cache,
615                                          const upb_msgdef *md);
616 bool upb_handlercache_addcleanup(upb_handlercache *h, void *p,
617                                  upb_handlerfree *hfree);
618 
619 #ifdef __cplusplus
620 }  /* extern "C" */
621 
622 class upb::HandlerCache {
623  public:
HandlerCache(upb_handlers_callback * callback,const void * closure)624   HandlerCache(upb_handlers_callback *callback, const void *closure)
625       : ptr_(upb_handlercache_new(callback, closure), upb_handlercache_free) {}
626   HandlerCache(HandlerCache&&) = default;
627   HandlerCache& operator=(HandlerCache&&) = default;
HandlerCache(upb_handlercache * c)628   HandlerCache(upb_handlercache* c) : ptr_(c, upb_handlercache_free) {}
629 
ptr()630   upb_handlercache* ptr() { return ptr_.get(); }
631 
Get(MessageDefPtr md)632   const upb_handlers *Get(MessageDefPtr md) {
633     return upb_handlercache_get(ptr_.get(), md.ptr());
634   }
635 
636  private:
637   std::unique_ptr<upb_handlercache, decltype(&upb_handlercache_free)> ptr_;
638 };
639 
640 #endif  /* __cplusplus */
641 
642 /* upb_byteshandler ***********************************************************/
643 
644 typedef struct {
645   upb_func *func;
646 
647   /* It is wasteful to include the entire attributes here:
648    *
649    * * Some of the information is redundant (like storing the closure type
650    *   separately for each handler that must match).
651    * * Some of the info is only needed prior to freeze() (like closure types).
652    * * alignment padding wastes a lot of space for alwaysok_.
653    *
654    * If/when the size and locality of handlers is an issue, we can optimize this
655    * not to store the entire attr like this.  We do not expose the table's
656    * layout to allow this optimization in the future. */
657   upb_handlerattr attr;
658 } upb_handlers_tabent;
659 
660 #define UPB_TABENT_INIT {NULL, UPB_HANDLERATTR_INIT}
661 
662 typedef struct {
663   upb_handlers_tabent table[3];
664 } upb_byteshandler;
665 
666 #define UPB_BYTESHANDLER_INIT                             \
667   {                                                       \
668     { UPB_TABENT_INIT, UPB_TABENT_INIT, UPB_TABENT_INIT } \
669   }
670 
upb_byteshandler_init(upb_byteshandler * handler)671 UPB_INLINE void upb_byteshandler_init(upb_byteshandler *handler) {
672   upb_byteshandler init = UPB_BYTESHANDLER_INIT;
673   *handler = init;
674 }
675 
676 #ifdef __cplusplus
677 extern "C" {
678 #endif
679 
680 /* Caller must ensure that "d" outlives the handlers. */
681 bool upb_byteshandler_setstartstr(upb_byteshandler *h,
682                                   upb_startstr_handlerfunc *func, void *d);
683 bool upb_byteshandler_setstring(upb_byteshandler *h,
684                                 upb_string_handlerfunc *func, void *d);
685 bool upb_byteshandler_setendstr(upb_byteshandler *h,
686                                 upb_endfield_handlerfunc *func, void *d);
687 
688 #ifdef __cplusplus
689 }  /* extern "C" */
690 
691 namespace upb {
692 typedef upb_byteshandler BytesHandler;
693 }
694 #endif
695 
696 /** Message handlers ******************************************************************/
697 
698 #ifdef __cplusplus
699 extern "C" {
700 #endif
701 
702 /* These are the handlers used internally by upb_msgfactory_getmergehandlers().
703  * They write scalar data to a known offset from the message pointer.
704  *
705  * These would be trivial for anyone to implement themselves, but it's better
706  * to use these because some JITs will recognize and specialize these instead
707  * of actually calling the function. */
708 
709 /* Sets a handler for the given primitive field that will write the data at the
710  * given offset.  If hasbit > 0, also sets a hasbit at the given bit offset
711  * (addressing each byte low to high). */
712 bool upb_msg_setscalarhandler(upb_handlers *h,
713                               const upb_fielddef *f,
714                               size_t offset,
715                               int32_t hasbit);
716 
717 /* If the given handler is a msghandlers_primitive field, returns true and sets
718  * *type, *offset and *hasbit.  Otherwise returns false. */
719 bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
720                                   upb_selector_t s,
721                                   upb_fieldtype_t *type,
722                                   size_t *offset,
723                                   int32_t *hasbit);
724 
725 
726 
727 #ifdef __cplusplus
728 }  /* extern "C" */
729 #endif
730 
731 #include "upb/port_undef.inc"
732 
733 #include "upb/handlers-inl.h"
734 
735 #endif  /* UPB_HANDLERS_H */
736