summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-07-03 11:37:18 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-07-03 11:37:18 -0700
commit62be5969a14b36e4f3ca336ec57c4627f541a69c (patch)
tree1d91a74460f41c27e6f2bcd3ffd2f176b096164e
parent9eaab71e99b1fedd8b2a29a99b8512b01719469a (diff)
Move FileDescriptorProto to an internal symbol table.
-rw-r--r--upb.h4
-rw-r--r--upb_context.c39
-rw-r--r--upb_context.h5
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. */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback