From ec67a5ded6a3f9c77e265e1beb3efff9fd68aa32 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 24 Jun 2009 18:35:57 -0700 Subject: Implemented a bit more of upb_context. --- upb_context.c | 16 +++++++++++++++- upb_context.h | 2 ++ upb_msg.h | 4 +++- upb_parse.h | 6 +++++- upb_table.h | 2 +- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/upb_context.c b/upb_context.c index 6797cbc..23c2bdf 100644 --- a/upb_context.c +++ b/upb_context.c @@ -5,6 +5,7 @@ */ #include +#include #include #include "descriptor.h" #include "upb_context.h" @@ -72,6 +73,19 @@ bool upb_context_addfd(struct upb_context *c, google_protobuf_FileDescriptorProto *fd, int onredef) { - /* TODO */ + /* TODO: properly handle redefinitions and unresolvable symbols. */ + if(fd->set_flags.has.message_type) { + for(unsigned int i = 0; i < fd->message_type->len; i++) { + struct google_protobuf_DescriptorProto *d = fd->message_type->elements[i]; + if(!d->set_flags.has.name) return false; + struct upb_symtab_entry e; + e.e.key = *d->name; + e.type = UPB_SYM_MESSAGE; + e.p.msg = malloc(sizeof(*e.p.msg)); + upb_msg_init(e.p.msg, d); + upb_strtable_insert(&c->symtab, &e.e); + } + } + /* TODO: handle enums, extensions, and services. */ return true; } diff --git a/upb_context.h b/upb_context.h index bf8e3b6..3ec1566 100644 --- a/upb_context.h +++ b/upb_context.h @@ -69,6 +69,8 @@ struct upb_symtab_entry *upb_context_resolve(struct upb_context *c, struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, struct upb_string *symbol); +/* TODO: let the client enumerate the symbols. */ + /* Adding symbols. ************************************************************/ /* Enum controlling what happens if a symbol is redefined. */ diff --git a/upb_msg.h b/upb_msg.h index 4f06119..6bbb3c3 100644 --- a/upb_msg.h +++ b/upb_msg.h @@ -67,9 +67,11 @@ struct upb_msg { int num_required_fields; /* Required fields have the lowest set bytemasks. */ struct upb_inttable fields_by_num; struct upb_strtable fields_by_name; - struct upb_msg_field fields[]; + struct upb_msg_field *fields; }; +/* Initialize and free a upb_msg. Note that init does not resolve + * upb_msg_field.ref -- that is left to the caller. */ void upb_msg_init(struct upb_msg *m, struct google_protobuf_DescriptorProto *d); void upb_msg_free(struct upb_msg *m); diff --git a/upb_parse.h b/upb_parse.h index 7e53cee..4be272a 100644 --- a/upb_parse.h +++ b/upb_parse.h @@ -37,7 +37,11 @@ void upb_parse_state_free(struct upb_parse_state *state); * * The client can set user_field_desc to a record describing this field -- this * pointer will be supplied to the value callback (for simple values) or the - * submsg_start callback (for submessages). */ + * submsg_start callback (for submessages). + * + * TODO: there needs to be a way to skip a delimited field while still knowing + * its offset and length. That could be through this callback or it could be a + * separate callback. */ typedef upb_field_type_t (*upb_tag_cb)(struct upb_parse_state *s, struct upb_tag *tag, void **user_field_desc); diff --git a/upb_table.h b/upb_table.h index 7565a52..4452fc9 100644 --- a/upb_table.h +++ b/upb_table.h @@ -94,7 +94,7 @@ INLINE void *upb_inttable_lookup(struct upb_inttable *t, uint32_t bucket = upb_inttable_bucket(t, key); struct upb_inttable_entry *e; do { - e = UPB_INDEX(t->t.entries, bucket-1, entry_size); + e = (struct upb_inttable_entry*)UPB_INDEX(t->t.entries, bucket-1, entry_size); if(e->key == key) return e; } while((bucket = e->next) != UPB_END_OF_CHAIN); return NULL; /* Not found. */ -- cgit v1.2.3