From f226554fa5b64c2a152f39e52fd4a56acc06f527 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sun, 4 Sep 2011 22:40:42 -0700 Subject: [PATCH] Fleshed out C++ def wrappers some. --- bindings/cpp/upb/def.hpp | 105 ++++++++++++++++++++++++++++++++++++++- bindings/cpp/upb/upb.hpp | 6 +++ upb/def.h | 34 ++++++------- 3 files changed, 127 insertions(+), 18 deletions(-) diff --git a/bindings/cpp/upb/def.hpp b/bindings/cpp/upb/def.hpp index d64625cecb..edec56a5ed 100644 --- a/bindings/cpp/upb/def.hpp +++ b/bindings/cpp/upb/def.hpp @@ -11,21 +11,124 @@ #ifndef UPB_DEF_HPP #define UPB_DEF_HPP +#include +#include +#include #include "upb/def.h" +#include "upb/upb.hpp" namespace upb { +class MessageDef; + +class FieldDef : public upb_fielddef { + public: + static FieldDef* Cast(upb_fielddef *f) { return (FieldDef*)f; } + static const FieldDef* Cast(const upb_fielddef *f) { return (FieldDef*)f; } + + static FieldDef* New() { return Cast(upb_fielddef_new()); } + FieldDef* Dup() { return Cast(upb_fielddef_dup(this)); } + + // Read accessors -- may be called at any time. + uint8_t type() const { return upb_fielddef_type(this); } + uint8_t label() const { return upb_fielddef_label(this); } + int32_t number() const { return upb_fielddef_number(this); } + std::string name() const { return std::string(upb_fielddef_name(this)); } + Value default_() const { return upb_fielddef_default(this); } + Value bound_value() const { return upb_fielddef_fval(this); } + + MessageDef* message() { return (MessageDef*)upb_fielddef_msgdef(this); } + const MessageDef* message() const { return (MessageDef*)upb_fielddef_msgdef(this); } + //Def* subdef() { return upb_fielddef_subdef(this); } + //const Def* subdef() { return upb_fielddef_subdef(this); } + + // Returns true if this FieldDef is finalized + bool IsFinalized() const { return upb_fielddef_finalized(this); } + struct _upb_accessor_vtbl *accessor() const { + return upb_fielddef_accessor(this); + } + std::string type_name() const { + return std::string(upb_fielddef_typename(this)); + } + + // Write accessors -- may not be called once the FieldDef is finalized. + + private: + FieldDef(); + ~FieldDef(); +}; + class MessageDef : public upb_msgdef { public: // Converting from C types to C++ wrapper types. static MessageDef* Cast(upb_msgdef *md) { return (MessageDef*)md; } static const MessageDef* Cast(const upb_msgdef *md) { - return (const MessageDef*)md; + return (MessageDef*)md; } + static MessageDef* New() { return Cast(upb_msgdef_new()); } + MessageDef* Dup() { return Cast(upb_msgdef_dup(this)); } + void Ref() const { upb_msgdef_ref(this); } void Unref() const { upb_msgdef_unref(this); } + // Read accessors -- may be called at any time. + + // The total size of in-memory messages created with this MessageDef. + uint16_t instance_size() const { return upb_msgdef_size(this); } + + // The number of "hasbit" bytes in a message instance. + uint8_t hasbit_bytes() const { return upb_msgdef_hasbit_bytes(this); } + + uint32_t extension_start() const { return upb_msgdef_extstart(this); } + uint32_t extension_end() const { return upb_msgdef_extend(this); } + + // Write accessors. May only be called before the msgdef is in a symtab. + + void set_instance_size(uint16_t size) { upb_msgdef_setsize(this, size); } + void set_hasbit_bytes(uint16_t size) { upb_msgdef_setsize(this, size); } + bool SetExtensionRange(uint32_t start, uint32_t end) { + return upb_msgdef_setextrange(this, start, end); + } + + // Adds a set of fields (upb_fielddef objects) to a msgdef. Caller retains + // its ref on the fielddef. May only be done before the msgdef is in a + // symtab (requires upb_def_ismutable(m) for the msgdef). The fielddef's + // name and number must be set, and the message may not already contain any + // field with this name or number, and this fielddef may not be part of + // another message, otherwise false is returned and no action is performed. + bool AddFields(FieldDef** f, int n) { + return upb_msgdef_addfields(this, (upb_fielddef**)f, n); + } + bool AddFields(const std::vector& fields) { + FieldDef *arr[fields.size()]; + std::copy(fields.begin(), fields.end(), arr); + return AddFields(arr, fields.size()); + } + + // Lookup fields by name or number, returning NULL if no such field exists. + FieldDef* FindFieldByName(const char *name) { + return FieldDef::Cast(upb_msgdef_ntof(this, name)); + } + FieldDef* FindFieldByName(const std::string& name) { + return FieldDef::Cast(upb_msgdef_ntof(this, name.c_str())); + } + FieldDef* FindFieldByNumber(uint32_t num) { + return FieldDef::Cast(upb_msgdef_itof(this, num)); + } + + const FieldDef* FindFieldByName(const char *name) const { + return FindFieldByName(name); + } + const FieldDef* FindFieldByName(const std::string& name) const { + return FindFieldByName(name); + } + const FieldDef* FindFieldByNumber(uint32_t num) const { + return FindFieldByNumber(num); + } + + // TODO: iteration over fields. + private: MessageDef(); ~MessageDef(); diff --git a/bindings/cpp/upb/upb.hpp b/bindings/cpp/upb/upb.hpp index 460fb43398..4fb337dd9c 100644 --- a/bindings/cpp/upb/upb.hpp +++ b/bindings/cpp/upb/upb.hpp @@ -20,6 +20,12 @@ class Status : public upb_status { const char *GetString() const { return upb_status_getstr(this); } }; +class Value : public upb_value { + public: + Value(const upb_value& val) { *this = val; } + Value() {} +}; + INLINE std::ostream& operator<<(std::ostream& out, const Status& status) { out << status.GetString(); return out; diff --git a/upb/def.h b/upb/def.h index 361753c45a..f6af798ff6 100644 --- a/upb/def.h +++ b/upb/def.h @@ -129,20 +129,20 @@ upb_fielddef *upb_fielddef_dup(upb_fielddef *f); bool upb_fielddef_ismutable(const upb_fielddef *f); // Read accessors. May be called any time. -INLINE uint8_t upb_fielddef_type(upb_fielddef *f) { return f->type; } -INLINE uint8_t upb_fielddef_label(upb_fielddef *f) { return f->label; } -INLINE int32_t upb_fielddef_number(upb_fielddef *f) { return f->number; } -INLINE char *upb_fielddef_name(upb_fielddef *f) { return f->name; } -INLINE upb_value upb_fielddef_default(upb_fielddef *f) { return f->defaultval; } -INLINE upb_value upb_fielddef_fval(upb_fielddef *f) { return f->fval; } -INLINE bool upb_fielddef_finalized(upb_fielddef *f) { return f->finalized; } -INLINE struct _upb_msgdef *upb_fielddef_msgdef(upb_fielddef *f) { +INLINE uint8_t upb_fielddef_type(const upb_fielddef *f) { return f->type; } +INLINE uint8_t upb_fielddef_label(const upb_fielddef *f) { return f->label; } +INLINE int32_t upb_fielddef_number(const upb_fielddef *f) { return f->number; } +INLINE char *upb_fielddef_name(const upb_fielddef *f) { return f->name; } +INLINE upb_value upb_fielddef_default(const upb_fielddef *f) { return f->defaultval; } +INLINE upb_value upb_fielddef_fval(const upb_fielddef *f) { return f->fval; } +INLINE bool upb_fielddef_finalized(const upb_fielddef *f) { return f->finalized; } +INLINE struct _upb_msgdef *upb_fielddef_msgdef(const upb_fielddef *f) { return f->msgdef; } -INLINE struct _upb_accessor_vtbl *upb_fielddef_accessor(upb_fielddef *f) { +INLINE struct _upb_accessor_vtbl *upb_fielddef_accessor(const upb_fielddef *f) { return f->accessor; } -INLINE const char *upb_fielddef_typename(upb_fielddef *f) { +INLINE const char *upb_fielddef_typename(const upb_fielddef *f) { return f->def ? f->def->fqname : NULL; } @@ -225,7 +225,7 @@ INLINE void upb_msgdef_ref(const upb_msgdef *md) { upb_def_ref(UPB_UPCAST(md)); upb_msgdef *upb_msgdef_dup(const upb_msgdef *m); // Read accessors. May be called at any time. -INLINE uint16_t upb_msgdef_size(const upb_msgdef *m) { return m->size; } +INLINE size_t upb_msgdef_size(const upb_msgdef *m) { return m->size; } INLINE uint8_t upb_msgdef_hasbit_bytes(const upb_msgdef *m) { return m->hasbit_bytes; } @@ -237,12 +237,12 @@ void upb_msgdef_setsize(upb_msgdef *m, uint16_t size); void upb_msgdef_sethasbit_bytes(upb_msgdef *m, uint16_t bytes); bool upb_msgdef_setextrange(upb_msgdef *m, uint32_t start, uint32_t end); -// Adds a fielddef to a msgdef. Caller retains its ref on the fielddef. May -// only be done before the msgdef is in a symtab (requires upb_def_ismutable(m) -// for the msgdef). The fielddef's name and number must be set, and the -// message may not already contain any field with this name or number, and this -// fielddef may not be part of another message, otherwise false is returned and -// no action is performed. +// Adds a set of fields (upb_fielddef objects) to a msgdef. Caller retains its +// ref on the fielddef. May only be done before the msgdef is in a symtab +// (requires upb_def_ismutable(m) for the msgdef). The fielddef's name and +// number must be set, and the message may not already contain any field with +// this name or number, and this fielddef may not be part of another message, +// otherwise false is returned and no action is performed. bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef **f, int n); INLINE bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f) { return upb_msgdef_addfields(m, &f, 1);