/* * upb - a minimalist implementation of protocol buffers. * * Copyright (c) 2011-2012 Google Inc. See LICENSE for details. * Author: Josh Haberman * * Inline definitions for handlers.h, which are particularly long and a bit * tricky. */ #ifndef UPB_HANDLERS_INL_H_ #define UPB_HANDLERS_INL_H_ #ifdef __cplusplus namespace upb { // Deleter: class for constructing a function that deletes a pointer type. template struct Deleter { static void Delete(void* p) { delete static_cast(p); } }; template Deleter MatchDeleter(T* data) { UPB_UNUSED(data); return Deleter(); } // Template magic for creating type-safe wrappers around the user's actual // function. These convert between the void*'s of the C API and the C++ // user's types. These also handle conversion between multiple types with // the same witdh; ie "long long" and "long" are both 64 bits on LP64. // EndMessageHandler template struct EndMessageHandlerWrapper2 { template static bool Wrapper(void *closure, const void *hd, Status* s) { UPB_UNUSED(hd); return F(static_cast(closure), s); } }; template struct EndMessageHandlerWrapper3 { template inline static bool Wrapper(void *closure, const void *hd, Status* s) { return F(static_cast(closure), static_cast(hd), s); } }; template inline EndMessageHandlerWrapper2 MatchWrapper(bool (*f)(C *, Status *)) { UPB_UNUSED(f); return EndMessageHandlerWrapper2(); } template inline EndMessageHandlerWrapper3 MatchWrapper(bool (*f)(C *, const D *, Status *)) { UPB_UNUSED(f); return EndMessageHandlerWrapper3(); } inline Handlers::EndMessageHandler MakeHandler(bool (*wrapper)(void *, const void *, Status *)) { return Handlers::EndMessageHandler::Make(wrapper, NULL, NULL); } template inline Handlers::EndMessageHandler BindHandler( bool (*wrapper)(void *, const void *, Status *), bool (*h)(C *, const D *, Status *), D *data) { UPB_UNUSED(h); // Only for making sure function matches "D". return Handlers::EndMessageHandler::Make(wrapper, data, MatchDeleter(data).Delete); } // ValueHandler template ::Type> struct ValueHandlerWrapper2 { template inline static bool Wrapper(void *closure, const void *hd, T2 val) { UPB_UNUSED(hd); return F(static_cast(closure), val); } }; template ::Type> struct ValueHandlerWrapper3 { template inline static bool Wrapper(void *closure, const void *hd, T2 val) { return F(static_cast(closure), static_cast(hd), val); } }; template inline ValueHandlerWrapper2 MatchWrapper(bool (*f)(C *, T)) { UPB_UNUSED(f); return ValueHandlerWrapper2(); } template inline ValueHandlerWrapper3 MatchWrapper(bool (*f)(C *, const D *, T)) { UPB_UNUSED(f); return ValueHandlerWrapper3(); } template inline typename Handlers::ValueHandler::H MakeHandler( bool (*wrapper)(void *, const void *, T)) { return Handlers::ValueHandler::H::Make(wrapper, NULL, NULL); } template inline typename Handlers::ValueHandler::H BindHandler( bool (*wrapper)(void *, const void *, T1), bool (*h)(C *, const D *, T2), D *data) { UPB_UNUSED(h); // Only for making sure function matches "D". return Handlers::ValueHandler::H::Make(wrapper, data, MatchDeleter(data).Delete); } // StartFieldHandler template struct StartFieldHandlerWrapper2 { template static void *Wrapper(void *closure, const void *hd) { UPB_UNUSED(hd); return F(static_cast(closure)); } }; template struct StartFieldHandlerWrapper3 { template inline static void *Wrapper(void *closure, const void *hd) { return F(static_cast(closure), static_cast(hd)); } }; template inline StartFieldHandlerWrapper2 MatchWrapper(R *(*f)(C *)) { UPB_UNUSED(f); return StartFieldHandlerWrapper2(); } template inline StartFieldHandlerWrapper3 MatchWrapper(R *(*f)(C *, const D *)) { UPB_UNUSED(f); return StartFieldHandlerWrapper3(); } inline Handlers::StartFieldHandler MakeHandler(void *(*wrapper)(void *, const void *)) { return Handlers::StartFieldHandler::Make(wrapper, NULL, NULL); } template inline Handlers::StartFieldHandler BindHandler( void *(*wrapper)(void *, const void *), R *(*h)(C *, const D *), D *data) { UPB_UNUSED(h); // Only for making sure function matches "D". return Handlers::StartFieldHandler::Make(wrapper, data, MatchDeleter(data).Delete); } // EndFieldHandler template struct EndFieldHandlerWrapper2 { template inline static bool Wrapper(void *closure, const void *hd) { UPB_UNUSED(hd); return F(static_cast(closure)); } }; template struct EndFieldHandlerWrapper3 { template inline static bool Wrapper(void *closure, const void *hd) { return F(static_cast(closure), static_cast(hd)); } }; template inline EndFieldHandlerWrapper2 MatchWrapper(bool (*f)(C *)) { UPB_UNUSED(f); return EndFieldHandlerWrapper2(); } template inline EndFieldHandlerWrapper3 MatchWrapper(bool (*f)(C *, const D *)) { UPB_UNUSED(f); return EndFieldHandlerWrapper3(); } inline Handlers::EndFieldHandler MakeHandler(bool (*wrapper)(void *, const void *)) { return Handlers::EndFieldHandler::Make(wrapper, NULL, NULL); } template inline Handlers::EndFieldHandler BindHandler( bool (*wrapper)(void *, const void *), bool (*h)(C *, const D *), D *data) { UPB_UNUSED(h); // Only for making sure function matches "D". return Handlers::EndFieldHandler::Make(wrapper, data, MatchDeleter(data).Delete); } // StartStringHandler template struct StartStringHandlerWrapper2 { template inline static void *Wrapper(void *closure, const void *hd, size_t hint) { UPB_UNUSED(hd); return F(static_cast(closure), hint); } }; template struct StartStringHandlerWrapper3 { template inline static void *Wrapper(void *closure, const void *hd, size_t hint) { return F(static_cast(closure), static_cast(hd), hint); } }; template inline StartStringHandlerWrapper2 MatchWrapper(R *(*f)(C *, size_t)) { UPB_UNUSED(f); return StartStringHandlerWrapper2(); } template inline StartStringHandlerWrapper3 MatchWrapper(R *(*f)(C *, const D *, size_t)) { UPB_UNUSED(f); return StartStringHandlerWrapper3(); } inline Handlers::StartStringHandler MakeHandler(void *(*wrapper)(void *, const void *, size_t)) { return Handlers::StartStringHandler::Make(wrapper, NULL, NULL); } template inline Handlers::StartStringHandler BindHandler( void *(*wrapper)(void *, const void *, size_t), R *(*h)(C *, const D *, size_t), D *data) { UPB_UNUSED(h); // Only for making sure function matches "D". return Handlers::StartStringHandler::Make(wrapper, data, MatchDeleter(data).Delete); } // StringHandler template struct StringHandlerWrapper2 { template inline static size_t Wrapper(void *closure, const void *hd, const char *buf, size_t len) { UPB_UNUSED(hd); return F(static_cast(closure), buf, len); } }; template struct StringHandlerWrapper3 { template inline static size_t Wrapper(void *closure, const void *hd, const char *buf, size_t len) { return F(static_cast(closure), static_cast(hd), buf, len); } }; template inline StringHandlerWrapper2 MatchWrapper(size_t (*f)(C *, const char *, size_t)) { UPB_UNUSED(f); return StringHandlerWrapper2(); } template inline StringHandlerWrapper3 MatchWrapper(size_t (*f)(C *, const D *, const char *, size_t)) { UPB_UNUSED(f); return StringHandlerWrapper3(); } inline Handlers::StringHandler MakeHandler( size_t (*wrapper)(void *, const void *, const char *, size_t)) { return Handlers::StringHandler::Make(wrapper, NULL, NULL); } template inline Handlers::StringHandler BindHandler( size_t (*wrapper)(void *, const void *, const char *, size_t), size_t (*h)(C *, const D *, const char *, size_t), D *data) { UPB_UNUSED(h); // Only for making sure function matches "D". return Handlers::StringHandler::Make(wrapper, data, MatchDeleter(data).Delete); } // 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 typename ValueHandler::Type>::H & \ handler) { \ handler.registered_ = true; \ return upb_handlers_set##ltype(this, f, handler.handler_, handler.data_, \ handler.cleanup_); \ } \ 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 // 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 bool Wrapper1(void *p1) { return F(static_cast(p1)); } template bool EndMessageWrapper(void *p1, upb::Status *s) { return F(static_cast(p1), s); } 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 FrameType *ft, const void *owner, upb_handlers_callback *callback, void *closure) { return upb_handlers_newfrozen(m, ft, owner, callback, closure); } inline bool Handlers::IsFrozen() const { return upb_handlers_isfrozen(this); } inline void Handlers::Ref(const void *owner) const { upb_handlers_ref(this, owner); } inline void Handlers::Unref(const void *owner) const { upb_handlers_unref(this, owner); } inline void Handlers::DonateRef(const void *from, const void *to) const { upb_handlers_donateref(this, from, to); } inline void Handlers::CheckRef(const void *owner) const { upb_handlers_checkref(this, owner); } inline const Status* Handlers::status() { return upb_handlers_status(this); } inline void Handlers::ClearError() { return upb_handlers_clearerr(this); } 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); } inline bool Handlers::SetStartMessageHandler( const Handlers::StartMessageHandler &handler) { handler.registered_ = true; return upb_handlers_setstartmsg(this, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetEndMessageHandler( const Handlers::EndMessageHandler &handler) { handler.registered_ = true; return upb_handlers_setendmsg(this, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetStartStringHandler(const FieldDef *f, const StartStringHandler &handler) { handler.registered_ = true; return upb_handlers_setstartstr(this, f, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetEndStringHandler(const FieldDef *f, const EndFieldHandler &handler) { handler.registered_ = true; return upb_handlers_setendstr(this, f, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetStringHandler(const FieldDef *f, const StringHandler& handler) { handler.registered_ = true; return upb_handlers_setstring(this, f, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetStartSequenceHandler( const FieldDef *f, const StartFieldHandler &handler) { handler.registered_ = true; return upb_handlers_setstartseq(this, f, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetStartSubMessageHandler( const FieldDef *f, const StartFieldHandler &handler) { handler.registered_ = true; return upb_handlers_setstartsubmsg(this, f, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetEndSubMessageHandler(const FieldDef *f, const EndFieldHandler &handler) { handler.registered_ = true; return upb_handlers_setendsubmsg(this, f, handler.handler_, handler.data_, handler.cleanup_); } inline bool Handlers::SetEndSequenceHandler(const FieldDef *f, const EndFieldHandler &handler) { handler.registered_ = true; return upb_handlers_setendseq(this, f, handler.handler_, handler.data_, handler.cleanup_); } 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); } } // namespace upb #endif // __cplusplus #endif // UPB_HANDLERS_INL_H_