summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-07-02 20:19:06 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-07-02 20:19:06 -0700
commitb0ef7f0b6778addc91ce04ca1d6e835d44387c83 (patch)
treeb67f490bd178d53c5fa2bc550fef77b0062efafb
parentb8481e0e55aebad1d9ffa0f3845609f929bca02f (diff)
More fixes, completions, still doesn't quite work.
-rw-r--r--Makefile2
-rw-r--r--descriptor.h5
-rw-r--r--tests.c12
-rw-r--r--upb.h2
-rw-r--r--upb_context.c21
-rw-r--r--upb_context.h6
-rw-r--r--upb_msg.c31
-rw-r--r--upb_msg.h2
-rw-r--r--upb_parse.c4
-rw-r--r--upb_parse.h2
-rw-r--r--upb_table.c34
11 files changed, 104 insertions, 17 deletions
diff --git a/Makefile b/Makefile
index b2af7b5..7f1fcd6 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
CC=gcc
CXX=g++
CFLAGS=-std=c99
-CPPFLAGS=-O3 -DNDEBUG -Wall -Wextra -pedantic -g -DUPB_UNALIGNED_READS_OK -fomit-frame-pointer
+CPPFLAGS=-Wall -Wextra -pedantic -g -DUPB_UNALIGNED_READS_OK -fomit-frame-pointer
OBJ=upb_parse.o upb_table.o upb_msg.o upb_context.o descriptor.o
all: $(OBJ) test_table tests
clean:
diff --git a/descriptor.h b/descriptor.h
index ea6fa78..1e7e927 100644
--- a/descriptor.h
+++ b/descriptor.h
@@ -1,5 +1,8 @@
/* Auto-generated from descriptor.proto. Do not edit. */
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H_
+#define GOOGLE_PROTOBUF_DESCRIPTOR_H_
+
#include "upb_msg.h"
/* Enums. */
@@ -401,3 +404,5 @@ struct google_protobuf_UninterpretedOption {
UPB_DEFINE_MSG_ARRAY(google_protobuf_UninterpretedOption)
extern google_protobuf_FileDescriptorProto google_protobuf_filedescriptor;
+
+#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_H_ */
diff --git a/tests.c b/tests.c
index de8e951..c42ebd9 100644
--- a/tests.c
+++ b/tests.c
@@ -1,7 +1,12 @@
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include "descriptor.c"
#include "upb_parse.c"
+#include "upb_context.c"
+#include "upb_msg.c"
+#include "upb_table.c"
void test_get_v_uint64_t()
{
@@ -51,9 +56,16 @@ void test_get_v_uint64_t()
assert(status == UPB_STATUS_NEED_MORE_DATA);
}
+void test_upb_context() {
+ struct upb_context c;
+ assert(upb_context_init(&c));
+ upb_context_free(&c);
+}
+
int main()
{
test_get_v_uint64_t();
+ test_upb_context();
printf("All tests passed.\n");
return 0;
}
diff --git a/upb.h b/upb.h
index 563314c..ebf73c0 100644
--- a/upb.h
+++ b/upb.h
@@ -34,6 +34,8 @@ extern "C" {
/* The maximum number of fields that any one .proto type can have. */
#define UPB_MAX_FIELDS (1<<16)
+INLINE uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; }
+
/* Represents a string or bytes. */
struct upb_string {
/* We expect the data to be 8-bit clean (uint8_t), but char* is such an
diff --git a/upb_context.c b/upb_context.c
index e124583..d469e54 100644
--- a/upb_context.c
+++ b/upb_context.c
@@ -22,8 +22,13 @@ bool upb_context_init(struct upb_context *c)
{
upb_strtable_init(&c->symtab, 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(!upb_context_addfd(c, &google_protobuf_filedescriptor)) {
+ assert(false);
return false; /* Indicates that upb is buggy or corrupt. */
+ }
+ c->fd_size = 16;
+ c->fd_len = 0;
+ c->fd = malloc(sizeof(*c->fd));
return true;
}
@@ -31,6 +36,7 @@ void upb_context_free(struct upb_context *c)
{
upb_strtable_free(&c->symtab);
for(size_t i = 0; i < c->fd_len; i++) free(c->fd[i]);
+ free(c->fd);
}
struct upb_symtab_entry *upb_context_lookup(struct upb_context *c,
@@ -112,7 +118,8 @@ static bool insert_enum(struct upb_strtable *t,
google_protobuf_EnumDescriptorProto *ed,
struct upb_string *base)
{
- if(!ed->set_flags.has.name) return false;
+ // TODO: re-enable when compiler sets this flag
+ //if(!ed->set_flags.has.name) return false;
/* We own this and must free it on destruct. */
struct upb_string fqname = join(base, ed->name);
@@ -137,7 +144,8 @@ static bool insert_message(struct upb_strtable *t,
google_protobuf_DescriptorProto *d,
struct upb_string *base)
{
- if(!d->set_flags.has.name) return false;
+ /* TODO: re-enable when compiler sets this flag. */
+ //if(!d->set_flags.has.name) return false;
/* We own this and must free it on destruct. */
struct upb_string fqname = join(base, d->name);
@@ -232,9 +240,14 @@ error:
}
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);
+ google_protobuf_FileDescriptorProto *fd =
+ upb_alloc_and_parse(c->fd_msg, fd_str, true);
if(!fd) return false;
if(!upb_context_addfd(c, fd)) return false;
+ if(c->fd_size == c->fd_len) {
+ c->fd_size *= 2;
+ c->fd = realloc(c->fd, c->fd_size);
+ }
c->fd[c->fd_len++] = fd; /* Need to keep a ref since we own it. */
return true;
}
diff --git a/upb_context.h b/upb_context.h
index cd62e30..01b8489 100644
--- a/upb_context.h
+++ b/upb_context.h
@@ -82,7 +82,11 @@ INLINE struct upb_symtab_entry *upb_context_symnext(
* defined in this context.
*
* Caller retains ownership of fd, but the context will contain references to
- * it, so it must outlive the context. */
+ * it, so it must outlive the context.
+ *
+ * upb_context_addfd only returns true or false; it does not give any hint
+ * about what happened in the case of failure. This is because the descriptor
+ * is expected to have been validated at the time it was parsed/generated. */
bool upb_context_addfd(struct upb_context *c,
google_protobuf_FileDescriptorProto *fd);
diff --git a/upb_msg.c b/upb_msg.c
index 1c79f57..d508b6d 100644
--- a/upb_msg.c
+++ b/upb_msg.c
@@ -10,8 +10,6 @@
#define ALIGN_UP(p, t) (t + ((p - 1) & (~t - 1)))
-static uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; }
-
static int div_round_up(int numerator, int denominator) {
/* cf. http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division */
return numerator > 0 ? (numerator - 1) / denominator + 1 : 0;
@@ -101,6 +99,20 @@ void *upb_msg_new(struct upb_msg *m)
//void upb_msg_free(void *msg, struct upb_msg *m, bool free_submsgs);
+void upb_msg_ref(struct upb_msg *m, struct upb_msg_field *f,
+ union upb_symbol_ref ref) {
+ struct google_protobuf_FieldDescriptorProto *d =
+ upb_msg_field_descriptor(f, m);
+ struct upb_fieldsbynum_entry *int_e = upb_inttable_lookup(
+ &m->fields_by_num, d->number, sizeof(struct upb_fieldsbynum_entry));
+ struct upb_fieldsbyname_entry *str_e =
+ upb_strtable_lookup(&m->fields_by_name, d->name);
+ assert(int_e && str_e);
+ f->ref = ref;
+ int_e->f.ref = ref;
+ str_e->f.ref = ref;
+}
+
struct mm_upb_string {
struct upb_string s;
uint32_t size;
@@ -262,3 +274,18 @@ upb_status_t upb_msg_parse(struct upb_msg_parse_state *s,
{
return upb_parse(&s->s, data, len, read);
}
+
+void *upb_alloc_and_parse(struct upb_msg *m, struct upb_string *str, bool byref)
+{
+ struct upb_msg_parse_state s;
+ void *msg = upb_msg_new(m);
+ upb_msg_parse_init(&s, msg, m, false, byref);
+ size_t read;
+ upb_status_t status = upb_msg_parse(&s, str->ptr, str->byte_len, &read);
+ if(status == UPB_STATUS_OK && read == str->byte_len) {
+ return msg;
+ } else {
+ upb_msg_free(msg);
+ return NULL;
+ }
+}
diff --git a/upb_msg.h b/upb_msg.h
index 48b411f..e751c27 100644
--- a/upb_msg.h
+++ b/upb_msg.h
@@ -242,7 +242,7 @@ void upb_msg_parse_free(struct upb_msg_parse_state *s);
upb_status_t upb_msg_parse(struct upb_msg_parse_state *s,
void *data, size_t len, size_t *read);
-void *upb_alloc_and_parse(struct upb_msg *m, struct upb_string *s);
+void *upb_alloc_and_parse(struct upb_msg *m, struct upb_string *s, bool byref);
/* Note! These two may not be use on a upb_string* that was initialized by
* means other than these functions. */
diff --git a/upb_parse.c b/upb_parse.c
index 559e227..8b86418 100644
--- a/upb_parse.c
+++ b/upb_parse.c
@@ -247,7 +247,7 @@ upb_status_t upb_parse_value(void **buf, void *end, upb_field_type_t ft,
#undef CASE
}
-void upb_parse_state_init(struct upb_parse_state *state, size_t udata_size)
+void upb_parse_init(struct upb_parse_state *state, size_t udata_size)
{
state->offset = 0;
size_t stack_bytes = (sizeof(*state->stack) + udata_size) * UPB_MAX_NESTING;
@@ -256,7 +256,7 @@ void upb_parse_state_init(struct upb_parse_state *state, size_t udata_size)
state->udata_size = udata_size;
}
-void upb_parse_state_free(struct upb_parse_state *state)
+void upb_parse_free(struct upb_parse_state *state)
{
free(state->stack);
}
diff --git a/upb_parse.h b/upb_parse.h
index 83104f1..182cb9e 100644
--- a/upb_parse.h
+++ b/upb_parse.h
@@ -89,7 +89,7 @@ upb_status_t upb_parse(struct upb_parse_state *s, void *buf, size_t len,
extern upb_wire_type_t upb_expected_wire_types[];
/* Returns true if wt is the correct on-the-wire type for ft. */
INLINE bool upb_check_type(upb_wire_type_t wt, upb_field_type_t ft) {
- return upb_expected_wire_types[ft] == wt;
+ return upb_type_info[ft].expected_wire_type == wt;
}
/* Data-consuming functions (to be called from value cb). *********************/
diff --git a/upb_table.c b/upb_table.c
index 22c0d5a..e572dd1 100644
--- a/upb_table.c
+++ b/upb_table.c
@@ -15,13 +15,11 @@ static const double MAX_LOAD = 0.85;
static uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed);
-static uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; }
-
/* We use 1-based indexes into the table so that 0 can be "NULL". */
-static struct upb_inttable_entry *intent(struct upb_inttable *t, uint32_t i) {
+static struct upb_inttable_entry *intent(struct upb_inttable *t, int32_t i) {
return UPB_INDEX(t->t.entries, i-1, t->t.entry_size);
}
-static struct upb_strtable_entry *strent(struct upb_strtable *t, uint32_t i) {
+static struct upb_strtable_entry *strent(struct upb_strtable *t, int32_t i) {
return UPB_INDEX(t->t.entries, i-1, t->t.entry_size);
}
@@ -190,7 +188,33 @@ void upb_strtable_insert(struct upb_strtable *t, struct upb_strtable_entry *e)
upb_strtable_free(t);
*t = new_table;
}
- strinsert(t->t.entries, e);
+ strinsert(t, e);
+}
+
+void *upb_inttable_begin(struct upb_inttable *t) {
+ return upb_inttable_next(t, intent(t, -1));
+}
+
+void *upb_inttable_next(struct upb_inttable *t, struct upb_inttable_entry *cur) {
+ struct upb_inttable_entry *end = intent(t, upb_inttable_size(t));
+ do {
+ cur = (void*)((char*)cur + t->t.entry_size);
+ if(cur == end) return NULL;
+ } while(cur->key == UPB_EMPTY_ENTRY);
+ return cur;
+}
+
+void *upb_strtable_begin(struct upb_strtable *t) {
+ return upb_strtable_next(t, strent(t, -1));
+}
+
+void *upb_strtable_next(struct upb_strtable *t, struct upb_strtable_entry *cur) {
+ struct upb_strtable_entry *end = strent(t, upb_strtable_size(t));
+ do {
+ cur = (void*)((char*)cur + t->t.entry_size);
+ if(cur == end) return NULL;
+ } while(cur->key.byte_len == 0);
+ return cur;
}
#ifdef UPB_UNALIGNED_READS_OK
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback