diff options
Diffstat (limited to 'upb/handlers.h')
-rw-r--r-- | upb/handlers.h | 687 |
1 files changed, 352 insertions, 335 deletions
diff --git a/upb/handlers.h b/upb/handlers.h index 1b8864a..229d808 100644 --- a/upb/handlers.h +++ b/upb/handlers.h @@ -33,25 +33,26 @@ class HandlerAttributes; class Handlers; template <class T> class Handler; template <class T> struct CanonicalType; -} // namespace upb +} /* namespace upb */ #endif -UPB_DECLARE_TYPE(upb::BufferHandle, upb_bufhandle); -UPB_DECLARE_TYPE(upb::BytesHandler, upb_byteshandler); -UPB_DECLARE_TYPE(upb::HandlerAttributes, upb_handlerattr); -UPB_DECLARE_TYPE(upb::Handlers, upb_handlers); - -// The maximum depth that the handler graph can have. This is a resource limit -// for the C stack since we sometimes need to recursively traverse the graph. -// Cycles are ok; the traversal will stop when it detects a cycle, but we must -// hit the cycle before the maximum depth is reached. -// -// If having a single static limit is too inflexible, we can add another variant -// of Handlers::Freeze that allows specifying this as a parameter. +UPB_DECLARE_TYPE(upb::BufferHandle, upb_bufhandle) +UPB_DECLARE_TYPE(upb::BytesHandler, upb_byteshandler) +UPB_DECLARE_TYPE(upb::HandlerAttributes, upb_handlerattr) +UPB_DECLARE_DERIVED_TYPE(upb::Handlers, upb::RefCounted, + upb_handlers, upb_refcounted) + +/* The maximum depth that the handler graph can have. This is a resource limit + * for the C stack since we sometimes need to recursively traverse the graph. + * Cycles are ok; the traversal will stop when it detects a cycle, but we must + * hit the cycle before the maximum depth is reached. + * + * If having a single static limit is too inflexible, we can add another variant + * of Handlers::Freeze that allows specifying this as a parameter. */ #define UPB_MAX_HANDLER_DEPTH 64 -// All the different types of handlers that can be registered. -// Only needed for the advanced functions in upb::Handlers. +/* All the different types of handlers that can be registered. + * Only needed for the advanced functions in upb::Handlers. */ typedef enum { UPB_HANDLER_INT32, UPB_HANDLER_INT64, @@ -66,25 +67,25 @@ typedef enum { UPB_HANDLER_STARTSUBMSG, UPB_HANDLER_ENDSUBMSG, UPB_HANDLER_STARTSEQ, - UPB_HANDLER_ENDSEQ, + UPB_HANDLER_ENDSEQ } upb_handlertype_t; #define UPB_HANDLER_MAX (UPB_HANDLER_ENDSEQ+1) #define UPB_BREAK NULL -// A convenient definition for when no closure is needed. +/* A convenient definition for when no closure is needed. */ extern char _upb_noclosure; #define UPB_NO_CLOSURE &_upb_noclosure -// A selector refers to a specific field handler in the Handlers object -// (for example: the STARTSUBMSG handler for field "field15"). +/* A selector refers to a specific field handler in the Handlers object + * (for example: the STARTSUBMSG handler for field "field15"). */ typedef int32_t upb_selector_t; UPB_BEGIN_EXTERN_C -// Forward-declares for C inline accessors. We need to declare these here -// so we can "friend" them in the class declarations in C++. +/* Forward-declares for C inline accessors. We need to declare these here + * so we can "friend" them in the class declarations in C++. */ UPB_INLINE upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s); UPB_INLINE const void *upb_handlerattr_handlerdata(const upb_handlerattr *attr); @@ -103,104 +104,111 @@ UPB_INLINE const char *upb_bufhandle_buf(const upb_bufhandle *h); UPB_END_EXTERN_C -// Static selectors for upb::Handlers. +/* Static selectors for upb::Handlers. */ #define UPB_STARTMSG_SELECTOR 0 #define UPB_ENDMSG_SELECTOR 1 #define UPB_STATIC_SELECTOR_COUNT 2 -// Static selectors for upb::BytesHandler. +/* Static selectors for upb::BytesHandler. */ #define UPB_STARTSTR_SELECTOR 0 #define UPB_STRING_SELECTOR 1 #define UPB_ENDSTR_SELECTOR 2 typedef void upb_handlerfree(void *d); -// A set of attributes that accompanies a handler's function pointer. -UPB_DEFINE_CLASS0(upb::HandlerAttributes, +#ifdef __cplusplus + +/* A set of attributes that accompanies a handler's function pointer. */ +class upb::HandlerAttributes { public: HandlerAttributes(); ~HandlerAttributes(); - // Sets the handler data that will be passed as the second parameter of the - // handler. To free this pointer when the handlers are freed, call - // Handlers::AddCleanup(). + /* Sets the handler data that will be passed as the second parameter of the + * handler. To free this pointer when the handlers are freed, call + * Handlers::AddCleanup(). */ bool SetHandlerData(const void *handler_data); const void* handler_data() const; - // Use this to specify the type of the closure. This will be checked against - // all other closure types for handler that use the same closure. - // Registration will fail if this does not match all other non-NULL closure - // types. + /* Use this to specify the type of the closure. This will be checked against + * all other closure types for handler that use the same closure. + * Registration will fail if this does not match all other non-NULL closure + * types. */ bool SetClosureType(const void *closure_type); const void* closure_type() const; - // Use this to specify the type of the returned closure. Only used for - // Start*{String,SubMessage,Sequence} handlers. This must match the closure - // type of any handlers that use it (for example, the StringBuf handler must - // match the closure returned from StartString). + /* Use this to specify the type of the returned closure. Only used for + * Start*{String,SubMessage,Sequence} handlers. This must match the closure + * type of any handlers that use it (for example, the StringBuf handler must + * match the closure returned from StartString). */ bool SetReturnClosureType(const void *return_closure_type); const void* return_closure_type() const; - // Set to indicate that the handler always returns "ok" (either "true" or a - // non-NULL closure). This is a hint that can allow code generators to - // generate more efficient code. + /* Set to indicate that the handler always returns "ok" (either "true" or a + * non-NULL closure). This is a hint that can allow code generators to + * generate more efficient code. */ bool SetAlwaysOk(bool always_ok); bool always_ok() const; private: friend UPB_INLINE const void * ::upb_handlerattr_handlerdata( const upb_handlerattr *attr); -, -UPB_DEFINE_STRUCT0(upb_handlerattr, +#else +struct upb_handlerattr { +#endif const void *handler_data_; const void *closure_type_; const void *return_closure_type_; bool alwaysok_; -)); +}; #define UPB_HANDLERATTR_INITIALIZER {NULL, NULL, NULL, false} typedef struct { upb_func *func; - // It is wasteful to include the entire attributes here: - // - // * Some of the information is redundant (like storing the closure type - // separately for each handler that must match). - // * Some of the info is only needed prior to freeze() (like closure types). - // * alignment padding wastes a lot of space for alwaysok_. - // - // If/when the size and locality of handlers is an issue, we can optimize this - // not to store the entire attr like this. We do not expose the table's - // layout to allow this optimization in the future. + + /* It is wasteful to include the entire attributes here: + * + * * Some of the information is redundant (like storing the closure type + * separately for each handler that must match). + * * Some of the info is only needed prior to freeze() (like closure types). + * * alignment padding wastes a lot of space for alwaysok_. + * + * If/when the size and locality of handlers is an issue, we can optimize this + * not to store the entire attr like this. We do not expose the table's + * layout to allow this optimization in the future. */ upb_handlerattr attr; } upb_handlers_tabent; -// Extra information about a buffer that is passed to a StringBuf handler. -// TODO(haberman): allow the handle to be pinned so that it will outlive -// the handler invocation. -UPB_DEFINE_CLASS0(upb::BufferHandle, +#ifdef __cplusplus + +/* Extra information about a buffer that is passed to a StringBuf handler. + * TODO(haberman): allow the handle to be pinned so that it will outlive + * the handler invocation. */ +class upb::BufferHandle { public: BufferHandle(); ~BufferHandle(); - // The beginning of the buffer. This may be different than the pointer - // passed to a StringBuf handler because the handler may receive data - // that is from the middle or end of a larger buffer. + /* The beginning of the buffer. This may be different than the pointer + * passed to a StringBuf handler because the handler may receive data + * that is from the middle or end of a larger buffer. */ const char* buffer() const; - // The offset within the attached object where this buffer begins. Only - // meaningful if there is an attached object. + /* The offset within the attached object where this buffer begins. Only + * meaningful if there is an attached object. */ size_t object_offset() const; - // Note that object_offset is the offset of "buf" within the attached object. + /* Note that object_offset is the offset of "buf" within the attached + * object. */ void SetBuffer(const char* buf, size_t object_offset); - // The BufferHandle can have an "attached object", which can be used to - // tunnel through a pointer to the buffer's underlying representation. + /* The BufferHandle can have an "attached object", which can be used to + * tunnel through a pointer to the buffer's underlying representation. */ template <class T> void SetAttachedObject(const T* obj); - // Returns NULL if the attached object is not of this type. + /* Returns NULL if the attached object is not of this type. */ template <class T> const T* GetAttachedObject() const; @@ -215,26 +223,29 @@ UPB_DEFINE_CLASS0(upb::BufferHandle, friend UPB_INLINE const void* ::upb_bufhandle_objtype( const upb_bufhandle *h); friend UPB_INLINE const char* ::upb_bufhandle_buf(const upb_bufhandle *h); -, -UPB_DEFINE_STRUCT0(upb_bufhandle, +#else +struct upb_bufhandle { +#endif const char *buf_; const void *obj_; const void *objtype_; size_t objofs_; -)); - -// A upb::Handlers object represents the set of handlers associated with a -// message in the graph of messages. You can think of it as a big virtual -// table with functions corresponding to all the events that can fire while -// parsing or visiting a message of a specific type. -// -// Any handlers that are not set behave as if they had successfully consumed -// the value. Any unset Start* handlers will propagate their closure to the -// inner frame. -// -// The easiest way to create the *Handler objects needed by the Set* methods is -// with the UpbBind() and UpbMakeHandler() macros; see below. -UPB_DEFINE_CLASS1(upb::Handlers, upb::RefCounted, +}; + +#ifdef __cplusplus + +/* A upb::Handlers object represents the set of handlers associated with a + * message in the graph of messages. You can think of it as a big virtual + * table with functions corresponding to all the events that can fire while + * parsing or visiting a message of a specific type. + * + * Any handlers that are not set behave as if they had successfully consumed + * the value. Any unset Start* handlers will propagate their closure to the + * inner frame. + * + * The easiest way to create the *Handler objects needed by the Set* methods is + * with the UpbBind() and UpbMakeHandler() macros; see below. */ +class upb::Handlers { public: typedef upb_selector_t Selector; typedef upb_handlertype_t Type; @@ -259,95 +270,94 @@ UPB_DEFINE_CLASS1(upb::Handlers, upb::RefCounted, typedef ValueHandler<double>::H DoubleHandler; typedef ValueHandler<bool>::H BoolHandler; - // Any function pointer can be converted to this and converted back to its - // correct type. + /* Any function pointer can be converted to this and converted back to its + * correct type. */ typedef void GenericFunction(); typedef void HandlersCallback(const void *closure, upb_handlers *h); - // Returns a new handlers object for the given frozen msgdef. - // Returns NULL if memory allocation failed. + /* Returns a new handlers object for the given frozen msgdef. + * Returns NULL if memory allocation failed. */ static reffed_ptr<Handlers> New(const MessageDef *m); - // Convenience function for registering a graph of handlers that mirrors the - // graph of msgdefs for some message. For "m" and all its children a new set - // of handlers will be created and the given callback will be invoked, - // allowing the client to register handlers for this message. Note that any - // subhandlers set by the callback will be overwritten. + /* Convenience function for registering a graph of handlers that mirrors the + * graph of msgdefs for some message. For "m" and all its children a new set + * of handlers will be created and the given callback will be invoked, + * allowing the client to register handlers for this message. Note that any + * subhandlers set by the callback will be overwritten. */ static reffed_ptr<const Handlers> NewFrozen(const MessageDef *m, HandlersCallback *callback, const void *closure); - // Functionality from upb::RefCounted. - bool IsFrozen() const; - void Ref(const void* owner) const; - void Unref(const void* owner) const; - void DonateRef(const void *from, const void *to) const; - void CheckRef(const void *owner) const; - - // All handler registration functions return bool to indicate success or - // failure; details about failures are stored in this status object. If a - // failure does occur, it must be cleared before the Handlers are frozen, - // otherwise the freeze() operation will fail. The functions may *only* be - // used while the Handlers are mutable. + /* Functionality from upb::RefCounted. */ + UPB_REFCOUNTED_CPPMETHODS + + /* All handler registration functions return bool to indicate success or + * failure; details about failures are stored in this status object. If a + * failure does occur, it must be cleared before the Handlers are frozen, + * otherwise the freeze() operation will fail. The functions may *only* be + * used while the Handlers are mutable. */ const Status* status(); void ClearError(); - // Call to freeze these Handlers. Requires that any SubHandlers are already - // frozen. For cycles, you must use the static version below and freeze the - // whole graph at once. + /* Call to freeze these Handlers. Requires that any SubHandlers are already + * frozen. For cycles, you must use the static version below and freeze the + * whole graph at once. */ bool Freeze(Status* s); - // Freezes the given set of handlers. You may not freeze a handler without - // also freezing any handlers they point to. + /* Freezes the given set of handlers. You may not freeze a handler without + * also freezing any handlers they point to. */ static bool Freeze(Handlers*const* handlers, int n, Status* s); static bool Freeze(const std::vector<Handlers*>& handlers, Status* s); - // Returns the msgdef associated with this handlers object. + /* Returns the msgdef associated with this handlers object. */ const MessageDef* message_def() const; - // Adds the given pointer and function to the list of cleanup functions that - // will be run when these handlers are freed. If this pointer has previously - // been registered, the function returns false and does nothing. + /* Adds the given pointer and function to the list of cleanup functions that + * will be run when these handlers are freed. If this pointer has previously + * been registered, the function returns false and does nothing. */ bool AddCleanup(void *ptr, upb_handlerfree *cleanup); - // Sets the startmsg handler for the message, which is defined as follows: - // - // bool startmsg(MyType* closure) { - // // Called when the message begins. Returns true if processing should - // // continue. - // return true; - // } + /* Sets the startmsg handler for the message, which is defined as follows: + * + * bool startmsg(MyType* closure) { + * // Called when the message begins. Returns true if processing should + * // continue. + * return true; + * } + */ bool SetStartMessageHandler(const StartMessageHandler& handler); - // Sets the endmsg handler for the message, which is defined as follows: - // - // bool endmsg(MyType* closure, upb_status *status) { - // // Called when processing of this message ends, whether in success or - // // failure. "status" indicates the final status of processing, and - // // can also be modified in-place to update the final status. - // } + /* Sets the endmsg handler for the message, which is defined as follows: + * + * bool endmsg(MyType* closure, upb_status *status) { + * // Called when processing of this message ends, whether in success or + * // failure. "status" indicates the final status of processing, and + * // can also be modified in-place to update the final status. + * } + */ bool SetEndMessageHandler(const EndMessageHandler& handler); - // Sets the value handler for the given field, which is defined as follows - // (this is for an int32 field; other field types will pass their native - // C/C++ type for "val"): - // - // bool OnValue(MyClosure* c, const MyHandlerData* d, int32_t val) { - // // Called when the field's value is encountered. "d" contains - // // whatever data was bound to this field when it was registered. - // // Returns true if processing should continue. - // return true; - // } - // - // handers->SetInt32Handler(f, UpbBind(OnValue, new MyHandlerData(...))); - // - // The value type must exactly match f->type(). - // For example, a handler that takes an int32_t parameter may only be used for - // fields of type UPB_TYPE_INT32 and UPB_TYPE_ENUM. - // - // Returns false if the handler failed to register; in this case the cleanup - // handler (if any) will be called immediately. + /* Sets the value handler for the given field, which is defined as follows + * (this is for an int32 field; other field types will pass their native + * C/C++ type for "val"): + * + * bool OnValue(MyClosure* c, const MyHandlerData* d, int32_t val) { + * // Called when the field's value is encountered. "d" contains + * // whatever data was bound to this field when it was registered. + * // Returns true if processing should continue. + * return true; + * } + * + * handers->SetInt32Handler(f, UpbBind(OnValue, new MyHandlerData(...))); + * + * The value type must exactly match f->type(). + * For example, a handler that takes an int32_t parameter may only be used for + * fields of type UPB_TYPE_INT32 and UPB_TYPE_ENUM. + * + * Returns false if the handler failed to register; in this case the cleanup + * handler (if any) will be called immediately. + */ bool SetInt32Handler (const FieldDef* f, const Int32Handler& h); bool SetInt64Handler (const FieldDef* f, const Int64Handler& h); bool SetUInt32Handler(const FieldDef* f, const UInt32Handler& h); @@ -356,240 +366,247 @@ UPB_DEFINE_CLASS1(upb::Handlers, upb::RefCounted, bool SetDoubleHandler(const FieldDef* f, const DoubleHandler& h); bool SetBoolHandler (const FieldDef* f, const BoolHandler& h); - // Like the previous, but templated on the type on the value (ie. int32). - // This is mostly useful to call from other templates. To call this you must - // specify the template parameter explicitly, ie: - // h->SetValueHandler<T>(f, UpbBind(MyHandler<T>, MyData)); + /* Like the previous, but templated on the type on the value (ie. int32). + * This is mostly useful to call from other templates. To call this you must + * specify the template parameter explicitly, ie: + * h->SetValueHandler<T>(f, UpbBind(MyHandler<T>, MyData)); */ template <class T> bool SetValueHandler( const FieldDef *f, const typename ValueHandler<typename CanonicalType<T>::Type>::H& handler); - // Sets handlers for a string field, which are defined as follows: - // - // MySubClosure* startstr(MyClosure* c, const MyHandlerData* d, - // size_t size_hint) { - // // Called when a string value begins. The return value indicates the - // // closure for the string. "size_hint" indicates the size of the - // // string if it is known, however if the string is length-delimited - // // and the end-of-string is not available size_hint will be zero. - // // This case is indistinguishable from the case where the size is - // // known to be zero. - // // - // // TODO(haberman): is it important to distinguish these cases? - // // If we had ssize_t as a type we could make -1 "unknown", but - // // ssize_t is POSIX (not ANSI) and therefore less portable. - // // In practice I suspect it won't be important to distinguish. - // return closure; - // } - // - // size_t str(MyClosure* closure, const MyHandlerData* d, - // const char *str, size_t len) { - // // Called for each buffer of string data; the multiple physical buffers - // // are all part of the same logical string. The return value indicates - // // how many bytes were consumed. If this number is less than "len", - // // this will also indicate that processing should be halted for now, - // // like returning false or UPB_BREAK from any other callback. If - // // number is greater than "len", the excess bytes will be skipped over - // // and not passed to the callback. - // return len; - // } - // - // bool endstr(MyClosure* c, const MyHandlerData* d) { - // // Called when a string value ends. Return value indicates whether - // // processing should continue. - // return true; - // } + /* Sets handlers for a string field, which are defined as follows: + * + * MySubClosure* startstr(MyClosure* c, const MyHandlerData* d, + * size_t size_hint) { + * // Called when a string value begins. The return value indicates the + * // closure for the string. "size_hint" indicates the size of the + * // string if it is known, however if the string is length-delimited + * // and the end-of-string is not available size_hint will be zero. + * // This case is indistinguishable from the case where the size is + * // known to be zero. + * // + * // TODO(haberman): is it important to distinguish these cases? + * // If we had ssize_t as a type we could make -1 "unknown", but + * // ssize_t is POSIX (not ANSI) and therefore less portable. + * // In practice I suspect it won't be important to distinguish. + * return closure; + * } + * + * size_t str(MyClosure* closure, const MyHandlerData* d, + * const char *str, size_t len) { + * // Called for each buffer of string data; the multiple physical buffers + * // are all part of the same logical string. The return value indicates + * // how many bytes were consumed. If this number is less than "len", + * // this will also indicate that processing should be halted for now, + * // like returning false or UPB_BREAK from any other callback. If + * // number is greater than "len", the excess bytes will be skipped over + * // and not passed to the callback. + * return len; + * } + * + * bool endstr(MyClosure* c, const MyHandlerData* d) { + * // Called when a string value ends. Return value indicates whether + * // processing should continue. + * return true; + * } + */ bool SetStartStringHandler(const FieldDef* f, const StartStringHandler& h); bool SetStringHandler(const FieldDef* f, const StringHandler& h); bool SetEndStringHandler(const FieldDef* f, const EndFieldHandler& h); - // Sets the startseq handler, which is defined as follows: - // - // MySubClosure *startseq(MyClosure* c, const MyHandlerData* d) { - // // Called when a sequence (repeated field) begins. The returned - // // pointer indicates the closure for the sequence (or UPB_BREAK - // // to interrupt processing). - // return closure; - // } - // - // h->SetStartSequenceHandler(f, UpbBind(startseq, new MyHandlerData(...))); - // - // Returns "false" if "f" does not belong to this message or is not a - // repeated field. + /* Sets the startseq handler, which is defined as follows: + * + * MySubClosure *startseq(MyClosure* c, const MyHandlerData* d) { + * // Called when a sequence (repeated field) begins. The returned + * // pointer indicates the closure for the sequence (or UPB_BREAK + * // to interrupt processing). + * return closure; + * } + * + * h->SetStartSequenceHandler(f, UpbBind(startseq, new MyHandlerData(...))); + * + * Returns "false" if "f" does not belong to this message or is not a + * repeated field. + */ bool SetStartSequenceHandler(const FieldDef* f, const StartFieldHandler& h); - // Sets the startsubmsg handler for the given field, which is defined as - // follows: - // - // MySubClosure* startsubmsg(MyClosure* c, const MyHandlerData* d) { - // // Called when a submessage begins. The returned pointer indicates the - // // closure for the sequence (or UPB_BREAK to interrupt processing). - // return closure; - // } - // - // h->SetStartSubMessageHandler(f, UpbBind(startsubmsg, - // new MyHandlerData(...))); - // - // Returns "false" if "f" does not belong to this message or is not a - // submessage/group field. + /* Sets the startsubmsg handler for the given field, which is defined as + * follows: + * + * MySubClosure* startsubmsg(MyClosure* c, const MyHandlerData* d) { + * // Called when a submessage begins. The returned pointer indicates the + * // closure for the sequence (or UPB_BREAK to interrupt processing). + * return closure; + * } + * + * h->SetStartSubMessageHandler(f, UpbBind(startsubmsg, + * new MyHandlerData(...))); + * + * Returns "false" if "f" does not belong to this message or is not a + * submessage/group field. + */ bool SetStartSubMessageHandler(const FieldDef* f, const StartFieldHandler& h); - // Sets the endsubmsg handler for the given field, which is defined as - // follows: - // - // bool endsubmsg(MyClosure* c, const MyHandlerData* d) { - // // Called when a submessage ends. Returns true to continue processing. - // return true; - // } - // - // Returns "false" if "f" does not belong to this message or is not a - // submessage/group field. + /* Sets the endsubmsg handler for the given field, which is defined as + * follows: + * + * bool endsubmsg(MyClosure* c, const MyHandlerData* d) { + * // Called when a submessage ends. Returns true to continue processing. + * return true; + * } + * + * Returns "false" if "f" does not belong to this message or is not a + * submessage/group field. + */ bool SetEndSubMessageHandler(const FieldDef *f, const EndFieldHandler &h); - // Starts the endsubseq handler for the given field, which is defined as - // follows: - // - // bool endseq(MyClosure* c, const MyHandlerData* d) { - // // Called when a sequence ends. Returns true continue processing. - // return true; - // } - // - // Returns "false" if "f" does not belong to this message or is not a - // repeated field. + /* Starts the endsubseq handler for the given field, which is defined as + * follows: + * + * bool endseq(MyClosure* c, const MyHandlerData* d) { + * // Called when a sequence ends. Returns true continue processing. + * return true; + * } + * + * Returns "false" if "f" does not belong to this message or is not a + * repeated field. + */ bool SetEndSequenceHandler(const FieldDef* f, const EndFieldHandler& h); - // Sets or gets the object that specifies handlers for the given field, which - // must be a submessage or group. Returns NULL if no handlers are set. + /* Sets or gets the object that specifies handlers for the given field, which + * must be a submessage or group. Returns NULL if no handlers are set. */ bool SetSubHandlers(const FieldDef* f, const Handlers* sub); const Handlers* GetSubHandlers(const FieldDef* f) const; - // Equivalent to GetSubHandlers, but takes the STARTSUBMSG selector for the - // field. + /* Equivalent to GetSubHandlers, but takes the STARTSUBMSG selector for the + * field. */ const Handlers* GetSubHandlers(Selector startsubmsg) const; - // A selector refers to a specific field handler in the Handlers object - // (for example: the STARTSUBMSG handler for field "field15"). - // On success, returns true and stores the selector in "s". - // If the FieldDef or Type are invalid, returns false. - // The returned selector is ONLY valid for Handlers whose MessageDef - // contains this FieldDef. + /* A selector refers to a specific field handler in the Handlers object + * (for example: the STARTSUBMSG handler for field "field15"). + * On success, returns true and stores the selector in "s". + * If the FieldDef or Type are invalid, returns false. + * The returned selector is ONLY valid for Handlers whose MessageDef + * contains this FieldDef. */ static bool GetSelector(const FieldDef* f, Type type, Selector* s); - // Given a START selector of any kind, returns the corresponding END selector. + /* Given a START selector of any kind, returns the corresponding END selector. */ static Selector GetEndSelector(Selector start_selector); - // Returns the function pointer for this handler. It is the client's - // responsibility to cast to the correct function type before calling it. + /* Returns the function pointer for this handler. It is the client's + * responsibility to cast to the correct function type before calling it. */ GenericFunction* GetHandler(Selector selector); - // Sets the given attributes to the attributes for this selector. + /* Sets the given attributes to the attributes for this selector. */ bool GetAttributes(Selector selector, HandlerAttributes* attr); - // Returns the handler data that was registered with this handler. + /* Returns the handler data that was registered with this handler. */ const void* GetHandlerData(Selector selector); - // Could add any of the following functions as-needed, with some minor - // implementation changes: - // - // const FieldDef* GetFieldDef(Selector selector); - // static bool IsSequence(Selector selector); + /* Could add any of the following functions as-needed, with some minor + * implementation changes: + * + * const FieldDef* GetFieldDef(Selector selector); + * static bool IsSequence(Selector selector); */ private: - UPB_DISALLOW_POD_OPS(Handlers, upb::Handlers); + UPB_DISALLOW_POD_OPS(Handlers, upb::Handlers) friend UPB_INLINE GenericFunction *::upb_handlers_gethandler( const upb_handlers *h, upb_selector_t s); friend UPB_INLINE const void *::upb_handlers_gethandlerdata( const upb_handlers *h, upb_selector_t s); +#else +struct upb_handlers { +#endif + upb_refcounted base; -, -UPB_DEFINE_STRUCT(upb_handlers, upb_refcounted, const upb_msgdef *msg; const upb_handlers **sub; const void *top_closure_type; upb_inttable cleanup_; - upb_status status_; // Used only when mutable. - upb_handlers_tabent table[1]; // Dynamically-sized field handler array. -)); - + upb_status status_; /* Used only when mutable. */ + upb_handlers_tabent table[1]; /* Dynamically-sized field handler array. */ +}; #ifdef __cplusplus namespace upb { -// Convenience macros for creating a Handler object that is wrapped with a -// type-safe wrapper function that converts the "void*" parameters/returns -// of the underlying C API into nice C++ function. -// -// Sample usage: -// void OnValue1(MyClosure* c, const MyHandlerData* d, int32_t val) { -// // do stuff ... -// } -// -// // Handler that doesn't need any data bound to it. -// void OnValue2(MyClosure* c, int32_t val) { -// // do stuff ... -// } -// -// // Handler that returns bool so it can return failure if necessary. -// bool OnValue3(MyClosure* c, int32_t val) { -// // do stuff ... -// return ok; -// } -// -// // Member function handler. -// class MyClosure { -// public: -// void OnValue(int32_t val) { -// // do stuff ... -// } -// }; -// -// // Takes ownership of the MyHandlerData. -// handlers->SetInt32Handler(f1, UpbBind(OnValue1, new MyHandlerData(...))); -// handlers->SetInt32Handler(f2, UpbMakeHandler(OnValue2)); -// handlers->SetInt32Handler(f1, UpbMakeHandler(OnValue3)); -// handlers->SetInt32Handler(f2, UpbMakeHandler(&MyClosure::OnValue)); +/* Convenience macros for creating a Handler object that is wrapped with a + * type-safe wrapper function that converts the "void*" parameters/returns + * of the underlying C API into nice C++ function. + * + * Sample usage: + * void OnValue1(MyClosure* c, const MyHandlerData* d, int32_t val) { + * // do stuff ... + * } + * + * // Handler that doesn't need any data bound to it. + * void OnValue2(MyClosure* c, int32_t val) { + * // do stuff ... + * } + * + * // Handler that returns bool so it can return failure if necessary. + * bool OnValue3(MyClosure* c, int32_t val) { + * // do stuff ... + * return ok; + * } + * + * // Member function handler. + * class MyClosure { + * public: + * void OnValue(int32_t val) { + * // do stuff ... + * } + * }; + * + * // Takes ownership of the MyHandlerData. + * handlers->SetInt32Handler(f1, UpbBind(OnValue1, new MyHandlerData(...))); + * handlers->SetInt32Handler(f2, UpbMakeHandler(OnValue2)); + * handlers->SetInt32Handler(f1, UpbMakeHandler(OnValue3)); + * handlers->SetInt32Handler(f2, UpbMakeHandler(&MyClosure::OnValue)); + */ #ifdef UPB_CXX11 -// In C++11, the "template" disambiguator can appear even outside templates, -// so all calls can safely use this pair of macros. +/* In C++11, the "template" disambiguator can appear even outside templates, + * so all calls can safely use this pair of macros. */ #define UpbMakeHandler(f) upb::MatchFunc(f).template GetFunc<f>() -// We have to be careful to only evaluate "d" once. +/* We have to be careful to only evaluate "d" once. */ #define UpbBind(f, d) upb::MatchFunc(f).template GetFunc<f>((d)) #else -// Prior to C++11, the "template" disambiguator may only appear inside a -// template, so the regular macro must not use "template" +/* Prior to C++11, the "template" disambiguator may only appear inside a + * template, so the regular macro must not use "template" */ #define UpbMakeHandler(f) upb::MatchFunc(f).GetFunc<f>() #define UpbBind(f, d) upb::MatchFunc(f).GetFunc<f>((d)) -#endif // UPB_CXX11 +#endif /* UPB_CXX11 */ -// This macro must be used in C++98 for calls from inside a template. But we -// define this variant in all cases; code that wants to be compatible with both -// C++98 and C++11 should always use this macro when calling from a template. +/* This macro must be used in C++98 for calls from inside a template. But we + * define this variant in all cases; code that wants to be compatible with both + * C++98 and C++11 should always use this macro when calling from a template. */ #define UpbMakeHandlerT(f) upb::MatchFunc(f).template GetFunc<f>() -// We have to be careful to only evaluate "d" once. +/* We have to be careful to only evaluate "d" once. */ #define UpbBindT(f, d) upb::MatchFunc(f).template GetFunc<f>((d)) -// Handler: a struct that contains the (handler, data, deleter) tuple that is -// used to register all handlers. Users can Make() these directly but it's -// more convenient to use the UpbMakeHandler/UpbBind macros above. +/* Handler: a struct that contains the (handler, data, deleter) tuple that is + * used to register all handlers. Users can Make() these directly but it's + * more convenient to use the UpbMakeHandler/UpbBind macros above. */ template <class T> class Handler { public: - // The underlying, handler function signature that upb uses internally. + /* The underlying, handler function signature that upb uses internally. */ typedef T FuncPtr; - // Intentionally implicit. + /* Intentionally implicit. */ template <class F> Handler(F func); ~Handler(); @@ -601,7 +618,7 @@ template <class T> class Handler { } } - UPB_DISALLOW_COPY_AND_ASSIGN(Handler); + UPB_DISALLOW_COPY_AND_ASSIGN(Handler) friend class Handlers; FuncPtr handler_; mutable HandlerAttributes attr_; @@ -610,15 +627,15 @@ template <class T> class Handler { upb_handlerfree *cleanup_func_; }; -} // namespace upb +} /* namespace upb */ -#endif // __cplusplus +#endif /* __cplusplus */ UPB_BEGIN_EXTERN_C -// Native C API. +/* Native C API. */ -// Handler function typedefs. +/* Handler function typedefs. */ typedef bool upb_startmsg_handlerfunc(void *c, const void*); typedef bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status); typedef void* upb_startfield_handlerfunc(void *c, const void *hd); @@ -635,10 +652,10 @@ typedef void *upb_startstr_handlerfunc(void *c, const void *hd, typedef size_t upb_string_handlerfunc(void *c, const void *hd, const char *buf, size_t n, const upb_bufhandle* handle); -// upb_bufhandle +/* upb_bufhandle */ size_t upb_bufhandle_objofs(const upb_bufhandle *h); -// upb_handlerattr +/* upb_handlerattr */ void upb_handlerattr_init(upb_handlerattr *attr); void upb_handlerattr_uninit(upb_handlerattr *attr); @@ -656,7 +673,7 @@ UPB_INLINE const void *upb_handlerattr_handlerdata( return attr->handler_data_; } -// upb_handlers +/* upb_handlers */ typedef void upb_handlers_callback(const void *closure, upb_handlers *h); upb_handlers *upb_handlers_new(const upb_msgdef *m, const void *owner); @@ -664,12 +681,9 @@ const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m, const void *owner, upb_handlers_callback *callback, const void *closure); -bool upb_handlers_isfrozen(const upb_handlers *h); -void upb_handlers_ref(const upb_handlers *h, const void *owner); -void upb_handlers_unref(const upb_handlers *h, const void *owner); -void upb_handlers_donateref(const upb_handlers *h, const void *from, - const void *to); -void upb_handlers_checkref(const upb_handlers *h, const void *owner); + +/* Include refcounted methods like upb_handlers_ref(). */ +UPB_REFCOUNTED_CMETHODS(upb_handlers, upb_handlers_upcast) const upb_status *upb_handlers_status(upb_handlers *h); void upb_handlers_clearerr(upb_handlers *h); @@ -740,26 +754,29 @@ UPB_INLINE const void *upb_handlers_gethandlerdata(const upb_handlers *h, return upb_handlerattr_handlerdata(&h->table[s].attr); } -// Handler types for single fields. -// Right now we only have one for TYPE_BYTES but ones for other types -// should follow. -// -// These follow the same handlers protocol for fields of a message. -UPB_DEFINE_CLASS0(upb::BytesHandler, +#ifdef __cplusplus + +/* Handler types for single fields. + * Right now we only have one for TYPE_BYTES but ones for other types + * should follow. + * + * These follow the same handlers protocol for fields of a message. */ +class upb::BytesHandler { public: BytesHandler(); ~BytesHandler(); -, -UPB_DEFINE_STRUCT0(upb_byteshandler, +#else +struct upb_byteshandler { +#endif upb_handlers_tabent table[3]; -)); +}; void upb_byteshandler_init(upb_byteshandler *h); -// Caller must ensure that "d" outlives the handlers. -// TODO(haberman): should this have a "freeze" operation? It's not necessary -// for memory management, but could be useful to force immutability and provide -// a convenient moment to verify that all registration succeeded. +/* Caller must ensure that "d" outlives the handlers. + * TODO(haberman): should this have a "freeze" operation? It's not necessary + * for memory management, but could be useful to force immutability and provide + * a convenient moment to verify that all registration succeeded. */ bool upb_byteshandler_setstartstr(upb_byteshandler *h, upb_startstr_handlerfunc *func, void *d); bool upb_byteshandler_setstring(upb_byteshandler *h, @@ -767,7 +784,7 @@ bool upb_byteshandler_setstring(upb_byteshandler *h, bool upb_byteshandler_setendstr(upb_byteshandler *h, upb_endfield_handlerfunc *func, void *d); -// "Static" methods +/* "Static" methods */ bool upb_handlers_freeze(upb_handlers *const *handlers, int n, upb_status *s); upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f); bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type, @@ -776,7 +793,7 @@ UPB_INLINE upb_selector_t upb_handlers_getendselector(upb_selector_t start) { return start + 1; } -// Internal-only. +/* Internal-only. */ uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f); uint32_t upb_handlers_selectorcount(const upb_fielddef *f); @@ -784,4 +801,4 @@ UPB_END_EXTERN_C #include "upb/handlers-inl.h" -#endif // UPB_HANDLERS_H +#endif /* UPB_HANDLERS_H */ |