/* ** Inline definitions for handlers.h, which are particularly long and a bit ** tricky. */ #ifndef UPB_HANDLERS_INL_H_ #define UPB_HANDLERS_INL_H_ #include /* C inline methods. */ /* upb_bufhandle */ UPB_INLINE void upb_bufhandle_init(upb_bufhandle *h) { h->obj_ = NULL; h->objtype_ = NULL; h->buf_ = NULL; h->objofs_ = 0; } UPB_INLINE void upb_bufhandle_uninit(upb_bufhandle *h) { UPB_UNUSED(h); } UPB_INLINE void upb_bufhandle_setobj(upb_bufhandle *h, const void *obj, const void *type) { h->obj_ = obj; h->objtype_ = type; } UPB_INLINE void upb_bufhandle_setbuf(upb_bufhandle *h, const char *buf, size_t ofs) { h->buf_ = buf; h->objofs_ = ofs; } UPB_INLINE const void *upb_bufhandle_obj(const upb_bufhandle *h) { return h->obj_; } UPB_INLINE const void *upb_bufhandle_objtype(const upb_bufhandle *h) { return h->objtype_; } UPB_INLINE const char *upb_bufhandle_buf(const upb_bufhandle *h) { return h->buf_; } #ifdef __cplusplus /* Type detection and typedefs for integer types. * For platforms where there are multiple 32-bit or 64-bit types, we need to be * able to enumerate them so we can properly create overloads for all variants. * * If any platform existed where there were three integer types with the same * size, this would have to become more complicated. For example, short, int, * and long could all be 32-bits. Even more diabolically, short, int, long, * and long long could all be 64 bits and still be standard-compliant. * However, few platforms are this strange, and it's unlikely that upb will be * used on the strangest ones. */ /* Can't count on stdint.h limits like INT32_MAX, because in C++ these are * only defined when __STDC_LIMIT_MACROS are defined before the *first* include * of stdint.h. We can't guarantee that someone else didn't include these first * without defining __STDC_LIMIT_MACROS. */ #define UPB_INT32_MAX 0x7fffffffLL #define UPB_INT32_MIN (-UPB_INT32_MAX - 1) #define UPB_INT64_MAX 0x7fffffffffffffffLL #define UPB_INT64_MIN (-UPB_INT64_MAX - 1) #if INT_MAX == UPB_INT32_MAX && INT_MIN == UPB_INT32_MIN #define UPB_INT_IS_32BITS 1 #endif #if LONG_MAX == UPB_INT32_MAX && LONG_MIN == UPB_INT32_MIN #define UPB_LONG_IS_32BITS 1 #endif #if LONG_MAX == UPB_INT64_MAX && LONG_MIN == UPB_INT64_MIN #define UPB_LONG_IS_64BITS 1 #endif #if LLONG_MAX == UPB_INT64_MAX && LLONG_MIN == UPB_INT64_MIN #define UPB_LLONG_IS_64BITS 1 #endif /* We use macros instead of typedefs so we can undefine them later and avoid * leaking them outside this header file. */ #if UPB_INT_IS_32BITS #define UPB_INT32_T int #define UPB_UINT32_T unsigned int #if UPB_LONG_IS_32BITS #define UPB_TWO_32BIT_TYPES 1 #define UPB_INT32ALT_T long #define UPB_UINT32ALT_T unsigned long #endif /* UPB_LONG_IS_32BITS */ #elif UPB_LONG_IS_32BITS /* && !UPB_INT_IS_32BITS */ #define UPB_INT32_T long #define UPB_UINT32_T unsigned long #endif /* UPB_INT_IS_32BITS */ #if UPB_LONG_IS_64BITS #define UPB_INT64_T long #define UPB_UINT64_T unsigned long #if UPB_LLONG_IS_64BITS #define UPB_TWO_64BIT_TYPES 1 #define UPB_INT64ALT_T long long #define UPB_UINT64ALT_T unsigned long long #endif /* UPB_LLONG_IS_64BITS */ #elif UPB_LLONG_IS_64BITS /* && !UPB_LONG_IS_64BITS */ #define UPB_INT64_T long long #define UPB_UINT64_T unsigned long long #endif /* UPB_LONG_IS_64BITS */ #undef UPB_INT32_MAX #undef UPB_INT32_MIN #undef UPB_INT64_MAX #undef UPB_INT64_MIN #undef UPB_INT_IS_32BITS #undef UPB_LONG_IS_32BITS #undef UPB_LONG_IS_64BITS #undef UPB_LLONG_IS_64BITS namespace upb { typedef void CleanupFunc(void *ptr); /* Template to remove "const" from "const T*" and just return "T*". * * We define a nonsense default because otherwise it will fail to instantiate as * a function parameter type even in cases where we don't expect any caller to * actually match the overload. */ class CouldntRemoveConst {}; template struct remove_constptr { typedef CouldntRemoveConst type; }; template struct remove_constptr { typedef T *type; }; /* Template that we use below to remove a template specialization from * consideration if it matches a specific type. */ template struct disable_if_same { typedef void Type; }; template struct disable_if_same {}; template void DeletePointer(void *p) { delete static_cast(p); } template struct FirstUnlessVoidOrBool { typedef T1 value; }; template struct FirstUnlessVoidOrBool { typedef T2 value; }; template struct FirstUnlessVoidOrBool { typedef T2 value; }; template struct is_same { static bool value; }; template struct is_same { static bool value; }; template bool is_same::value = false; template bool is_same::value = true; /* FuncInfo *******************************************************************/ /* Info about the user's original, pre-wrapped function. */ template struct FuncInfo { /* The type of the closure that the function takes (its first param). */ typedef C Closure; /* The return type. */ typedef R Return; }; /* Func ***********************************************************************/ /* Func1, Func2, Func3: Template classes representing a function and its * signature. * * Since the function is a template parameter, calling the function can be * inlined at compile-time and does not require a function pointer at runtime. * These functions are not bound to a handler data so have no data or cleanup * handler. */ struct UnboundFunc { CleanupFunc *GetCleanup() { return NULL; } void *GetData() { return NULL; } }; template struct Func1 : public UnboundFunc { typedef R Return; typedef I FuncInfo; static R Call(P1 p1) { return F(p1); } }; template struct Func2 : public UnboundFunc { typedef R Return; typedef I FuncInfo; static R Call(P1 p1, P2 p2) { return F(p1, p2); } }; template struct Func3 : public UnboundFunc { typedef R Return; typedef I FuncInfo; static R Call(P1 p1, P2 p2, P3 p3) { return F(p1, p2, p3); } }; template struct Func4 : public UnboundFunc { typedef R Return; typedef I FuncInfo; static R Call(P1 p1, P2 p2, P3 p3, P4 p4) { return F(p1, p2, p3, p4); } }; template struct Func5 : public UnboundFunc { typedef R Return; typedef I FuncInfo; static R Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { return F(p1, p2, p3, p4, p5); } }; /* BoundFunc ******************************************************************/ /* BoundFunc2, BoundFunc3: Like Func2/Func3 except also contains a value that * shall be bound to the function's second parameter. * * Note that the second parameter is a const pointer, but our stored bound value * is non-const so we can free it when the handlers are destroyed. */ template struct BoundFunc { typedef typename remove_constptr::type MutableP2; explicit BoundFunc(MutableP2 data_) : data(data_) {} CleanupFunc *GetCleanup() { return &DeletePointer; } MutableP2 GetData() { return data; } MutableP2 data; }; template struct BoundFunc2 : public BoundFunc { typedef BoundFunc Base; typedef I FuncInfo; explicit BoundFunc2(typename Base::MutableP2 arg) : Base(arg) {} }; template struct BoundFunc3 : public BoundFunc { typedef BoundFunc Base; typedef I FuncInfo; explicit BoundFunc3(typename Base::MutableP2 arg) : Base(arg) {} }; template struct BoundFunc4 : public BoundFunc { typedef BoundFunc Base; typedef I FuncInfo; explicit BoundFunc4(typename Base::MutableP2 arg) : Base(arg) {} }; template struct BoundFunc5 : public BoundFunc { typedef BoundFunc Base; typedef I FuncInfo; explicit BoundFunc5(typename Base::MutableP2 arg) : Base(arg) {} }; /* FuncSig ********************************************************************/ /* FuncSig1, FuncSig2, FuncSig3: template classes reflecting a function * *signature*, but without a specific function attached. * * These classes contain member functions that can be invoked with a * specific function to return a Func/BoundFunc class. */ template struct FuncSig1 { template Func1 > GetFunc() { return Func1 >(); } }; template struct FuncSig2 { template Func2 > GetFunc() { return Func2 >(); } template BoundFunc2 > GetFunc( typename remove_constptr::type param2) { return BoundFunc2 >(param2); } }; template struct FuncSig3 { template Func3 > GetFunc() { return Func3 >(); } template BoundFunc3 > GetFunc( typename remove_constptr::type param2) { return BoundFunc3 >(param2); } }; template struct FuncSig4 { template Func4 > GetFunc() { return Func4 >(); } template BoundFunc4 > GetFunc( typename remove_constptr::type param2) { return BoundFunc4 >(param2); } }; template struct FuncSig5 { template Func5 > GetFunc() { return Func5 >(); } template BoundFunc5 > GetFunc( typename remove_constptr::type param2) { return BoundFunc5 >(param2); } }; /* Overloaded template function that can construct the appropriate FuncSig* * class given a function pointer by deducing the template parameters. */ template inline FuncSig1 MatchFunc(R (*f)(P1)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return FuncSig1(); } template inline FuncSig2 MatchFunc(R (*f)(P1, P2)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return FuncSig2(); } template inline FuncSig3 MatchFunc(R (*f)(P1, P2, P3)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return FuncSig3(); } template inline FuncSig4 MatchFunc(R (*f)(P1, P2, P3, P4)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return FuncSig4(); } template inline FuncSig5 MatchFunc(R (*f)(P1, P2, P3, P4, P5)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return FuncSig5(); } /* MethodSig ******************************************************************/ /* CallMethod*: a function template that calls a given method. */ template R CallMethod0(C *obj) { return ((*obj).*F)(); } template R CallMethod1(C *obj, P1 arg1) { return ((*obj).*F)(arg1); } template R CallMethod2(C *obj, P1 arg1, P2 arg2) { return ((*obj).*F)(arg1, arg2); } template R CallMethod3(C *obj, P1 arg1, P2 arg2, P3 arg3) { return ((*obj).*F)(arg1, arg2, arg3); } template R CallMethod4(C *obj, P1 arg1, P2 arg2, P3 arg3, P4 arg4) { return ((*obj).*F)(arg1, arg2, arg3, arg4); } /* MethodSig: like FuncSig, but for member functions. * * GetFunc() returns a normal FuncN object, so after calling GetFunc() no * more logic is required to special-case methods. */ template struct MethodSig0 { template Func1, FuncInfo > GetFunc() { return Func1, FuncInfo >(); } }; template struct MethodSig1 { template Func2, FuncInfo > GetFunc() { return Func2, FuncInfo >(); } template BoundFunc2, FuncInfo > GetFunc( typename remove_constptr::type param1) { return BoundFunc2, FuncInfo >( param1); } }; template struct MethodSig2 { template Func3, FuncInfo > GetFunc() { return Func3, FuncInfo >(); } template BoundFunc3, FuncInfo > GetFunc(typename remove_constptr::type param1) { return BoundFunc3, FuncInfo >(param1); } }; template struct MethodSig3 { template Func4, FuncInfo > GetFunc() { return Func4, FuncInfo >(); } template BoundFunc4, FuncInfo > GetFunc(typename remove_constptr::type param1) { return BoundFunc4, FuncInfo >(param1); } }; template struct MethodSig4 { template Func5, FuncInfo > GetFunc() { return Func5, FuncInfo >(); } template BoundFunc5, FuncInfo > GetFunc(typename remove_constptr::type param1) { return BoundFunc5, FuncInfo >( param1); } }; template inline MethodSig0 MatchFunc(R (C::*f)()) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return MethodSig0(); } template inline MethodSig1 MatchFunc(R (C::*f)(P1)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return MethodSig1(); } template inline MethodSig2 MatchFunc(R (C::*f)(P1, P2)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return MethodSig2(); } template inline MethodSig3 MatchFunc(R (C::*f)(P1, P2, P3)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return MethodSig3(); } template inline MethodSig4 MatchFunc(R (C::*f)(P1, P2, P3, P4)) { UPB_UNUSED(f); /* Only used for template parameter deduction. */ return MethodSig4(); } /* MaybeWrapReturn ************************************************************/ /* Template class that attempts to wrap the return value of the function so it * matches the expected type. There are two main adjustments it may make: * * 1. If the function returns void, make it return the expected type and with * a value that always indicates success. * 2. If the function returns bool, make it return the expected type with a * value that indicates success or failure. * * The "expected type" for return is: * 1. void* for start handlers. If the closure parameter has a different type * we will cast it to void* for the return in the success case. * 2. size_t for string buffer handlers. * 3. bool for everything else. */ /* Template parameters are FuncN type and desired return type. */ template struct MaybeWrapReturn; /* If the return type matches, return the given function unwrapped. */ template struct MaybeWrapReturn { typedef F Func; }; /* Function wrapper that munges the return value from void to (bool)true. */ template bool ReturnTrue2(P1 p1, P2 p2) { F(p1, p2); return true; } template bool ReturnTrue3(P1 p1, P2 p2, P3 p3) { F(p1, p2, p3); return true; } /* Function wrapper that munges the return value from void to (void*)arg1 */ template void *ReturnClosure2(P1 p1, P2 p2) { F(p1, p2); return p1; } template void *ReturnClosure3(P1 p1, P2 p2, P3 p3) { F(p1, p2, p3); return p1; } /* Function wrapper that munges the return value from R to void*. */ template void *CastReturnToVoidPtr2(P1 p1, P2 p2) { return F(p1, p2); } template void *CastReturnToVoidPtr3(P1 p1, P2 p2, P3 p3) { return F(p1, p2, p3); } /* Function wrapper that munges the return value from bool to void*. */ template void *ReturnClosureOrBreak2(P1 p1, P2 p2) { return F(p1, p2) ? p1 : UPB_BREAK; } template void *ReturnClosureOrBreak3(P1 p1, P2 p2, P3 p3) { return F(p1, p2, p3) ? p1 : UPB_BREAK; } /* For the string callback, which takes five params, returns the size param. */ template size_t ReturnStringLen(P1 p1, P2 p2, const char *p3, size_t p4, const BufferHandle *p5) { F(p1, p2, p3, p4, p5); return p4; } /* For the string callback, which takes five params, returns the size param or * zero. */ template size_t ReturnNOr0(P1 p1, P2 p2, const char *p3, size_t p4, const BufferHandle *p5) { return F(p1, p2, p3, p4, p5) ? p4 : 0; } /* If we have a function returning void but want a function returning bool, wrap * it in a function that returns true. */ template struct MaybeWrapReturn, bool> { typedef Func2, I> Func; }; template struct MaybeWrapReturn, bool> { typedef Func3, I> Func; }; /* If our function returns void but we want one returning void*, wrap it in a * function that returns the first argument. */ template struct MaybeWrapReturn, void *> { typedef Func2, I> Func; }; template struct MaybeWrapReturn, void *> { typedef Func3, I> Func; }; /* If our function returns R* but we want one returning void*, wrap it in a * function that casts to void*. */ template struct MaybeWrapReturn, void *, typename disable_if_same::Type> { typedef Func2, I> Func; }; template struct MaybeWrapReturn, void *, typename disable_if_same::Type> { typedef Func3, I> Func; }; /* If our function returns bool but we want one returning void*, wrap it in a * function that returns either the first param or UPB_BREAK. */ template struct MaybeWrapReturn, void *> { typedef Func2, I> Func; }; template struct MaybeWrapReturn, void *> { typedef Func3, I> Func; }; /* If our function returns void but we want one returning size_t, wrap it in a * function that returns the size argument. */ template struct MaybeWrapReturn< Func5, size_t> { typedef Func5, I> Func; }; /* If our function returns bool but we want one returning size_t, wrap it in a * function that returns either 0 or the buf size. */ template struct MaybeWrapReturn< Func5, size_t> { typedef Func5, I> Func; }; /* ConvertParams **************************************************************/ /* Template class that converts the function parameters if necessary, and * ignores the HandlerData parameter if appropriate. * * Template parameter is the are FuncN function type. */ template struct ConvertParams; /* Function that discards the handler data parameter. */ template R IgnoreHandlerData2(void *p1, const void *hd) { UPB_UNUSED(hd); return F(static_cast(p1)); } template R IgnoreHandlerData3(void *p1, const void *hd, P2Wrapper p2) { UPB_UNUSED(hd); return F(static_cast(p1), p2); } template R IgnoreHandlerData4(void *p1, const void *hd, P2 p2, P3 p3) { UPB_UNUSED(hd); return F(static_cast(p1), p2, p3); } template R IgnoreHandlerData5(void *p1, const void *hd, P2 p2, P3 p3, P4 p4) { UPB_UNUSED(hd); return F(static_cast(p1), p2, p3, p4); } template R IgnoreHandlerDataIgnoreHandle(void *p1, const void *hd, const char *p2, size_t p3, const BufferHandle *handle) { UPB_UNUSED(hd); UPB_UNUSED(handle); return F(static_cast(p1), p2, p3); } /* Function that casts the handler data parameter. */ template R CastHandlerData2(void *c, const void *hd) { return F(static_cast(c), static_cast(hd)); } template R CastHandlerData3(void *c, const void *hd, P3Wrapper p3) { return F(static_cast(c), static_cast(hd), p3); } template R CastHandlerData5(void *c, const void *hd, P3 p3, P4 p4, P5 p5) { return F(static_cast(c), static_cast(hd), p3, p4, p5); } template R CastHandlerDataIgnoreHandle(void *c, const void *hd, const char *p3, size_t p4, const BufferHandle *handle) { UPB_UNUSED(handle); return F(static_cast(c), static_cast(hd), p3, p4); } /* For unbound functions, ignore the handler data. */ template struct ConvertParams, T> { typedef Func2, I> Func; }; template struct ConvertParams, R2 (*)(P1_2, P2_2, P3_2)> { typedef Func3, I> Func; }; /* For StringBuffer only; this ignores both the handler data and the * BufferHandle. */ template struct ConvertParams, T> { typedef Func5, I> Func; }; template struct ConvertParams, T> { typedef Func5, I> Func; }; /* For bound functions, cast the handler data. */ template struct ConvertParams, T> { typedef Func2, I> Func; }; template struct ConvertParams, R2 (*)(P1_2, P2_2, P3_2)> { typedef Func3, I> Func; }; /* For StringBuffer only; this ignores the BufferHandle. */ template struct ConvertParams, T> { typedef Func5, I> Func; }; template struct ConvertParams, T> { typedef Func5, I> Func; }; /* utype/ltype are upper/lower-case, ctype is canonical C type, vtype is * variant C type. */ #define TYPE_METHODS(utype, ltype, ctype, vtype) \ template <> struct CanonicalType { \ typedef ctype Type; \ }; \ template <> \ inline bool Handlers::SetValueHandler( \ const FieldDef *f, \ const Handlers::utype ## Handler& handler) { \ UPB_ASSERT(!handler.registered_); \ handler.AddCleanup(this); \ handler.registered_ = true; \ return upb_handlers_set##ltype(this, f, handler.handler_, &handler.attr_); \ } \ TYPE_METHODS(Double, double, double, double) TYPE_METHODS(Float, float, float, float) TYPE_METHODS(UInt64, uint64, uint64_t, UPB_UINT64_T) TYPE_METHODS(UInt32, uint32, uint32_t, UPB_UINT32_T) TYPE_METHODS(Int64, int64, int64_t, UPB_INT64_T) TYPE_METHODS(Int32, int32, int32_t, UPB_INT32_T) TYPE_METHODS(Bool, bool, bool, bool) #ifdef UPB_TWO_32BIT_TYPES TYPE_METHODS(Int32, int32, int32_t, UPB_INT32ALT_T) TYPE_METHODS(UInt32, uint32, uint32_t, UPB_UINT32ALT_T) #endif #ifdef UPB_TWO_64BIT_TYPES TYPE_METHODS(Int64, int64, int64_t, UPB_INT64ALT_T) TYPE_METHODS(UInt64, uint64, uint64_t, UPB_UINT64ALT_T) #endif #undef TYPE_METHODS template <> struct CanonicalType { typedef Status* Type; }; /* Type methods that are only one-per-canonical-type and not * one-per-cvariant. */ #define TYPE_METHODS(utype, ctype) \ inline bool Handlers::Set##utype##Handler(const FieldDef *f, \ const utype##Handler &h) { \ return SetValueHandler(f, h); \ } \ TYPE_METHODS(Double, double) TYPE_METHODS(Float, float) TYPE_METHODS(UInt64, uint64_t) TYPE_METHODS(UInt32, uint32_t) TYPE_METHODS(Int64, int64_t) TYPE_METHODS(Int32, int32_t) TYPE_METHODS(Bool, bool) #undef TYPE_METHODS template struct ReturnOf; template struct ReturnOf { typedef R Return; }; template struct ReturnOf { typedef R Return; }; template struct ReturnOf { typedef R Return; }; template struct ReturnOf { typedef R Return; }; template const void *UniquePtrForType() { static const char ch = 0; return &ch; } template template inline Handler::Handler(F func) : registered_(false), cleanup_data_(func.GetData()), cleanup_func_(func.GetCleanup()) { upb_handlerattr_sethandlerdata(&attr_, func.GetData()); typedef typename ReturnOf::Return Return; typedef typename ConvertParams::Func ConvertedParamsFunc; typedef typename MaybeWrapReturn::Func ReturnWrappedFunc; handler_ = ReturnWrappedFunc().Call; /* Set attributes based on what templates can statically tell us about the * user's function. */ /* If the original function returns void, then we know that we wrapped it to * always return ok. */ bool always_ok = is_same::value; attr_.SetAlwaysOk(always_ok); /* Closure parameter and return type. */ attr_.SetClosureType(UniquePtrForType()); /* We use the closure type (from the first parameter) if the return type is * void or bool, since these are the two cases we wrap to return the closure's * type anyway. * * This is all nonsense for non START* handlers, but it doesn't matter because * in that case the value will be ignored. */ typedef typename FirstUnlessVoidOrBool::value EffectiveReturn; attr_.SetReturnClosureType(UniquePtrForType()); } template inline Handler::~Handler() { UPB_ASSERT(registered_); } inline HandlerAttributes::HandlerAttributes() { upb_handlerattr_init(this); } inline HandlerAttributes::~HandlerAttributes() { upb_handlerattr_uninit(this); } inline bool HandlerAttributes::SetHandlerData(const void *hd) { return upb_handlerattr_sethandlerdata(this, hd); } inline const void* HandlerAttributes::handler_data() const { return upb_handlerattr_handlerdata(this); } inline bool HandlerAttributes::SetClosureType(const void *type) { return upb_handlerattr_setclosuretype(this, type); } inline const void* HandlerAttributes::closure_type() const { return upb_handlerattr_closuretype(this); } inline bool HandlerAttributes::SetReturnClosureType(const void *type) { return upb_handlerattr_setreturnclosuretype(this, type); } inline const void* HandlerAttributes::return_closure_type() const { return upb_handlerattr_returnclosuretype(this); } inline bool HandlerAttributes::SetAlwaysOk(bool always_ok) { return upb_handlerattr_setalwaysok(this, always_ok); } inline bool HandlerAttributes::always_ok() const { return upb_handlerattr_alwaysok(this); } inline BufferHandle::BufferHandle() { upb_bufhandle_init(this); } inline BufferHandle::~BufferHandle() { upb_bufhandle_uninit(this); } inline const char* BufferHandle::buffer() const { return upb_bufhandle_buf(this); } inline size_t BufferHandle::object_offset() const { return upb_bufhandle_objofs(this); } inline void BufferHandle::SetBuffer(const char* buf, size_t ofs) { upb_bufhandle_setbuf(this, buf, ofs); } template void BufferHandle::SetAttachedObject(const T* obj) { upb_bufhandle_setobj(this, obj, UniquePtrForType()); } template const T* BufferHandle::GetAttachedObject() const { return upb_bufhandle_objtype(this) == UniquePtrForType() ? static_cast(upb_bufhandle_obj(this)) : NULL; } inline reffed_ptr Handlers::New(const MessageDef *m) { upb_handlers *h = upb_handlers_new(m, &h); return reffed_ptr(h, &h); } inline reffed_ptr Handlers::NewFrozen( const MessageDef *m, upb_handlers_callback *callback, const void *closure) { const upb_handlers *h = upb_handlers_newfrozen(m, &h, callback, closure); return reffed_ptr(h, &h); } inline const Status* Handlers::status() { return upb_handlers_status(this); } inline void Handlers::ClearError() { return upb_handlers_clearerr(this); } inline bool Handlers::Freeze(Status *s) { upb::Handlers* h = this; return upb_handlers_freeze(&h, 1, s); } inline bool Handlers::Freeze(Handlers *const *handlers, int n, Status *s) { return upb_handlers_freeze(handlers, n, s); } inline bool Handlers::Freeze(const std::vector& h, Status* status) { return upb_handlers_freeze((Handlers* const*)&h[0], h.size(), status); } inline const MessageDef *Handlers::message_def() const { return upb_handlers_msgdef(this); } inline bool Handlers::AddCleanup(void *p, upb_handlerfree *func) { return upb_handlers_addcleanup(this, p, func); } inline bool Handlers::SetStartMessageHandler( const Handlers::StartMessageHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setstartmsg(this, handler.handler_, &handler.attr_); } inline bool Handlers::SetEndMessageHandler( const Handlers::EndMessageHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setendmsg(this, handler.handler_, &handler.attr_); } inline bool Handlers::SetStartStringHandler(const FieldDef *f, const StartStringHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setstartstr(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetEndStringHandler(const FieldDef *f, const EndFieldHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setendstr(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetStringHandler(const FieldDef *f, const StringHandler& handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setstring(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetStartSequenceHandler( const FieldDef *f, const StartFieldHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setstartseq(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetStartSubMessageHandler( const FieldDef *f, const StartFieldHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setstartsubmsg(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetEndSubMessageHandler(const FieldDef *f, const EndFieldHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setendsubmsg(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetEndSequenceHandler(const FieldDef *f, const EndFieldHandler &handler) { UPB_ASSERT(!handler.registered_); handler.registered_ = true; handler.AddCleanup(this); return upb_handlers_setendseq(this, f, handler.handler_, &handler.attr_); } inline bool Handlers::SetSubHandlers(const FieldDef *f, const Handlers *sub) { return upb_handlers_setsubhandlers(this, f, sub); } 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_handlers_getselector(f, type, s); } inline Handlers::Selector Handlers::GetEndSelector(Handlers::Selector start) { return upb_handlers_getendselector(start); } inline Handlers::GenericFunction *Handlers::GetHandler( Handlers::Selector selector) { return upb_handlers_gethandler(this, selector); } inline const void *Handlers::GetHandlerData(Handlers::Selector selector) { return upb_handlers_gethandlerdata(this, selector); } inline BytesHandler::BytesHandler() { upb_byteshandler_init(this); } inline BytesHandler::~BytesHandler() {} } /* namespace upb */ #endif /* __cplusplus */ #undef UPB_TWO_32BIT_TYPES #undef UPB_TWO_64BIT_TYPES #undef UPB_INT32_T #undef UPB_UINT32_T #undef UPB_INT32ALT_T #undef UPB_UINT32ALT_T #undef UPB_INT64_T #undef UPB_UINT64_T #undef UPB_INT64ALT_T #undef UPB_UINT64ALT_T #endif /* UPB_HANDLERS_INL_H_ */