summaryrefslogtreecommitdiff
path: root/src/upb_def.c
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-12-22 17:08:14 -0800
committerJoshua Haberman <joshua@reverberate.org>2009-12-22 17:08:14 -0800
commitf49f7f94c10de1ab39bd045e4ff6bb281541b51f (patch)
treeeede24aebb884f1a11aaa31f66302d430331cc86 /src/upb_def.c
parenta230cf5053ce553d92ba5efb51324149fae201b6 (diff)
More progress, upb_data and upb_def compile (but are incomplete).
Diffstat (limited to 'src/upb_def.c')
-rw-r--r--src/upb_def.c117
1 files changed, 55 insertions, 62 deletions
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 <stdlib.h>
+#include <limits.h>
#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);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback