From f49f7f94c10de1ab39bd045e4ff6bb281541b51f Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 22 Dec 2009 17:08:14 -0800 Subject: More progress, upb_data and upb_def compile (but are incomplete). --- src/upb_def.c | 117 +++++++++++++++++++++++++++------------------------------- 1 file changed, 55 insertions(+), 62 deletions(-) (limited to 'src/upb_def.c') diff --git a/src/upb_def.c b/src/upb_def.c index abf2b56..5f52f31 100644 --- a/src/upb_def.c +++ b/src/upb_def.c @@ -5,6 +5,7 @@ */ #include +#include #include "descriptor.h" #include "upb_def.h" #include "upb_data.h" @@ -149,7 +150,7 @@ void _upb_def_cyclic_ref(struct upb_def *def) { } static void upb_def_init(struct upb_def *def, enum upb_def_type type, - struct upb_string *fqname) { + upb_string *fqname) { def->type = type; def->is_cyclic = 0; // We detect this later, after resolving refs. def->search_depth = 0; @@ -165,10 +166,10 @@ static void upb_def_uninit(struct upb_def *def) { struct upb_unresolveddef { struct upb_def base; - struct upb_string *name; + upb_string *name; }; -static struct upb_unresolveddef *upb_unresolveddef_new(struct upb_string *str) { +static struct upb_unresolveddef *upb_unresolveddef_new(upb_string *str) { struct upb_unresolveddef *def = malloc(sizeof(*def)); upb_string *name = upb_string_getref(str, UPB_REF_THREADUNSAFE_READONLY); upb_def_init(&def->base, UPB_DEF_UNRESOLVED, name); @@ -267,7 +268,7 @@ static void fielddef_sort(struct upb_fielddef **defs, size_t num) static struct upb_msgdef *msgdef_new(struct upb_fielddef **fields, int num_fields, - struct upb_string *fqname, + upb_string *fqname, struct upb_status *status) { if(num_fields > UPB_MAX_FIELDS) { @@ -349,11 +350,11 @@ struct ntoi_ent { struct iton_ent { struct upb_inttable_entry e; - struct upb_string *string; + upb_string *string; }; static struct upb_enumdef *enumdef_new(google_protobuf_EnumDescriptorProto *ed, - struct upb_string *fqname) + upb_string *fqname) { struct upb_enumdef *e = malloc(sizeof(*e)); upb_def_init(&e->base, UPB_DEF_ENUM, fqname); @@ -421,34 +422,36 @@ static int my_memrchr(char *data, char c, size_t len) /* Given a symbol and the base symbol inside which it is defined, find the * symbol's definition in t. */ static struct symtab_ent *resolve(struct upb_strtable *t, - struct upb_string *base, - struct upb_string *symbol) + upb_string *base, + upb_string *symbol) { - if(base->byte_len + symbol->byte_len + 1 >= UPB_SYMBOL_MAXLEN || - symbol->byte_len == 0) return NULL; - - if(symbol->ptr[0] == UPB_SYMBOL_SEPARATOR) { - /* Symbols starting with '.' are absolute, so we do a single lookup. */ - struct upb_string sym_str = {.ptr = symbol->ptr+1, - .byte_len = symbol->byte_len-1}; - return upb_strtable_lookup(t, &sym_str); + if(upb_strlen(base) + upb_strlen(symbol) + 1 >= UPB_SYMBOL_MAXLEN || + upb_strlen(symbol) == 0) return NULL; + + if(upb_string_getrobuf(symbol)[0] == UPB_SYMBOL_SEPARATOR) { + // Symbols starting with '.' are absolute, so we do a single lookup. + // Slice to omit the leading '.' + upb_string *sym_str = upb_strslice(symbol, 1, INT_MAX); + struct symtab_ent *e = upb_strtable_lookup(t, sym_str); + upb_string_unref(sym_str); + return e; } else { - /* Remove components from base until we find an entry or run out. */ - char sym[UPB_SYMBOL_MAXLEN+1]; - struct upb_string sym_str = {.ptr = sym}; - int baselen = base->byte_len; + // Remove components from base until we find an entry or run out. + upb_string *sym_str = upb_string_new(true); + int baselen = upb_strlen(base); while(1) { - /* sym_str = base[0...base_len] + UPB_SYMBOL_SEPARATOR + symbol */ - memcpy(sym, base->ptr, baselen); - sym[baselen] = UPB_SYMBOL_SEPARATOR; - memcpy(sym + baselen + 1, symbol->ptr, symbol->byte_len); - sym_str.byte_len = baselen + symbol->byte_len + 1; - - struct symtab_ent *e = upb_strtable_lookup(t, &sym_str); + // sym_str = base[0...base_len] + UPB_SYMBOL_SEPARATOR + symbol + upb_strlen_t len = baselen + upb_strlen(symbol) + 1; + char *buf = upb_string_getrwbuf(sym_str, len); + memcpy(buf, upb_string_getrobuf(base), baselen); + buf[baselen] = UPB_SYMBOL_SEPARATOR; + memcpy(buf + baselen + 1, upb_string_getrobuf(symbol), upb_strlen(symbol)); + + struct symtab_ent *e = upb_strtable_lookup(t, sym_str); if (e) return e; else if(baselen == 0) return NULL; /* No more scopes to try. */ - baselen = my_memrchr(base->ptr, UPB_SYMBOL_SEPARATOR, baselen); + baselen = my_memrchr(buf, UPB_SYMBOL_SEPARATOR, baselen); } } } @@ -457,26 +460,18 @@ static struct symtab_ent *resolve(struct upb_strtable *t, * join("Foo.Bar", "Baz") -> "Foo.Bar.Baz" * join("", "Baz") -> "Baz" * Caller owns a ref on the returned string. */ -static struct upb_string *join(struct upb_string *base, struct upb_string *name) { - size_t len = base->byte_len + name->byte_len; - if(base->byte_len > 0) len++; /* For the separator. */ - struct upb_string *joined = upb_string_new(); - char *joined_ptr = upb_string_getrwbuf(joined, len); - if(base->byte_len > 0) { - /* nested_base = base + '.' + d->name */ - memcpy(joined_ptr, base->ptr, base->byte_len); - joined_ptr[base->byte_len] = UPB_SYMBOL_SEPARATOR; - memcpy(&joined_ptr[base->byte_len+1], name->ptr, name->byte_len); - } else { - memcpy(joined_ptr, name->ptr, name->byte_len); +static upb_string *join(upb_string *base, upb_string *name) { + upb_string *joined = upb_strdup(base, true); + upb_strlen_t len = upb_strlen(joined); + if(len > 0) { + upb_string_getrwbuf(joined, len + 1)[len] = UPB_SYMBOL_SEPARATOR; } + upb_strcat(joined, name); return joined; } -static struct upb_string *try_define(struct upb_strtable *t, - struct upb_string *base, - struct upb_string *name, - struct upb_status *status) +static upb_string *try_define(struct upb_strtable *t, upb_string *base, + upb_string *name, struct upb_status *status) { if(!name) { upb_seterr(status, UPB_STATUS_ERROR, @@ -484,7 +479,7 @@ static struct upb_string *try_define(struct upb_strtable *t, UPB_STRARG(base)); return NULL; } - struct upb_string *fqname = join(base, name); + upb_string *fqname = join(base, name); if(upb_strtable_lookup(t, fqname)) { upb_seterr(status, UPB_STATUS_ERROR, "attempted to redefine symbol '" UPB_STRFMT "'", @@ -497,11 +492,11 @@ static struct upb_string *try_define(struct upb_strtable *t, static void insert_enum(struct upb_strtable *t, google_protobuf_EnumDescriptorProto *ed, - struct upb_string *base, + upb_string *base, struct upb_status *status) { - struct upb_string *name = ed->set_flags.has.name ? ed->name : NULL; - struct upb_string *fqname = try_define(t, base, name, status); + upb_string *name = ed->set_flags.has.name ? ed->name : NULL; + upb_string *fqname = try_define(t, base, name, status); if(!fqname) return; struct symtab_ent e; @@ -512,11 +507,11 @@ static void insert_enum(struct upb_strtable *t, static void insert_message(struct upb_strtable *t, google_protobuf_DescriptorProto *d, - struct upb_string *base, bool sort, + upb_string *base, bool sort, struct upb_status *status) { - struct upb_string *name = d->set_flags.has.name ? d->name : NULL; - struct upb_string *fqname = try_define(t, base, name, status); + upb_string *name = d->set_flags.has.name ? d->name : NULL; + upb_string *fqname = try_define(t, base, name, status); if(!fqname) return; int num_fields = d->set_flags.has.field ? d->field->len : 0; @@ -601,7 +596,7 @@ static void addfd(struct upb_strtable *addto, struct upb_strtable *existingdefs, google_protobuf_FileDescriptorProto *fd, bool sort, struct upb_status *status) { - struct upb_string *pkg; + upb_string *pkg; // Temporary hack until the static data is integrated into our // memory-management scheme. bool should_unref; @@ -635,11 +630,11 @@ static void addfd(struct upb_strtable *addto, struct upb_strtable *existingdefs, for(e = upb_strtable_begin(addto); e; e = upb_strtable_next(addto, &e->e)) { struct upb_msgdef *m = upb_dyncast_msgdef(e->def); if(!m) continue; - struct upb_string *base = e->e.key; + upb_string *base = e->e.key; for(upb_field_count_t i = 0; i < m->num_fields; i++) { struct upb_fielddef *f = &m->fields[i]; if(!upb_hasdef(f)) continue; // No resolving necessary. - struct upb_string *name = upb_downcast_unresolveddef(f->def)->name; + upb_string *name = upb_downcast_unresolveddef(f->def)->name; struct symtab_ent *found = resolve(existingdefs, base, name); if(!found) found = resolve(addto, base, name); upb_field_type_t expected = upb_issubmsg(f) ? UPB_DEF_MSG : UPB_DEF_ENUM; @@ -689,9 +684,9 @@ struct upb_symtab *upb_symtab_new() if(!upb_ok(&status)) { fprintf(stderr, "Failed to initialize upb: %s.\n", status.msg); assert(false); - return NULL; /* Indicates that upb is buggy or corrupt. */ + return NULL; // Indicates that upb is buggy or corrupt. } - struct upb_string name = UPB_STRLIT("google.protobuf.FileDescriptorSet"); + upb_string name = UPB_STRLIT("google.protobuf.FileDescriptorSet"); struct symtab_ent *e = upb_strtable_lookup(&s->psymtab, &name); assert(e); s->fds_msgdef = upb_downcast_msgdef(e->def); @@ -737,8 +732,7 @@ struct upb_def **upb_symtab_getdefs(struct upb_symtab *s, int *count, return defs; } -struct upb_def *upb_symtab_lookup(struct upb_symtab *s, - struct upb_string *sym) +struct upb_def *upb_symtab_lookup(struct upb_symtab *s, upb_string *sym) { upb_rwlock_rdlock(&s->lock); struct symtab_ent *e = upb_strtable_lookup(&s->symtab, sym); @@ -752,9 +746,8 @@ struct upb_def *upb_symtab_lookup(struct upb_symtab *s, } -struct upb_def *upb_symtab_resolve(struct upb_symtab *s, - struct upb_string *base, - struct upb_string *symbol) { +struct upb_def *upb_symtab_resolve(struct upb_symtab *s, upb_string *base, + upb_string *symbol) { upb_rwlock_rdlock(&s->lock); struct symtab_ent *e = resolve(&s->symtab, base, symbol); struct upb_def *ret = NULL; @@ -816,7 +809,7 @@ void upb_symtab_addfds(struct upb_symtab *s, return; } -void upb_symtab_add_desc(struct upb_symtab *s, struct upb_string *desc, +void upb_symtab_add_desc(struct upb_symtab *s, upb_string *desc, struct upb_status *status) { upb_msg *fds = upb_msg_new(s->fds_msgdef); -- cgit v1.2.3