From 62be5969a14b36e4f3ca336ec57c4627f541a69c Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 3 Jul 2009 11:37:18 -0700 Subject: Move FileDescriptorProto to an internal symbol table. --- upb.h | 4 ++++ upb_context.c | 39 ++++++++++++++++++++++++++++----------- upb_context.h | 5 +++-- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/upb.h b/upb.h index 8c1af4f..d62fba6 100644 --- a/upb.h +++ b/upb.h @@ -59,6 +59,10 @@ INLINE void upb_print(struct upb_string *str) { fputc('\n', stdout); } +#define UPB_STRLIT(strlit) {.ptr=strlit, .byte_len=sizeof(strlit)-1} +#define UPB_STRFARG(str) (str).byte_len, (str).ptr +#define UPB_STRFMT "%.*s" + /* A list of types as they are encoded on-the-wire. */ enum upb_wire_type { UPB_WIRE_TYPE_VARINT = 0, diff --git a/upb_context.c b/upb_context.c index e9cfdfb..8025614 100644 --- a/upb_context.c +++ b/upb_context.c @@ -18,24 +18,30 @@ static int memrchr(char *data, char c, size_t len) return off; } +bool addfd(struct upb_strtable *t, google_protobuf_FileDescriptorProto *fd); + bool upb_context_init(struct upb_context *c) { upb_strtable_init(&c->symtab, 16, sizeof(struct upb_symtab_entry)); + upb_strtable_init(&c->psymtab, 16, sizeof(struct upb_symtab_entry)); /* Add all the types in descriptor.proto so we can parse descriptors. */ - if(!upb_context_addfd(c, &google_protobuf_filedescriptor)) { + if(!addfd(&c->psymtab, &google_protobuf_filedescriptor)) { assert(false); return false; /* Indicates that upb is buggy or corrupt. */ } + struct upb_string name = UPB_STRLIT("google.protobuf.FileDescriptorProto"); + c->fd_msg = upb_strtable_lookup(&c->psymtab, &name); + assert(c->fd_msg); c->fd_size = 16; c->fd_len = 0; c->fd = malloc(sizeof(*c->fd)); return true; } -void upb_context_free(struct upb_context *c) +static void free_symtab(struct upb_strtable *t) { - struct upb_symtab_entry *e = upb_strtable_begin(&c->symtab); - for(; e; e = upb_strtable_next(&c->symtab, &e->e)) { + struct upb_symtab_entry *e = upb_strtable_begin(t); + for(; e; e = upb_strtable_next(t, &e->e)) { switch(e->type) { case UPB_SYM_MESSAGE: upb_msg_free(e->ref.msg); break; case UPB_SYM_ENUM: upb_enum_free(e->ref._enum); break; @@ -44,7 +50,13 @@ void upb_context_free(struct upb_context *c) free(e->ref.msg); /* The pointer is the same for all. */ free(e->e.key.ptr); } - upb_strtable_free(&c->symtab); + upb_strtable_free(t); +} + +void upb_context_free(struct upb_context *c) +{ + free_symtab(&c->symtab); + free_symtab(&c->psymtab); for(size_t i = 0; i < c->fd_len; i++) free(c->fd[i]); free(c->fd); } @@ -192,8 +204,7 @@ static bool insert_message(struct upb_strtable *t, return true; } -bool upb_context_addfd(struct upb_context *c, - google_protobuf_FileDescriptorProto *fd) +bool addfd(struct upb_strtable *t, google_protobuf_FileDescriptorProto *fd) { struct upb_string package = {.byte_len=0}; if(fd->set_flags.has.package) package = *fd->package; @@ -223,7 +234,7 @@ bool upb_context_addfd(struct upb_context *c, /* Attempt to resolve all references. */ struct upb_symtab_entry *e; for(e = upb_strtable_begin(&tmp); e; e = upb_strtable_next(&tmp, &e->e)) { - if(upb_strtable_lookup(&c->symtab, &e->e.key)) + if(upb_strtable_lookup(t, &e->e.key)) goto error; /* Redefinition prohibited. */ if(e->type == UPB_SYM_MESSAGE) { struct upb_msg *m = e->ref.msg; @@ -232,9 +243,9 @@ bool upb_context_addfd(struct upb_context *c, google_protobuf_FieldDescriptorProto *fd = m->field_descriptors[i]; union upb_symbol_ref ref; if(fd->type == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE) - ref = resolve2(&c->symtab, &tmp, &e->e.key, fd->type_name, UPB_SYM_MESSAGE); + ref = resolve2(t, &tmp, &e->e.key, fd->type_name, UPB_SYM_MESSAGE); else if(fd->type == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_ENUM) - ref = resolve2(&c->symtab, &tmp, &e->e.key, fd->type_name, UPB_SYM_ENUM); + ref = resolve2(t, &tmp, &e->e.key, fd->type_name, UPB_SYM_ENUM); else continue; /* No resolving necessary. */ if(!ref.msg) goto error; /* Ref. to undefined symbol. */ @@ -245,7 +256,7 @@ bool upb_context_addfd(struct upb_context *c, /* All references were successfully resolved -- add to the symbol table. */ for(e = upb_strtable_begin(&tmp); e; e = upb_strtable_next(&tmp, &e->e)) - upb_strtable_insert(&c->symtab, &e->e); + upb_strtable_insert(t, &e->e); upb_strtable_free(&tmp); return true; @@ -255,6 +266,12 @@ error: return false; } +bool upb_context_addfd(struct upb_context *c, + google_protobuf_FileDescriptorProto *fd) +{ + return addfd(&c->symtab, fd); +} + bool upb_context_parsefd(struct upb_context *c, struct upb_string *fd_str) { google_protobuf_FileDescriptorProto *fd = upb_alloc_and_parse(c->fd_msg, fd_str, true); diff --git a/upb_context.h b/upb_context.h index 01b8489..d96ee39 100644 --- a/upb_context.h +++ b/upb_context.h @@ -27,8 +27,9 @@ 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. */ + struct upb_strtable symtab; /* The context's symbol table. */ + struct upb_strtable psymtab; /* Private symbols, for internal use. */ + struct upb_msg *fd_msg; /* This is in psymtab, ptr here for convenience. */ /* A list of the FileDescriptorProtos we own (from having parsed them * ourselves) and must free on destruction. */ -- cgit v1.2.3