More fixes, completions, still doesn't quite work.

pull/13171/head
Joshua Haberman 16 years ago
parent b8481e0e55
commit b0ef7f0b67
  1. 2
      Makefile
  2. 5
      descriptor.h
  3. 12
      tests.c
  4. 2
      upb.h
  5. 21
      upb_context.c
  6. 6
      upb_context.h
  7. 31
      upb_msg.c
  8. 2
      upb_msg.h
  9. 4
      upb_parse.c
  10. 2
      upb_parse.h
  11. 34
      upb_table.c

@ -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:

@ -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_ */

@ -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;
}

@ -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

@ -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;
}

@ -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);

@ -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;
}
}

@ -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. */

@ -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);
}

@ -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). *********************/

@ -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

Loading…
Cancel
Save