From 3bd691a4975b2267ff04611507e766a7f9f87e83 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 8 May 2015 16:56:29 -0700 Subject: Google-internal development. --- upb/descriptor/reader.c | 117 +++++++++++++++++++++++++++++++++++------------- upb/descriptor/reader.h | 78 ++++++-------------------------- 2 files changed, 100 insertions(+), 95 deletions(-) (limited to 'upb/descriptor') diff --git a/upb/descriptor/reader.c b/upb/descriptor/reader.c index 1baad81..0b289c0 100644 --- a/upb/descriptor/reader.c +++ b/upb/descriptor/reader.c @@ -20,6 +20,54 @@ #include "upb/sink.h" #include "upb/descriptor/descriptor.upb.h" +// upb_deflist is an internal-only dynamic array for storing a growing list of +// upb_defs. +typedef struct { + upb_def **defs; + size_t len; + size_t size; + bool owned; +} upb_deflist; + +// We keep a stack of all the messages scopes we are currently in, as well as +// the top-level file scope. This is necessary to correctly qualify the +// definitions that are contained inside. "name" tracks the name of the +// message or package (a bare name -- not qualified by any enclosing scopes). +typedef struct { + char *name; + // Index of the first def that is under this scope. For msgdefs, the + // msgdef itself is at start-1. + int start; +} upb_descreader_frame; + +// The maximum number of nested declarations that are allowed, ie. +// message Foo { +// message Bar { +// message Baz { +// } +// } +// } +// +// This is a resource limit that affects how big our runtime stack can grow. +// TODO: make this a runtime-settable property of the Reader instance. +#define UPB_MAX_MESSAGE_NESTING 64 + +struct upb_descreader { + upb_sink sink; + upb_deflist defs; + upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING]; + int stack_len; + + uint32_t number; + char *name; + bool saw_number; + bool saw_name; + + char *default_string; + + upb_fielddef *f; +}; + static char *upb_strndup(const char *buf, size_t n) { char *ret = malloc(n + 1); if (!ret) return NULL; @@ -99,36 +147,6 @@ static void upb_deflist_qualify(upb_deflist *l, char *str, int32_t start) { /* upb_descreader ************************************************************/ -void upb_descreader_init(upb_descreader *r, const upb_handlers *handlers, - upb_status *status) { - UPB_UNUSED(status); - upb_deflist_init(&r->defs); - upb_sink_reset(upb_descreader_input(r), handlers, r); - r->stack_len = 0; - r->name = NULL; - r->default_string = NULL; -} - -void upb_descreader_uninit(upb_descreader *r) { - free(r->name); - upb_deflist_uninit(&r->defs); - free(r->default_string); - while (r->stack_len > 0) { - upb_descreader_frame *f = &r->stack[--r->stack_len]; - free(f->name); - } -} - -upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n) { - *n = r->defs.len; - upb_deflist_donaterefs(&r->defs, owner); - return r->defs.defs; -} - -upb_sink *upb_descreader_input(upb_descreader *r) { - return &r->sink; -} - static upb_msgdef *upb_descreader_top(upb_descreader *r) { assert(r->stack_len > 1); int index = r->stack[r->stack_len-1].start - 1; @@ -568,6 +586,45 @@ static void reghandlers(const void *closure, upb_handlers *h) { #undef D +void descreader_cleanup(void *_r) { + upb_descreader *r = _r; + free(r->name); + upb_deflist_uninit(&r->defs); + free(r->default_string); + while (r->stack_len > 0) { + upb_descreader_frame *f = &r->stack[--r->stack_len]; + free(f->name); + } +} + + +/* Public API ****************************************************************/ + +upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) { + upb_descreader *r = upb_env_malloc(e, sizeof(upb_descreader)); + if (!r || !upb_env_addcleanup(e, descreader_cleanup, r)) { + return NULL; + } + + upb_deflist_init(&r->defs); + upb_sink_reset(upb_descreader_input(r), h, r); + r->stack_len = 0; + r->name = NULL; + r->default_string = NULL; + + return r; +} + +upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n) { + *n = r->defs.len; + upb_deflist_donaterefs(&r->defs, owner); + return r->defs.defs; +} + +upb_sink *upb_descreader_input(upb_descreader *r) { + return &r->sink; +} + const upb_handlers *upb_descreader_newhandlers(const void *owner) { const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s); const upb_handlers *h = upb_handlers_newfrozen( diff --git a/upb/descriptor/reader.h b/upb/descriptor/reader.h index 700fd65..bcd4b06 100644 --- a/upb/descriptor/reader.h +++ b/upb/descriptor/reader.h @@ -11,6 +11,7 @@ #ifndef UPB_DESCRIPTOR_H #define UPB_DESCRIPTOR_H +#include "upb/env.h" #include "upb/sink.h" #ifdef __cplusplus @@ -23,45 +24,11 @@ class Reader; UPB_DECLARE_TYPE(upb::descriptor::Reader, upb_descreader); -// Internal-only structs used by Reader. - -// upb_deflist is an internal-only dynamic array for storing a growing list of -// upb_defs. -typedef struct { - UPB_PRIVATE_FOR_CPP - upb_def **defs; - size_t len; - size_t size; - bool owned; -} upb_deflist; - -// We keep a stack of all the messages scopes we are currently in, as well as -// the top-level file scope. This is necessary to correctly qualify the -// definitions that are contained inside. "name" tracks the name of the -// message or package (a bare name -- not qualified by any enclosing scopes). -typedef struct { - UPB_PRIVATE_FOR_CPP - char *name; - // Index of the first def that is under this scope. For msgdefs, the - // msgdef itself is at start-1. - int start; -} upb_descreader_frame; - -// The maximum number of nested declarations that are allowed, ie. -// message Foo { -// message Bar { -// message Baz { -// } -// } -// } -// -// This is a resource limit that affects how big our runtime stack can grow. -// TODO: make this a runtime-settable property of the Reader instance. -#define UPB_MAX_MESSAGE_NESTING 64 +#ifdef __cplusplus // Class that receives descriptor data according to the descriptor.proto schema // and use it to build upb::Defs corresponding to that schema. -UPB_DEFINE_CLASS0(upb::descriptor::Reader, +class upb::descriptor::Reader { public: // These handlers must have come from NewHandlers() and must outlive the // Reader. @@ -71,11 +38,7 @@ UPB_DEFINE_CLASS0(upb::descriptor::Reader, // to build/memory-manage the handlers at runtime at all). Unfortunately this // is a bit tricky to implement for Handlers, but necessary to simplify this // interface. - Reader(const Handlers* handlers, Status* status); - ~Reader(); - - // Resets the reader's state and discards any defs it may have built. - void Reset(); + static Reader* Create(Environment* env, const Handlers* handlers); // The reader's input; this is where descriptor.proto data should be sent. Sink* input(); @@ -91,45 +54,30 @@ UPB_DEFINE_CLASS0(upb::descriptor::Reader, // Builds and returns handlers for the reader, owned by "owner." static Handlers* NewHandlers(const void* owner); -, -UPB_DEFINE_STRUCT0(upb_descreader, - upb_sink sink; - upb_deflist defs; - upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING]; - int stack_len; - uint32_t number; - char *name; - bool saw_number; - bool saw_name; + private: + UPB_DISALLOW_POD_OPS(Reader, upb::descriptor::Reader); +}; - char *default_string; - - upb_fielddef *f; -)); +#endif -UPB_BEGIN_EXTERN_C // { +UPB_BEGIN_EXTERN_C // C API. -void upb_descreader_init(upb_descreader *r, const upb_handlers *handlers, - upb_status *status); -void upb_descreader_uninit(upb_descreader *r); -void upb_descreader_reset(upb_descreader *r); +upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h); upb_sink *upb_descreader_input(upb_descreader *r); upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n); const upb_handlers *upb_descreader_newhandlers(const void *owner); -UPB_END_EXTERN_C // } +UPB_END_EXTERN_C #ifdef __cplusplus // C++ implementation details. ///////////////////////////////////////////////// namespace upb { namespace descriptor { -inline Reader::Reader(const Handlers *h, Status *s) { - upb_descreader_init(this, h, s); +inline Reader* Reader::Create(Environment* e, const Handlers *h) { + return upb_descreader_create(e, h); } -inline Reader::~Reader() { upb_descreader_uninit(this); } -inline void Reader::Reset() { upb_descreader_reset(this); } inline Sink* Reader::input() { return upb_descreader_input(this); } inline upb::Def** Reader::GetDefs(void* owner, int* n) { return upb_descreader_getdefs(this, owner, n); -- cgit v1.2.3