From 01fb1d45ed26068bcb32a2dbf4ba8e56e65475e9 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sun, 28 Jun 2009 12:35:08 -0700 Subject: Stubbed out a few more methods in _msg and _context. --- upb_context.c | 12 +++++++++++- upb_context.h | 30 +++++++++++++----------------- upb_msg.h | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/upb_context.c b/upb_context.c index 642270a..e2c7aa9 100644 --- a/upb_context.c +++ b/upb_context.c @@ -30,6 +30,7 @@ bool upb_context_init(struct upb_context *c) void upb_context_free(struct upb_context *c) { upb_strtable_free(&c->symtab); + for(size_t i = 0; i < c->fd_len; i++) free(c->fd[i]); } struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, @@ -215,7 +216,7 @@ bool upb_context_addfd(struct upb_context *c, else continue; /* No resolving necessary. */ if(!ref.msg) goto error; - upb_msg_ref(m, f, &ref); + upb_msg_ref(m, f, ref); } } } @@ -227,5 +228,14 @@ bool upb_context_addfd(struct upb_context *c, return true; error: + /* TODO */ return false; } + +bool upb_context_parsefd(struct upb_context *c, struct upb_string *fd_str) { + google_protobuf_FileDescriptorProto *fd = upb_msg_parse(c->fd_msg, fd_str); + if(!fd) return false; + if(!upb_context_addfd(c, fd)) return false; + c->fd[c->fd_len++] = fd; /* Need to keep a ref since we own it. */ + return true; +} diff --git a/upb_context.h b/upb_context.h index 3b84889..4f9deaf 100644 --- a/upb_context.h +++ b/upb_context.h @@ -2,9 +2,10 @@ * upb - a minimalist implementation of protocol buffers. * * A context represents a namespace of proto definitions, sort of like an - * interpreter's symbol table. It is mostly empty when first constructed. - * Clients add definitions to the context by supplying unserialized or - * serialized descriptors (as defined in descriptor.proto). + * interpreter's symbol table. It is empty when first constructed, with the + * exception of built-in types (those defined in descriptor.proto). Clients + * add definitions to the context by supplying unserialized or serialized + * descriptors (as defined in descriptor.proto). * * Copyright (c) 2009 Joshua Haberman. See LICENSE for details. */ @@ -27,6 +28,12 @@ struct upb_symtab_entry { struct upb_context { struct upb_strtable symtab; + struct upb_msg *fd_msg; /* This is in symtab also, kept here for convenience. */ + + /* A list of the FileDescriptorProtos we own (from having parsed them + * ourselves) and must free on destruction. */ + size_t fd_size, fd_len; + google_protobuf_FileDescriptorProto **fd; }; /* Initializes and frees a upb_context, respectively. Newly initialized @@ -72,20 +79,9 @@ struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, bool upb_context_addfd(struct upb_context *c, google_protobuf_FileDescriptorProto *fd); -/* Adds the serialized FileDescriptorSet proto contained in fdss to the context, - * and adds symbol table entries for all the objects defined therein. onredef - * controls the behavior in the case the fds attempts to define a type that is - * already defined. - * - * Returns true if the protobuf in fds was parsed successfully and all - * references were successfully resolved. If false is returned, the context is - * unmodified. */ -bool upb_context_parsefds(struct upb_context *c, struct upb_string *fds, - int onredef); - -/* Like the previous, but for a single FileDescriptorProto instead of a set. */ -bool upb_context_parsefd(struct upb_context *c, struct upb_string *fds, - int onredef); +/* Like the previous, but takes a serialized FileDescriptorProto and parses + * it before adding to the context. */ +bool upb_context_parsefd(struct upb_context *c, struct upb_string *fd); #ifdef __cplusplus } /* extern "C" */ diff --git a/upb_msg.h b/upb_msg.h index 78fd2ce..70d4405 100644 --- a/upb_msg.h +++ b/upb_msg.h @@ -107,6 +107,13 @@ INLINE struct upb_msg_field *upb_get_msg_field( bool upb_msg_init(struct upb_msg *m, struct google_protobuf_DescriptorProto *d); void upb_msg_free(struct upb_msg *m); +/* Clients use this function on a previously initialized upb_msg to resolve the + * "ref" field in the upb_msg_field and upb_abbrev_msg_field. Since messages + * can refer to each other in mutually-recursive ways, this step must be + * separated from initialization. The function is necessary because there are + * multiple internal maps in which the ref appears. */ +void upb_msg_ref(struct upb_msg *m, struct upb_msg_field *f, union upb_symbol_ref ref); + /* While these are written to be as fast as possible, it will still be faster * to cache the results of this lookup if possible. These return NULL if no * such field is found. */ @@ -272,6 +279,13 @@ INLINE void upb_msg_clear(void *s, struct upb_msg *m) memset(s, 0, m->set_flags_bytes); } +/* Serialization/Deserialization. ********************************************/ + +/* Parses the string data in s according to the message description in m. + * Returns a newly allocated message which is now owned by the caller, or + * NULL if there was an error parsing the string. */ +void *upb_msg_parse(struct upb_msg *m, struct upb_string *s); + #ifdef __cplusplus } /* extern "C" */ #endif -- cgit v1.2.3