summaryrefslogtreecommitdiff
path: root/upb/handlers.h
diff options
context:
space:
mode:
authorJosh Haberman <haberman@google.com>2013-05-11 16:45:38 -0700
committerJosh Haberman <haberman@google.com>2013-05-11 16:45:38 -0700
commitcfdb9907cb87d15eaab72ceefbfa42fd7a4c3127 (patch)
tree63f5d70ad64daeeb4ffc777c2c3afd50e2e281b1 /upb/handlers.h
parent7d3e2bd2c4cfd1296d1d6f996d7548de26540d41 (diff)
Synced with 3 months of Google-internal development.
Major changes: - Got rid of all bytestream interfaces in favor of using regular handlers. - new Pipeline object represents a upb pipeline, does bump allocation internally to manage memory. - proto2 support now can handle extensions.
Diffstat (limited to 'upb/handlers.h')
-rw-r--r--upb/handlers.h505
1 files changed, 414 insertions, 91 deletions
diff --git a/upb/handlers.h b/upb/handlers.h
index 094702e..582ba43 100644
--- a/upb/handlers.h
+++ b/upb/handlers.h
@@ -25,11 +25,23 @@
#include "upb/def.h"
#ifdef __cplusplus
-namespace upb { class Handlers; }
+struct upb_frametype;
+namespace upb {
+typedef upb_frametype FrameType;
+class Handlers;
+class SinkFrame;
+}
+typedef upb::FrameType upb_frametype;
typedef upb::Handlers upb_handlers;
+typedef upb::SinkFrame upb_sinkframe;
+UPB_INLINE void *upb_sinkframe_handlerdata(const upb_sinkframe* frame);
#else
+struct upb_frametype;
struct upb_handlers;
+struct upb_sinkframe;
+typedef struct upb_frametype upb_frametype;
typedef struct upb_handlers upb_handlers;
+typedef struct upb_sinkframe upb_sinkframe;
#endif
// All the different types of handlers that can be registered.
@@ -61,7 +73,7 @@ extern char _upb_noclosure;
// A selector refers to a specific field handler in the Handlers object
// (for example: the STARTSUBMSG handler for field "field15").
-typedef uint32_t upb_selector_t;
+typedef int32_t upb_selector_t;
#ifdef __cplusplus
@@ -78,24 +90,34 @@ class upb::Handlers {
typedef upb_selector_t Selector;
typedef upb_handlertype_t Type;
- typedef bool StartMessageHandler(void* closure);
- typedef void EndMessageHandler(void* closure, Status* status);
- typedef void* StartFieldHandler(void* closure, void* data);
- typedef bool EndFieldHandler(void *closure, void *data);
- typedef void* StartStringHandler(void *c, void *d, size_t size_hint);
- typedef size_t StringHandler(void *c, void *d, const char *buf, size_t len);
+ typedef bool StartMessageHandler(const SinkFrame*);
+ typedef void EndMessageHandler(const SinkFrame*, Status* status);
+ typedef void* StartFieldHandler(const SinkFrame*);
+ typedef bool EndFieldHandler(const SinkFrame*);
+ typedef void* StartStringHandler(const SinkFrame* c, size_t size_hint);
+ typedef size_t StringHandler(const SinkFrame* c, const char* buf, size_t len);
template <class T> struct Value {
- typedef bool Handler(void* closure, void* data, T val);
+ typedef bool Handler(const SinkFrame*, T val);
};
- typedef Value<int32_t>::Handler Int32Handler;
- typedef Value<int64_t>::Handler Int64Handler;
- typedef Value<uint32_t>::Handler Uint32Handler;
- typedef Value<uint64_t>::Handler Uint64Handler;
- typedef Value<float>::Handler FloatHandler;
- typedef Value<double>::Handler DoubleHandler;
- typedef Value<bool>::Handler BoolHandler;
+ typedef Value<upb_int32_t>::Handler Int32Handler;
+ typedef Value<upb_int64_t>::Handler Int64Handler;
+ typedef Value<upb_uint32_t>::Handler UInt32Handler;
+ typedef Value<upb_uint64_t>::Handler UInt64Handler;
+ typedef Value<float>::Handler FloatHandler;
+ typedef Value<double>::Handler DoubleHandler;
+ typedef Value<bool>::Handler BoolHandler;
+
+#ifdef UPB_TWO_32BIT_TYPES
+ typedef Value<upb_int32alt_t>::Handler Int32Handler2;
+ typedef Value<upb_uint32alt_t>::Handler UInt32Handler2;
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+ typedef Value<upb_int64alt_t>::Handler Int64Handler2;
+ typedef Value<upb_uint64alt_t>::Handler UInt64Handler2;
+#endif
// Any function pointer can be converted to this and converted back to its
// correct type.
@@ -106,17 +128,23 @@ class upb::Handlers {
typedef void HandlersCallback(void *closure, upb_handlers *h);
- // Returns a new handlers object for the given frozen msgdef. A single ref
- // will belong to the given owner.
+ // Returns a new handlers object for the given frozen msgdef that will use
+ // the given FrameType as its top-level state (can be NULL, for now). A
+ // single ref on the returned object will belong to the given owner.
// Returns NULL if memory allocation failed.
- static Handlers* New(const MessageDef* m, const void *owner);
+ static Handlers* New(const MessageDef* m,
+ const FrameType* ft,
+ const void *owner);
// 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 const Handlers* NewFrozen(const MessageDef *m, const void *owner,
+ // subhandlers set by the callback will be overwritten. A single ref on the
+ // returned object will belong to the given owner.
+ static const Handlers* NewFrozen(const MessageDef *m,
+ const FrameType* ft,
+ const void *owner,
HandlersCallback *callback, void *closure);
// Functionality from upb::RefCounted.
@@ -126,6 +154,9 @@ class upb::Handlers {
void DonateRef(const void *from, const void *to) const;
void CheckRef(const void *owner) const;
+ // Top-level frame type.
+ const FrameType* frame_type() const;
+
// Freezes the given set of handlers. You may not freeze a handler without
// also freezing any handlers they point to. In the future we may want to
// require that all fields of the submessage have had subhandlers set for
@@ -137,7 +168,7 @@ class upb::Handlers {
// Sets the startmsg handler for the message, which is defined as follows:
//
- // bool startmsg(void *closure) {
+ // bool startmsg(const upb::SinkFrame* frame) {
// // Called when the message begins. Returns true if processing should
// // continue.
// return true;
@@ -147,7 +178,7 @@ class upb::Handlers {
// Sets the endmsg handler for the message, which is defined as follows:
//
- // void endmsg(void *closure, upb_status *status) {
+ // void endmsg(const upb::SinkFrame* frame, 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.
@@ -159,7 +190,7 @@ class upb::Handlers {
// (this is for an int32 field; other field types will pass their native
// C/C++ type for "val"):
//
- // bool value(void *closure, void *d, int32_t val) {
+ // bool value(const upb::SinkFrame *frame, upb_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.
@@ -168,24 +199,72 @@ class upb::Handlers {
//
// The value type must exactly match f->type().
// For example, SetInt32Handler() may only be used for fields of type
- // UPB_TYPE_INT32, UPB_TYPE_SINT32, UPB_TYPE_SFIXED32, and UPB_TYPE_ENUM.
+ // UPB_TYPE_INT32 and UPB_TYPE_ENUM.
//
// "d" is the data that will be bound to this callback and passed to it.
// If "fr" is non-NULL it will be run when the data is no longer needed.
//
// Returns "false" if "f" does not belong to this message or has the wrong
// type for this handler.
+ //
+ // NOTE: the prototype above uses "upb_int32_t" and not "int32_t" from
+ // stdint.h. For C++ any int32 typedef will work correctly thanks to
+ // function overloading on the function pointer type. But in C things are
+ // more complicated; "int" and "long" could both be 32-bit types, but the
+ // two are incompatible with each other when it comes to function pointers.
+ // Since we don't know what the underlying type of int32_t is, we have to
+ // define our own which we *do* know the underlying type of. The easiest
+ // and most portable choice is to define handlers in C with the upb_intXX_t
+ // types.
bool SetInt32Handler (const FieldDef* f, Int32Handler* h, void* d, Free* fr);
bool SetInt64Handler (const FieldDef* f, Int64Handler* h, void* d, Free* fr);
- bool SetUint32Handler(const FieldDef* f, Uint32Handler* h, void* d, Free* fr);
- bool SetUint64Handler(const FieldDef* f, Uint64Handler* h, void* d, Free* fr);
+ bool SetUInt32Handler(const FieldDef* f, UInt32Handler* h, void* d, Free* fr);
+ bool SetUInt64Handler(const FieldDef* f, UInt64Handler* h, void* d, Free* fr);
bool SetFloatHandler (const FieldDef* f, FloatHandler* h, void* d, Free* fr);
bool SetDoubleHandler(const FieldDef* f, DoubleHandler* h, void* d, Free* fr);
bool SetBoolHandler (const FieldDef* f, BoolHandler* h, void* d, Free* fr);
+ // Convenience versions that look up the field by name first. These return
+ // false if no field with this name exists, or for any of the other reasons
+ // that the FieldDef* version returns false.
+ bool SetInt32Handler (const char *name, Int32Handler* h, void* d, Free* fr);
+ bool SetInt64Handler (const char *name, Int64Handler* h, void* d, Free* fr);
+ bool SetUInt32Handler(const char *name, UInt32Handler* h, void* d, Free* fr);
+ bool SetUInt64Handler(const char *name, UInt64Handler* h, void* d, Free* fr);
+ bool SetFloatHandler (const char *name, FloatHandler* h, void* d, Free* fr);
+ bool SetDoubleHandler(const char *name, DoubleHandler* h, void* d, Free* fr);
+ bool SetBoolHandler (const char *name, BoolHandler* h, void* d, Free* fr);
+
+ // On platforms where there are two 32-bit or 64-bit integer types, provide
+ // registration functions for both. Function overloading should make this
+ // all transparent to the user.
+#ifdef UPB_TWO_32BIT_TYPES
+ bool SetInt32Handler (const FieldDef* f, Int32Handler2* h, void* d, Free* x);
+ bool SetUInt32Handler(const FieldDef* f, UInt32Handler2* h, void* d, Free* x);
+ bool SetInt32Handler (const char *name, Int32Handler2* h, void* d, Free* x);
+ bool SetUInt32Handler(const char *name, UInt32Handler2* h, void* d, Free* x);
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+ bool SetInt64Handler (const FieldDef* f, Int64Handler2* h, void* d, Free* x);
+ bool SetUInt64Handler(const FieldDef* f, UInt64Handler2* h, void* d, Free* x);
+ bool SetInt64Handler (const char *name, Int64Handler2* h, void* d, Free* x);
+ bool SetUInt64Handler(const char *name, UInt64Handler2* h, void* d, Free* x);
+#endif
+
+ // Like the above, but these are templated on the type of the value. For
+ // example, templating on int64_t is equivalent to calling SetInt64Handler.
+ // Attempts to template on a type that does not map to a UPB_TYPE_* type
+ // (like int8_t, since protobufs have no 8-bit type) will get an "undefined
+ // function" compilation error.
+ template<class T> bool SetValueHandler(
+ const FieldDef* f, typename Value<T>::Handler* h, void* d, Free* fr);
+ template<class T> bool SetValueHandler(
+ const char* name, typename Value<T>::Handler* h, void* d, Free* fr);
+
// Sets handlers for a string field, which are defined as follows:
//
- // void* startstr(void *closure, void *data, size_t size_hint) {
+ // void* startstr(const upb::SinkFrame *frame, 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
@@ -200,7 +279,7 @@ class upb::Handlers {
// return closure;
// }
//
- // size_t str(void *closure, void *data, const char *str, size_t len) {
+ // size_t str(const upb::SinkFrame* frame, 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",
@@ -211,7 +290,7 @@ class upb::Handlers {
// return len;
// }
//
- // bool endstr(void *closure, void *data) {
+ // bool endstr(const upb::SinkFrame* frame) {
// // Called when a string value ends.
// return true;
// }
@@ -221,13 +300,18 @@ class upb::Handlers {
bool SetEndStringHandler(const FieldDef* f, EndFieldHandler* h,
void* d, Free* fr);
- // A setter that is templated on the type of the value.
- template<class T> bool SetValueHandler(
- const FieldDef* f, typename Value<T>::Handler* h, void* d, Free* fr);
+ // Convenience versions that look up the field by name first. These return
+ // false if no field with this name exists, or for any of the other reasons
+ // that the FieldDef* version returns false.
+ bool SetStartStringHandler(const char* name, StartStringHandler* h,
+ void* d, Free* fr);
+ bool SetStringHandler(const char* name, StringHandler* h, void* d, Free* fr);
+ bool SetEndStringHandler(const char* name, EndFieldHandler* h,
+ void* d, Free* fr);
// Sets the startseq handler, which is defined as follows:
//
- // void *startseq(void *closure, void *data) {
+ // void *startseq(const upb::SinkFrame* frame) {
// // Called when a sequence (repeated field) begins. The returned
// // pointer indicates the closure for the sequence (or UPB_BREAK
// // to interrupt processing).
@@ -241,11 +325,13 @@ class upb::Handlers {
// If "cleanup" is non-NULL it will be run when the data is no longer needed.
bool SetStartSequenceHandler(const FieldDef* f, StartFieldHandler *handler,
void* data, Free* cleanup);
+ bool SetStartSequenceHandler(const char* name, StartFieldHandler *handler,
+ void* data, Free* cleanup);
// Sets the startsubmsg handler for the given field, which is defined as
// follows:
//
- // void *startsubmsg(void *closure, void *data) {
+ // void *startsubmsg(const upb::SinkFrame *frame) {
// // Called when a submessage begins. The returned pointer indicates the
// // closure for the sequence (or UPB_BREAK to interrupt processing).
// return closure;
@@ -258,11 +344,13 @@ class upb::Handlers {
// submessage/group field.
bool SetStartSubMessageHandler(const FieldDef* f, StartFieldHandler *handler,
void* data, Free* cleanup);
+ bool SetStartSubMessageHandler(const char* name, StartFieldHandler *handler,
+ void* data, Free* cleanup);
// Sets the endsubmsg handler for the given field, which is defined as
// follows:
//
- // bool endsubmsg(void *closure, void *data) {
+ // bool endsubmsg(const upb::SinkFrame *frame) {
// // Called when a submessage ends. Returns true to continue processing.
// return true;
// }
@@ -274,11 +362,13 @@ class upb::Handlers {
// submessage/group field.
bool SetEndSubMessageHandler(const FieldDef* f, EndFieldHandler *handler,
void* data, Free* cleanup);
+ bool SetEndSubMessageHandler(const char* name, EndFieldHandler *handler,
+ void* data, Free* cleanup);
// Starts the endsubseq handler for the given field, which is defined as
// follows:
//
- // bool endseq(void *closure, void *data) {
+ // bool endseq(const upb::SinkFrame *frame) {
// // Called when a sequence ends. Returns true continue processing.
// return true;
// }
@@ -290,16 +380,17 @@ class upb::Handlers {
// repeated field.
bool SetEndSequenceHandler(const FieldDef* f, EndFieldHandler *handler,
void* data, Free* cleanup);
+ bool SetEndSequenceHandler(const char* name, EndFieldHandler *handler,
+ void* data, Free* cleanup);
// 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;
- // NOTE: The remaining functions in this class are mostly of interest to
- // byte-code/JIT compilers (or upb internals); most users will not need them.
- // These functions also require more care, since passing a selector that
- // does not match the type of these handlers yields undefined behavior.
+ // 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").
@@ -309,6 +400,9 @@ class upb::Handlers {
// 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.
+ 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.
GenericFunction* GetHandler(Selector selector);
@@ -325,18 +419,19 @@ class upb::Handlers {
//
// const FieldDef* GetFieldDef(Selector selector);
// static bool IsSequence(Selector selector);
- // Selector GetEndSelector(Selector start_selector);
private:
UPB_DISALLOW_POD_OPS(Handlers);
+ friend void* ::upb_sinkframe_handlerdata(const upb_sinkframe* frame);
#else
struct upb_handlers {
#endif
upb_refcounted base;
const upb_msgdef *msg;
- bool (*startmsg)(void*);
- void (*endmsg)(void*, upb_status*);
+ const upb_frametype *ft;
+ bool (*startmsg)(const upb_sinkframe*);
+ void (*endmsg)(const upb_sinkframe*, upb_status*);
void *fh_base[1]; // Start of dynamically-sized field handler array.
};
@@ -344,26 +439,40 @@ struct upb_handlers {
#ifdef __cplusplus
extern "C" {
#endif
-typedef bool upb_startmsg_handler(void *c);
-typedef void upb_endmsg_handler(void *c, upb_status *status);
-typedef void* upb_startfield_handler(void *closure, void *d);
-typedef bool upb_endfield_handler(void *closure, void *d);
+typedef bool upb_startmsg_handler(const upb_sinkframe *frame);
+typedef void upb_endmsg_handler(const upb_sinkframe *frame, upb_status *status);
+typedef void* upb_startfield_handler(const upb_sinkframe *frame);
+typedef bool upb_endfield_handler(const upb_sinkframe *frame);
typedef void upb_handlers_callback(void *closure, upb_handlers *h);
typedef void upb_handlerfree(void *d);
typedef void upb_func();
-typedef bool upb_int32_handler(void *c, void *d, int32_t val);
-typedef bool upb_int64_handler(void *c, void *d, int64_t val);
-typedef bool upb_uint32_handler(void *c, void *d, uint32_t val);
-typedef bool upb_uint64_handler(void *c, void *d, uint64_t val);
-typedef bool upb_float_handler(void *c, void *d, float val);
-typedef bool upb_double_handler(void *c, void *d, double val);
-typedef bool upb_bool_handler(void *c, void *d, bool val);
-typedef void* upb_startstr_handler(void *closure, void *d, size_t size_hint);
-typedef size_t upb_string_handler(void *c, void *d, const char *buf, size_t n);
-
-upb_handlers *upb_handlers_new(const upb_msgdef *m, const void *owner);
+typedef bool upb_int32_handler(const upb_sinkframe *f, upb_int32_t val);
+typedef bool upb_int64_handler(const upb_sinkframe *f, upb_int64_t val);
+typedef bool upb_uint32_handler(const upb_sinkframe *f, upb_uint32_t val);
+typedef bool upb_uint64_handler(const upb_sinkframe *f, upb_uint64_t val);
+typedef bool upb_float_handler(const upb_sinkframe *f, float val);
+typedef bool upb_double_handler(const upb_sinkframe *f, double val);
+typedef bool upb_bool_handler(const upb_sinkframe *f, bool val);
+typedef void* upb_startstr_handler(const upb_sinkframe *f, size_t size_hint);
+typedef size_t upb_string_handler(
+ const upb_sinkframe *f, const char *buf, size_t n);
+
+#ifdef UPB_TWO_32BIT_TYPES
+typedef bool upb_int32_handler2(const upb_sinkframe *f, upb_int32alt_t val);
+typedef bool upb_uint32_handler2(const upb_sinkframe *f, upb_uint32alt_t val);
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+typedef bool upb_int64_handler2(const upb_sinkframe *f, upb_int64alt_t val);
+typedef bool upb_uint64_handler2(const upb_sinkframe *f, upb_uint64alt_t val);
+#endif
+
+upb_handlers *upb_handlers_new(const upb_msgdef *m,
+ const upb_frametype *ft,
+ const void *owner);
const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
+ const upb_frametype *ft,
const void *owner,
upb_handlers_callback *callback,
void *closure);
@@ -378,6 +487,7 @@ void upb_handlers_checkref(const upb_handlers *h, const void *owner);
bool upb_handlers_freeze(upb_handlers *const*handlers, int n, upb_status *s);
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
+const upb_frametype *upb_handlers_frametype(const upb_handlers *h);
void upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handler *handler);
upb_startmsg_handler *upb_handlers_getstartmsg(const upb_handlers *h);
void upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handler *handler);
@@ -428,13 +538,36 @@ bool upb_handlers_setsubhandlers(
upb_handlers *h, const upb_fielddef *f, const upb_handlers *sub);
const upb_handlers *upb_handlers_getsubhandlers(
const upb_handlers *h, const upb_fielddef *f);
+const upb_handlers *upb_handlers_getsubhandlers_sel(
+ const upb_handlers *h, upb_selector_t sel);
upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f);
bool upb_getselector(
const upb_fielddef *f, upb_handlertype_t type, upb_selector_t *s);
+UPB_INLINE upb_selector_t upb_getendselector(upb_selector_t start) {
+ return start + 1;
+}
upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s);
void *upb_handlers_gethandlerdata(const upb_handlers *h, upb_selector_t s);
size_t upb_gethandleroffset(upb_selector_t s);
+#ifdef UPB_TWO_32BIT_TYPES
+bool upb_handlers_setint32alt(
+ upb_handlers *h, const upb_fielddef *f, upb_int32_handler2 *handler,
+ void *d, upb_handlerfree *fr);
+bool upb_handlers_setuint32alt(
+ upb_handlers *h, const upb_fielddef *f, upb_uint32_handler2 *handler,
+ void *d, upb_handlerfree *fr);
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+bool upb_handlers_setint64alt(
+ upb_handlers *h, const upb_fielddef *f, upb_int64_handler2 *handler,
+ void *d, upb_handlerfree *fr);
+bool upb_handlers_setuint64alt(
+ upb_handlers *h, const upb_fielddef *f, upb_uint64_handler2 *handler,
+ void *d, upb_handlerfree *fr);
+#endif
+
// Internal-only.
uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f);
uint32_t upb_handlers_selectorcount(const upb_fielddef *f);
@@ -444,11 +577,12 @@ uint32_t upb_handlers_selectorcount(const upb_fielddef *f);
// Convenience versions of the above that first look up the field by name.
#define DEFINE_NAME_SETTER(slot, type) \
- INLINE void upb_handlers_set ## slot ## _n( \
+ UPB_INLINE bool upb_handlers_set ## slot ## _n( \
upb_handlers *h, const char *name, type val, \
void *d, upb_handlerfree *fr) { \
- upb_handlers_set ## slot(h, upb_msgdef_ntof( \
- upb_handlers_msgdef(h), name), val, d, fr); \
+ const upb_fielddef *f = upb_msgdef_ntof(upb_handlers_msgdef(h), name); \
+ if (!f) return false; \
+ return upb_handlers_set ## slot(h, f, val, d, fr); \
}
DEFINE_NAME_SETTER(int32, upb_int32_handler*);
DEFINE_NAME_SETTER(int64, upb_int64_handler*);
@@ -464,6 +598,17 @@ DEFINE_NAME_SETTER(startseq, upb_startfield_handler*);
DEFINE_NAME_SETTER(startsubmsg, upb_startfield_handler*);
DEFINE_NAME_SETTER(endsubmsg, upb_endfield_handler*);
DEFINE_NAME_SETTER(endseq, upb_endfield_handler*);
+
+#ifdef UPB_TWO_32BIT_TYPES
+DEFINE_NAME_SETTER(int32alt, upb_int32_handler2*);
+DEFINE_NAME_SETTER(uint32alt, upb_uint32_handler2*);
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+DEFINE_NAME_SETTER(int64alt, upb_int64_handler2*);
+DEFINE_NAME_SETTER(uint64alt, upb_uint64_handler2*);
+#endif
+
#undef DEFINE_NAME_SETTER
// Value writers for every in-memory type: write the data to a known offset
@@ -488,13 +633,13 @@ typedef struct upb_stdmsg_fval {
#ifdef __cplusplus
extern "C" {
#endif
-bool upb_stdmsg_setint32(void *c, void *d, int32_t val);
-bool upb_stdmsg_setint64(void *c, void *d, int64_t val);
-bool upb_stdmsg_setuint32(void *c, void *d, uint32_t val);
-bool upb_stdmsg_setuint64(void *c, void *d, uint64_t val);
-bool upb_stdmsg_setfloat(void *c, void *d, float val);
-bool upb_stdmsg_setdouble(void *c, void *d, double val);
-bool upb_stdmsg_setbool(void *c, void *d, bool val);
+bool upb_stdmsg_setint32(const upb_sinkframe *frame, int32_t val);
+bool upb_stdmsg_setint64(const upb_sinkframe *frame, int64_t val);
+bool upb_stdmsg_setuint32(const upb_sinkframe *frame, uint32_t val);
+bool upb_stdmsg_setuint64(const upb_sinkframe *frame, uint64_t val);
+bool upb_stdmsg_setfloat(const upb_sinkframe *frame, float val);
+bool upb_stdmsg_setdouble(const upb_sinkframe *frame, double val);
+bool upb_stdmsg_setbool(const upb_sinkframe *frame, bool val);
#ifdef __cplusplus
} // extern "C"
#endif
@@ -503,14 +648,18 @@ bool upb_stdmsg_setbool(void *c, void *d, bool val);
namespace upb {
+// This function should be specialized by types that have a FrameType.
+template<class T> inline const FrameType* GetFrameType() { return NULL; }
+
// C++ Wrappers
-inline Handlers* Handlers::New(const MessageDef* m, const void *owner) {
- return upb_handlers_new(m, owner);
+inline Handlers* Handlers::New(const MessageDef* m, const FrameType* ft,
+ const void *owner) {
+ return upb_handlers_new(m, ft, owner);
}
inline const Handlers* Handlers::NewFrozen(
- const MessageDef *m, const void *owner,
+ const MessageDef *m, const FrameType* ft, const void *owner,
upb_handlers_callback *callback, void *closure) {
- return upb_handlers_newfrozen(m, owner, callback, closure);
+ return upb_handlers_newfrozen(m, ft, owner, callback, closure);
}
inline bool Handlers::IsFrozen() const {
return upb_handlers_isfrozen(this);
@@ -530,6 +679,9 @@ inline void Handlers::CheckRef(const void *owner) const {
inline bool Handlers::Freeze(Handlers*const* handlers, int n, Status* s) {
return upb_handlers_freeze(handlers, n, s);
}
+inline const FrameType* Handlers::frame_type() const {
+ return upb_handlers_frametype(this);
+}
inline const MessageDef* Handlers::message_def() const {
return upb_handlers_msgdef(this);
}
@@ -551,13 +703,13 @@ inline bool Handlers::SetInt64Handler(
void *d, Handlers::Free *fr) {
return upb_handlers_setint64(this, f, handler, d, fr);
}
-inline bool Handlers::SetUint32Handler(
- const FieldDef *f, Handlers::Uint32Handler *handler,
+inline bool Handlers::SetUInt32Handler(
+ const FieldDef *f, Handlers::UInt32Handler *handler,
void *d, Handlers::Free *fr) {
return upb_handlers_setuint32(this, f, handler, d, fr);
}
-inline bool Handlers::SetUint64Handler(
- const FieldDef *f, Handlers::Uint64Handler *handler,
+inline bool Handlers::SetUInt64Handler(
+ const FieldDef *f, Handlers::UInt64Handler *handler,
void *d, Handlers::Free *fr) {
return upb_handlers_setuint64(this, f, handler, d, fr);
}
@@ -615,6 +767,76 @@ inline bool Handlers::SetSubHandlers(
const FieldDef* f, const Handlers* sub) {
return upb_handlers_setsubhandlers(this, f, sub);
}
+inline bool Handlers::SetInt32Handler(
+ const char* name, Handlers::Int32Handler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setint32_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetInt64Handler(
+ const char* name, Handlers::Int64Handler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setint64_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetUInt32Handler(
+ const char* name, Handlers::UInt32Handler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setuint32_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetUInt64Handler(
+ const char* name, Handlers::UInt64Handler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setuint64_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetFloatHandler(
+ const char* name, Handlers::FloatHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setfloat_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetDoubleHandler(
+ const char* name, Handlers::DoubleHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setdouble_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetBoolHandler(
+ const char* name, Handlers::BoolHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setbool_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetStartStringHandler(
+ const char* name, Handlers::StartStringHandler* handler,
+ void* d, Handlers::Free* fr) {
+ return upb_handlers_setstartstr_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetEndStringHandler(
+ const char* name, Handlers::EndFieldHandler* handler,
+ void* d, Handlers::Free* fr) {
+ return upb_handlers_setendstr_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetStringHandler(
+ const char* name, Handlers::StringHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setstring_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetStartSequenceHandler(
+ const char* name, Handlers::StartFieldHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setstartseq_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetStartSubMessageHandler(
+ const char* name, Handlers::StartFieldHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setstartsubmsg_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetEndSubMessageHandler(
+ const char* name, Handlers::EndFieldHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setendsubmsg_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetEndSequenceHandler(
+ const char* name, Handlers::EndFieldHandler *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setendseq_n(this, name, handler, d, fr);
+}
inline Handlers::StartMessageHandler *Handlers::GetStartMessageHandler() const {
return upb_handlers_getstartmsg(this);
}
@@ -625,10 +847,17 @@ inline const Handlers* Handlers::GetSubHandlers(
const FieldDef* f) const {
return upb_handlers_getsubhandlers(this, f);
}
+inline const Handlers* Handlers::GetSubHandlers(
+ Handlers::Selector sel) const {
+ return upb_handlers_getsubhandlers_sel(this, sel);
+}
inline bool Handlers::GetSelector(
const FieldDef* f, Handlers::Type type, Handlers::Selector* s) {
return upb_getselector(f, type, s);
}
+inline Handlers::Selector Handlers::GetEndSelector(Handlers::Selector start) {
+ return upb_getendselector(start);
+}
inline Handlers::GenericFunction* Handlers::GetHandler(
Handlers::Selector selector) {
return upb_handlers_gethandler(this, selector);
@@ -640,6 +869,52 @@ inline size_t Handlers::GetHandlerOffset(Handlers::Selector selector) {
return upb_gethandleroffset(selector);
}
+#ifdef UPB_TWO_32BIT_TYPES
+inline bool Handlers::SetInt32Handler(
+ const FieldDef *f, Handlers::Int32Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setint32alt(this, f, handler, d, fr);
+}
+inline bool Handlers::SetUInt32Handler(
+ const FieldDef *f, Handlers::UInt32Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setuint32alt(this, f, handler, d, fr);
+}
+inline bool Handlers::SetInt32Handler(
+ const char* name, Handlers::Int32Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setint32alt_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetUInt32Handler(
+ const char* name, Handlers::UInt32Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setuint32alt_n(this, name, handler, d, fr);
+}
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+inline bool Handlers::SetInt64Handler(
+ const FieldDef *f, Handlers::Int64Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setint64alt(this, f, handler, d, fr);
+}
+inline bool Handlers::SetUInt64Handler(
+ const FieldDef *f, Handlers::UInt64Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setuint64alt(this, f, handler, d, fr);
+}
+inline bool Handlers::SetInt64Handler(
+ const char* name, Handlers::Int64Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setint64alt_n(this, name, handler, d, fr);
+}
+inline bool Handlers::SetUInt64Handler(
+ const char* name, Handlers::UInt64Handler2 *handler,
+ void *d, Handlers::Free *fr) {
+ return upb_handlers_setuint64alt_n(this, name, handler, d, fr);
+}
+#endif
+
#define SET_VALUE_HANDLER(type, ctype) \
template<> \
inline bool Handlers::SetValueHandler<ctype>( \
@@ -647,14 +922,32 @@ inline size_t Handlers::GetHandlerOffset(Handlers::Selector selector) {
typename Handlers::Value<ctype>::Handler* handler, \
void* data, Handlers::Free* cleanup) { \
return upb_handlers_set ## type(this, f, handler, data, cleanup); \
+ } \
+ template<> \
+ inline bool Handlers::SetValueHandler<ctype>( \
+ const char* f, \
+ typename Handlers::Value<ctype>::Handler* handler, \
+ void* data, Handlers::Free* cleanup) { \
+ return upb_handlers_set ## type ## _n(this, f, handler, data, cleanup); \
}
SET_VALUE_HANDLER(double, double);
SET_VALUE_HANDLER(float, float);
-SET_VALUE_HANDLER(uint64, uint64_t);
-SET_VALUE_HANDLER(uint32, uint32_t);
-SET_VALUE_HANDLER(int64, int64_t);
-SET_VALUE_HANDLER(int32, int32_t);
+SET_VALUE_HANDLER(uint64, upb_uint64_t);
+SET_VALUE_HANDLER(uint32, upb_uint32_t);
+SET_VALUE_HANDLER(int64, upb_int64_t);
+SET_VALUE_HANDLER(int32, upb_int32_t);
SET_VALUE_HANDLER(bool, bool);
+
+#ifdef UPB_TWO_32BIT_TYPES
+SET_VALUE_HANDLER(int32alt, upb_int32alt_t);
+SET_VALUE_HANDLER(uint32alt, upb_uint32alt_t);
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+SET_VALUE_HANDLER(int64alt, upb_int64alt_t);
+SET_VALUE_HANDLER(uint64alt, upb_uint64alt_t);
+#endif
+
#undef SET_VALUE_HANDLER
template <class T> void DeletePointer(void *p) { delete static_cast<T*>(p); }
@@ -665,25 +958,55 @@ void SetStoreValueHandler(
// A handy templated function that will retrieve a value handler for a given
// C++ type.
-#define SET_STORE_VALUE_HANDLER(type, ctype) \
+#define SET_STORE_VALUE_HANDLER(type, ctype, handlerctype) \
template <> \
inline void SetStoreValueHandler<ctype>(const FieldDef* f, size_t offset, \
int32_t hasbit, Handlers* h) { \
- h->SetValueHandler<ctype>( \
+ h->SetValueHandler<handlerctype>( \
f, upb_stdmsg_set ## type, new upb_stdmsg_fval(offset, hasbit), \
&upb::DeletePointer<upb_stdmsg_fval>); \
}
-SET_STORE_VALUE_HANDLER(double, double);
-SET_STORE_VALUE_HANDLER(float, float);
-SET_STORE_VALUE_HANDLER(uint64, uint64_t);
-SET_STORE_VALUE_HANDLER(uint32, uint32_t);
-SET_STORE_VALUE_HANDLER(int64, int64_t);
-SET_STORE_VALUE_HANDLER(int32, int32_t);
-SET_STORE_VALUE_HANDLER(bool, bool);
-#undef GET_VALUE_HANDLER
+SET_STORE_VALUE_HANDLER(double, double, double);
+SET_STORE_VALUE_HANDLER(float, float, float);
+SET_STORE_VALUE_HANDLER(uint64, upb_uint64_t, uint64_t);
+SET_STORE_VALUE_HANDLER(uint32, upb_uint32_t, uint32_t);
+SET_STORE_VALUE_HANDLER(int64, upb_int64_t, int64_t);
+SET_STORE_VALUE_HANDLER(int32, upb_int32_t, int32_t);
+SET_STORE_VALUE_HANDLER(bool, bool, bool);
+
+#ifdef UPB_TWO_32BIT_TYPES
+SET_STORE_VALUE_HANDLER(int32, upb_int32alt_t, int32_t);
+SET_STORE_VALUE_HANDLER(uint32, upb_uint32alt_t, uint32_t);
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+SET_STORE_VALUE_HANDLER(int64, upb_int64alt_t, int64_t);
+SET_STORE_VALUE_HANDLER(uint64, upb_uint64alt_t, uint64_t);
+#endif
+
+#undef SET_STORE_VALUE_HANDLER
} // namespace upb
#endif
+// Implementation detail, put in the header file only so
+// upb_sinkframe_handlerdata() can be inlined.
+typedef struct {
+ upb_func *handler;
+
+ // Could put either or both of these in a separate table to save memory when
+ // they are sparse.
+ void *data;
+ upb_handlerfree *cleanup;
+
+ // TODO(haberman): this is wasteful; only the first "fieldhandler" of a
+ // submessage field needs this. To reduce memory footprint we should either:
+ // - put the subhandlers in a separate "fieldhandler", stored as part of
+ // a union with one of the above fields.
+ // - count selector offsets by individual pointers instead of by whole
+ // fieldhandlers.
+ const upb_handlers *subhandlers;
+} upb_fieldhandler;
+
#endif
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback