summaryrefslogtreecommitdiff
path: root/upb/pb
diff options
context:
space:
mode:
Diffstat (limited to 'upb/pb')
-rw-r--r--upb/pb/decoder.c141
-rw-r--r--upb/pb/decoder_x64.dasc141
-rw-r--r--upb/pb/glue.c94
-rw-r--r--upb/pb/glue.h17
-rw-r--r--upb/pb/textprinter.c7
-rw-r--r--upb/pb/varint.h10
6 files changed, 145 insertions, 265 deletions
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c
index 06125dd..b0e2392 100644
--- a/upb/pb/decoder.c
+++ b/upb/pb/decoder.c
@@ -13,6 +13,33 @@
#include "upb/pb/decoder.h"
#include "upb/pb/varint.h"
+typedef struct {
+ uint8_t native_wire_type;
+ bool is_numeric;
+} upb_decoder_typeinfo;
+
+static const upb_decoder_typeinfo upb_decoder_types[] = {
+ {UPB_WIRE_TYPE_END_GROUP, false}, // ENDGROUP
+ {UPB_WIRE_TYPE_64BIT, true}, // DOUBLE
+ {UPB_WIRE_TYPE_32BIT, true}, // FLOAT
+ {UPB_WIRE_TYPE_VARINT, true}, // INT64
+ {UPB_WIRE_TYPE_VARINT, true}, // UINT64
+ {UPB_WIRE_TYPE_VARINT, true}, // INT32
+ {UPB_WIRE_TYPE_64BIT, true}, // FIXED64
+ {UPB_WIRE_TYPE_32BIT, true}, // FIXED32
+ {UPB_WIRE_TYPE_VARINT, true}, // BOOL
+ {UPB_WIRE_TYPE_DELIMITED, false}, // STRING
+ {UPB_WIRE_TYPE_START_GROUP, false}, // GROUP
+ {UPB_WIRE_TYPE_DELIMITED, false}, // MESSAGE
+ {UPB_WIRE_TYPE_DELIMITED, false}, // BYTES
+ {UPB_WIRE_TYPE_VARINT, true}, // UINT32
+ {UPB_WIRE_TYPE_VARINT, true}, // ENUM
+ {UPB_WIRE_TYPE_32BIT, true}, // SFIXED32
+ {UPB_WIRE_TYPE_64BIT, true}, // SFIXED64
+ {UPB_WIRE_TYPE_VARINT, true}, // SINT32
+ {UPB_WIRE_TYPE_VARINT, true}, // SINT64
+};
+
/* upb_decoderplan ************************************************************/
#ifdef UPB_USE_JIT_X64
@@ -32,37 +59,6 @@
#include "upb/pb/decoder_x64.h"
#endif
-typedef struct {
- upb_fhandlers base;
- void (*decode)(struct _upb_decoder *d, struct _upb_fieldent *f);
-#ifdef UPB_USE_JIT_X64
- uint32_t jit_pclabel;
- uint32_t jit_pclabel_notypecheck;
-#endif
-} upb_dplanfield;
-
-typedef struct {
- upb_mhandlers base;
-#ifdef UPB_USE_JIT_X64
- uint32_t jit_startmsg_pclabel;
- uint32_t jit_endofbuf_pclabel;
- uint32_t jit_endofmsg_pclabel;
- uint32_t jit_dyndispatch_pclabel;
- uint32_t jit_unknownfield_pclabel;
- int32_t jit_parent_field_done_pclabel;
- uint32_t max_field_number;
- // Currently keyed on field number. Could also try keying it
- // on encoded or decoded tag, or on encoded field number.
- void **tablearray;
-#endif
-} upb_dplanmsg;
-
-static void *upb_decoderplan_fptrs[];
-
-void upb_decoderplan_initfhandlers(upb_fhandlers *f) {
- f->decode = upb_decoderplan_fptrs[f->type];
-}
-
upb_decoderplan *upb_decoderplan_new(upb_handlers *h, bool allowjit) {
upb_decoderplan *p = malloc(sizeof(*p));
p->handlers = h;
@@ -72,17 +68,6 @@ upb_decoderplan *upb_decoderplan_new(upb_handlers *h, bool allowjit) {
p->jit_code = NULL;
if (allowjit) upb_decoderplan_makejit(p);
#endif
- // Set function pointers for each field's decode function.
- for (int i = 0; i < h->msgs_len; i++) {
- upb_mhandlers *m = h->msgs[i];
- for(upb_inttable_iter i = upb_inttable_begin(&m->fieldtab);
- !upb_inttable_done(i);
- i = upb_inttable_next(&m->fieldtab, i)) {
- upb_itofhandlers_ent *e = upb_inttable_iter_value(i);
- upb_fhandlers *f = e->f;
- upb_decoderplan_initfhandlers(f);
- }
- }
return p;
}
@@ -396,14 +381,6 @@ static void upb_decode_MESSAGE(upb_decoder *d, upb_fhandlers *f) {
upb_push_msg(d, f, upb_decoder_offset(d) + len);
}
-#define F(type) &upb_decode_ ## type
-static void *upb_decoderplan_fptrs[] = {
- &upb_endgroup, F(DOUBLE), F(FLOAT), F(INT64),
- F(UINT64), F(INT32), F(FIXED64), F(FIXED32), F(BOOL), F(STRING),
- F(GROUP), F(MESSAGE), F(STRING), F(UINT32), F(ENUM), F(SFIXED32),
- F(SFIXED64), F(SINT32), F(SINT64)};
-#undef F
-
/* The main decoding loop *****************************************************/
@@ -431,16 +408,18 @@ INLINE upb_fhandlers *upb_decode_tag(upb_decoder *d) {
if (!upb_trydecode_varint32(d, &tag)) return NULL;
uint8_t wire_type = tag & 0x7;
uint32_t fieldnum = tag >> 3;
- upb_itofhandlers_ent *e = upb_inttable_fastlookup(
- d->dispatch_table, fieldnum, sizeof(upb_itofhandlers_ent));
- upb_fhandlers *f = e ? e->f : NULL;
+ const upb_value *val = upb_inttable_lookup32(d->dispatch_table, fieldnum);
+ upb_fhandlers *f = val ? upb_value_getptr(*val) : NULL;
+ bool is_packed = false;
if (f) {
// Wire type check.
- if (wire_type == upb_types[f->type].native_wire_type ||
- (wire_type == UPB_WIRE_TYPE_DELIMITED &&
- upb_types[f->type].is_numeric)) {
+ if (wire_type == upb_decoder_types[f->type].native_wire_type) {
// Wire type is ok.
+ } else if ((wire_type == UPB_WIRE_TYPE_DELIMITED &&
+ upb_decoder_types[f->type].is_numeric)) {
+ // Wire type is ok (and packed).
+ is_packed = true;
} else {
f = NULL;
}
@@ -453,19 +432,18 @@ INLINE upb_fhandlers *upb_decode_tag(upb_decoder *d) {
if (fr->is_sequence && fr->f != f) {
upb_dispatch_endseq(&d->dispatcher);
upb_decoder_setmsgend(d);
+ fr = d->dispatcher.top;
}
- if (f && f->repeated && (!fr->is_sequence || fr->f != f)) {
- uint64_t old_end = d->dispatcher.top->end_ofs;
- upb_dispatcher_frame *fr = upb_dispatch_startseq(&d->dispatcher, f);
- if (wire_type != UPB_WIRE_TYPE_DELIMITED ||
- upb_issubmsgtype(f->type) || upb_isstringtype(f->type)) {
- // Non-packed field -- this tag pertains to only a single message.
- fr->end_ofs = old_end;
- } else {
+ if (f && f->repeated && !fr->is_sequence) {
+ upb_dispatcher_frame *fr2 = upb_dispatch_startseq(&d->dispatcher, f);
+ if (is_packed) {
// Packed primitive field.
uint32_t len = upb_decode_varint32(d);
- fr->end_ofs = upb_decoder_offset(d) + len;
- fr->is_packed = true;
+ fr2->end_ofs = upb_decoder_offset(d) + len;
+ fr2->is_packed = true;
+ } else {
+ // Non-packed field -- this tag pertains to only a single message.
+ fr2->end_ofs = fr->end_ofs;
}
upb_decoder_setmsgend(d);
}
@@ -513,13 +491,37 @@ upb_success_t upb_decoder_decode(upb_decoder *d) {
if (!d->top_is_packed) f = upb_decode_tag(d);
if (!f) {
// Sucessful EOF. We may need to dispatch a top-level implicit frame.
- if (d->dispatcher.top == d->dispatcher.stack + 1) {
- assert(d->dispatcher.top->is_sequence);
+ if (d->dispatcher.top->is_sequence) {
+ assert(d->dispatcher.top == d->dispatcher.stack + 1);
upb_dispatch_endseq(&d->dispatcher);
}
+ assert(d->dispatcher.top == d->dispatcher.stack);
+ upb_dispatch_endmsg(&d->dispatcher, &d->status);
return UPB_OK;
}
- f->decode(d, f);
+
+ switch (f->type) {
+ case UPB_TYPE_ENDGROUP: upb_endgroup(d, f); break;
+ case UPB_TYPE(DOUBLE): upb_decode_DOUBLE(d, f); break;
+ case UPB_TYPE(FLOAT): upb_decode_FLOAT(d, f); break;
+ case UPB_TYPE(INT64): upb_decode_INT64(d, f); break;
+ case UPB_TYPE(UINT64): upb_decode_UINT64(d, f); break;
+ case UPB_TYPE(INT32): upb_decode_INT32(d, f); break;
+ case UPB_TYPE(FIXED64): upb_decode_FIXED64(d, f); break;
+ case UPB_TYPE(FIXED32): upb_decode_FIXED32(d, f); break;
+ case UPB_TYPE(BOOL): upb_decode_BOOL(d, f); break;
+ case UPB_TYPE(STRING):
+ case UPB_TYPE(BYTES): upb_decode_STRING(d, f); break;
+ case UPB_TYPE(GROUP): upb_decode_GROUP(d, f); break;
+ case UPB_TYPE(MESSAGE): upb_decode_MESSAGE(d, f); break;
+ case UPB_TYPE(UINT32): upb_decode_UINT32(d, f); break;
+ case UPB_TYPE(ENUM): upb_decode_ENUM(d, f); break;
+ case UPB_TYPE(SFIXED32): upb_decode_SFIXED32(d, f); break;
+ case UPB_TYPE(SFIXED64): upb_decode_SFIXED64(d, f); break;
+ case UPB_TYPE(SINT32): upb_decode_SINT32(d, f); break;
+ case UPB_TYPE(SINT64): upb_decode_SINT64(d, f); break;
+ case UPB_TYPE_NONE: assert(false); break;
+ }
upb_decoder_checkpoint(d);
}
}
@@ -542,7 +544,6 @@ void upb_decoder_resetplan(upb_decoder *d, upb_decoderplan *p, int msg_offset) {
void upb_decoder_resetinput(upb_decoder *d, upb_byteregion *input,
void *closure) {
assert(d->plan);
- assert(upb_byteregion_discardofs(input) == upb_byteregion_startofs(input));
upb_dispatcher_frame *f =
upb_dispatcher_reset(&d->dispatcher, closure, d->plan->handlers->msgs[0]);
upb_status_clear(&d->status);
diff --git a/upb/pb/decoder_x64.dasc b/upb/pb/decoder_x64.dasc
index fa984ef..f58e403 100644
--- a/upb/pb/decoder_x64.dasc
+++ b/upb/pb/decoder_x64.dasc
@@ -9,8 +9,8 @@
|// parsing the specific message and calling specific handlers.
|//
|// Since the JIT can call other functions (the JIT'ted code is not a leaf
-|// function) we must respect alignment rules. On OS X, this means aligning
-|// the stack to 16 bytes.
+|// function) we must respect alignment rules. All x86-64 systems require
+|// 16-byte stack alignment.
#include <sys/mman.h>
#include "dynasm/dasm_x86.h"
@@ -103,7 +103,7 @@ void upb_reg_jit_gdb(upb_decoderplan *plan) {
// Has to be a separate function, otherwise GCC will complain about
// expressions like (&foo != NULL) because they will never evaluate
// to false.
-static void upb_assert_notnull(void *addr) { assert(addr != NULL); }
+static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; }
|.arch x64
|.actionlist upb_jit_actionlist
@@ -401,45 +401,10 @@ static void upb_decoderplan_jit_decodefield(upb_decoderplan *plan,
}
}
-#if 0
-// These appear not to speed things up, but keeping around for
-// further experimentation.
-static void upb_decoderplan_jit_doappend(upb_decoderplan *plan, uint8_t size,
- upb_fhandlers *f) {
- | mov eax, STDARRAY:ARG1_64->len
- | cmp eax, STDARRAY:ARG1_64->size
- | jne >2
- // If array is full, fall back to actual function.
- | loadfval f
- | callp f->value
- | jmp >3
- |2:
- | mov rcx, STDARRAY:ARG1_64->ptr
- | mov esi, eax
- | add eax, 1
-
- switch (size) {
- case 8:
- | mov [rcx + rsi * 8], ARG3_64
- break;
-
- case 4:
- | mov [rcx + rsi * 4], ARG3_32
- break;
-
- case 1:
- | mov [rcx + rsi * 4], ARG3_8
- break;
- }
-
- | mov STDARRAY:ARG1_64->len, eax
- |3:
-}
-#endif
-
static void upb_decoderplan_jit_callcb(upb_decoderplan *plan,
upb_fhandlers *f) {
- // Call callbacks.
+ // Call callbacks. Specializing the append accessors didn't yield a speed
+ // increase in benchmarks.
if (upb_issubmsgtype(f->type)) {
if (f->type == UPB_TYPE(MESSAGE)) {
| mov rsi, PTR
@@ -457,7 +422,10 @@ static void upb_decoderplan_jit_callcb(upb_decoderplan *plan,
| mov ARG1_64, CLOSURE
| loadfval f
| callp f->startsubmsg
+ | sethas CLOSURE, f->hasbit
| mov CLOSURE, rdx
+ } else {
+ | sethas CLOSURE, f->hasbit
}
| mov qword FRAME->closure, CLOSURE
// TODO: Handle UPB_SKIPSUBMSG, UPB_BREAK
@@ -465,6 +433,7 @@ static void upb_decoderplan_jit_callcb(upb_decoderplan *plan,
const upb_mhandlers *sub_m = upb_fhandlers_getsubmsg(f);
| call =>sub_m->jit_startmsg_pclabel;
+ | popframe upb_fhandlers_getmsg(f)
// Call endsubmsg handler (if any).
if (f->endsubmsg) {
@@ -473,7 +442,6 @@ static void upb_decoderplan_jit_callcb(upb_decoderplan *plan,
| loadfval f
| callp f->endsubmsg
}
- | popframe upb_fhandlers_getmsg(f)
// TODO: Handle UPB_SKIPSUBMSG, UPB_BREAK
| mov DECODER->ptr, PTR
} else {
@@ -494,21 +462,6 @@ static void upb_decoderplan_jit_callcb(upb_decoderplan *plan,
} else if (f->value == &upb_stdmsg_setbool) {
const upb_fielddef *fd = upb_value_getfielddef(f->fval);
| mov [ARG1_64 + fd->offset], ARG3_8
-#if 0
- // These appear not to speed things up, but keeping around for
- // further experimentation.
- } else if (f->value == &upb_stdmsg_setint64_r ||
- f->value == &upb_stdmsg_setuint64_r ||
- f->value == &upb_stdmsg_setptr_r ||
- f->value == &upb_stdmsg_setdouble_r) {
- upb_decoderplan_jit_doappend(plan, 8, f);
- } else if (f->value == &upb_stdmsg_setint32_r ||
- f->value == &upb_stdmsg_setuint32_r ||
- f->value == &upb_stdmsg_setfloat_r) {
- upb_decoderplan_jit_doappend(plan, 4, f);
- } else if (f->value == &upb_stdmsg_setbool_r) {
- upb_decoderplan_jit_doappend(plan, 1, f);
-#endif
} else if (f->value) {
// Load closure and fval into arg registers.
||#ifndef NDEBUG
@@ -520,16 +473,26 @@ static void upb_decoderplan_jit_callcb(upb_decoderplan *plan,
| loadfval f
| callp f->value
}
- | sethas CLOSURE, f->valuehasbit
+ | sethas CLOSURE, f->hasbit
// TODO: Handle UPB_SKIPSUBMSG, UPB_BREAK
| mov DECODER->ptr, PTR
}
}
+static uint64_t upb_get_encoded_tag(upb_fhandlers *f) {
+ uint32_t tag = (f->number << 3) | upb_decoder_types[f->type].native_wire_type;
+ uint64_t encoded_tag = upb_vencode32(tag);
+ // No tag should be greater than 5 bytes.
+ assert(encoded_tag <= 0xffffffffff);
+ return encoded_tag;
+}
+
// PTR should point to the beginning of the tag.
-static void upb_decoderplan_jit_field(upb_decoderplan *plan, uint64_t tag,
- uint64_t next_tag, upb_mhandlers *m,
+static void upb_decoderplan_jit_field(upb_decoderplan *plan, upb_mhandlers *m,
upb_fhandlers *f, upb_fhandlers *next_f) {
+ uint64_t tag = upb_get_encoded_tag(f);
+ uint64_t next_tag = next_f ? upb_get_encoded_tag(next_f) : 0;
+
// PC-label for the dispatch table.
// We check the wire type (which must be loaded in edx) because the
// table is keyed on field number, not type.
@@ -541,10 +504,13 @@ static void upb_decoderplan_jit_field(upb_decoderplan *plan, uint64_t tag,
| mov rsi, FRAME->end_ofs
| pushframe f, rsi, true
if (f->startseq) {
- | mov ARG1_64, CLOSURE
+ | mov ARG1_64, CLOSURE
| loadfval f
- | callp f->startseq
- | mov CLOSURE, rdx
+ | callp f->startseq
+ | sethas CLOSURE, f->hasbit
+ | mov CLOSURE, rdx
+ } else {
+ | sethas CLOSURE, f->hasbit
}
| mov qword FRAME->closure, CLOSURE
}
@@ -590,6 +556,11 @@ static int upb_compare_uint32(const void *a, const void *b) {
}
static void upb_decoderplan_jit_msg(upb_decoderplan *plan, upb_mhandlers *m) {
+ |=>m->jit_afterstartmsg_pclabel:
+ // There was a call to get here, so we need to align the stack.
+ | sub rsp, 8
+ | jmp >1
+
|=>m->jit_startmsg_pclabel:
// There was a call to get here, so we need to align the stack.
| sub rsp, 8
@@ -602,6 +573,7 @@ static void upb_decoderplan_jit_msg(upb_decoderplan *plan, upb_mhandlers *m) {
// TODO: Handle UPB_SKIPSUBMSG, UPB_BREAK
}
+ |1:
| setmsgend m
| check_eob m
| mov ecx, dword [PTR]
@@ -616,30 +588,19 @@ static void upb_decoderplan_jit_msg(upb_decoderplan *plan, upb_mhandlers *m) {
int num_keys = upb_inttable_count(&m->fieldtab);
uint32_t *keys = malloc(num_keys * sizeof(*keys));
int idx = 0;
- for(upb_inttable_iter i = upb_inttable_begin(&m->fieldtab);
- !upb_inttable_done(i);
- i = upb_inttable_next(&m->fieldtab, i)) {
- keys[idx++] = upb_inttable_iter_key(i);
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &m->fieldtab);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ keys[idx++] = upb_inttable_iter_key(&i);
}
qsort(keys, num_keys, sizeof(uint32_t), &upb_compare_uint32);
- upb_fhandlers *last_f = NULL;
- uint64_t last_encoded_tag = 0;
for(int i = 0; i < num_keys; i++) {
- uint32_t fieldnum = keys[i];
- upb_itofhandlers_ent *e = upb_inttable_lookup(&m->fieldtab, fieldnum);
- upb_fhandlers *f = e->f;
- assert(f->number == fieldnum);
- uint32_t tag = (f->number << 3) | upb_types[f->type].native_wire_type;
- uint64_t encoded_tag = upb_vencode32(tag);
- // No tag should be greater than 5 bytes.
- assert(encoded_tag <= 0xffffffffff);
- if (last_f) upb_decoderplan_jit_field(
- plan, last_encoded_tag, encoded_tag, m, last_f, f);
- last_encoded_tag = encoded_tag;
- last_f = f;
+ upb_fhandlers *f = upb_mhandlers_lookup(m, keys[i]);
+ upb_fhandlers *next_f =
+ (i + 1 < num_keys) ? upb_mhandlers_lookup(m, keys[i + 1]) : NULL;
+ upb_decoderplan_jit_field(plan, m, f, next_f);
}
- upb_decoderplan_jit_field(plan, last_encoded_tag, 0, m, last_f, NULL);
free(keys);
@@ -733,18 +694,19 @@ static void upb_decoderplan_jit_assignfieldlabs(upb_fhandlers *f,
static void upb_decoderplan_jit_assignmsglabs(upb_mhandlers *m,
uint32_t *pclabel_count) {
m->jit_startmsg_pclabel = (*pclabel_count)++;
+ m->jit_afterstartmsg_pclabel = (*pclabel_count)++;
m->jit_endofbuf_pclabel = (*pclabel_count)++;
m->jit_endofmsg_pclabel = (*pclabel_count)++;
m->jit_dyndispatch_pclabel = (*pclabel_count)++;
m->jit_unknownfield_pclabel = (*pclabel_count)++;
m->max_field_number = 0;
upb_inttable_iter i;
- for(i = upb_inttable_begin(&m->fieldtab); !upb_inttable_done(i);
- i = upb_inttable_next(&m->fieldtab, i)) {
- uint32_t key = upb_inttable_iter_key(i);
+ upb_inttable_begin(&i, &m->fieldtab);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ uint32_t key = upb_inttable_iter_key(&i);
m->max_field_number = UPB_MAX(m->max_field_number, key);
- upb_itofhandlers_ent *e = upb_inttable_iter_value(i);
- upb_decoderplan_jit_assignfieldlabs(e->f, pclabel_count);
+ upb_fhandlers *f = upb_value_getptr(upb_inttable_iter_value(&i));
+ upb_decoderplan_jit_assignfieldlabs(f, pclabel_count);
}
// TODO: support large field numbers by either using a hash table or
// generating code for a binary search. For now large field numbers
@@ -784,11 +746,12 @@ static void upb_decoderplan_makejit(upb_decoderplan *plan) {
// Create dispatch tables.
for (int i = 0; i < h->msgs_len; i++) {
upb_mhandlers *m = h->msgs[i];
+ // We jump to after the startmsg handler since it is called before entering
+ // the JIT (either by upb_decoder or by a previous call to the JIT).
m->jit_func =
- plan->jit_code + dasm_getpclabel(plan, m->jit_startmsg_pclabel);
+ plan->jit_code + dasm_getpclabel(plan, m->jit_afterstartmsg_pclabel);
for (uint32_t j = 0; j <= m->max_field_number; j++) {
- upb_itofhandlers_ent *e = upb_inttable_lookup(&m->fieldtab, j);
- upb_fhandlers *f = e ? e->f : NULL;
+ upb_fhandlers *f = upb_mhandlers_lookup(m, j);
if (f) {
m->tablearray[j] =
plan->jit_code + dasm_getpclabel(plan, f->jit_pclabel);
diff --git a/upb/pb/glue.c b/upb/pb/glue.c
index 4949fe3..40b901d 100644
--- a/upb/pb/glue.c
+++ b/upb/pb/glue.c
@@ -1,84 +1,17 @@
/*
* upb - a minimalist implementation of protocol buffers.
*
- * Copyright (c) 2010 Google Inc. See LICENSE for details.
+ * Copyright (c) 2010-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include "upb/bytestream.h"
-#include "upb/descriptor.h"
-#include "upb/msg.h"
+#include "upb/descriptor/reader.h"
#include "upb/pb/decoder.h"
#include "upb/pb/glue.h"
-#include "upb/pb/textprinter.h"
-
-bool upb_strtomsg(const char *str, size_t len, void *msg, const upb_msgdef *md,
- bool allow_jit, upb_status *status) {
- upb_stringsrc strsrc;
- upb_stringsrc_init(&strsrc);
- upb_stringsrc_reset(&strsrc, str, len);
-
- upb_decoder d;
- upb_handlers *h = upb_handlers_new();
- upb_accessors_reghandlers(h, md);
- upb_decoderplan *p = upb_decoderplan_new(h, allow_jit);
- upb_decoder_init(&d);
- upb_handlers_unref(h);
- upb_decoder_resetplan(&d, p, 0);
- upb_decoder_resetinput(&d, upb_stringsrc_allbytes(&strsrc), msg);
- upb_success_t ret = upb_decoder_decode(&d);
- // stringsrc and the handlers registered by upb_accessors_reghandlers()
- // should not suspend.
- assert((ret == UPB_OK) == upb_ok(upb_decoder_status(&d)));
- if (status) upb_status_copy(status, upb_decoder_status(&d));
-
- upb_stringsrc_uninit(&strsrc);
- upb_decoder_uninit(&d);
- upb_decoderplan_unref(p);
- return ret == UPB_OK;
-}
-
-void *upb_filetonewmsg(const char *fname, const upb_msgdef *md, upb_status *s) {
- void *msg = upb_stdmsg_new(md);
- size_t len;
- char *data = upb_readfile(fname, &len);
- if (!data) goto err;
- upb_strtomsg(data, len, msg, md, false, s);
- if (!upb_ok(s)) goto err;
- return msg;
-
-err:
- upb_stdmsg_free(msg, md);
- return NULL;
-}
-
-#if 0
-void upb_msgtotext(upb_string *str, upb_msg *msg, upb_msgdef *md,
- bool single_line) {
- upb_stringsink strsink;
- upb_stringsink_init(&strsink);
- upb_stringsink_reset(&strsink, str);
-
- upb_textprinter *p = upb_textprinter_new();
- upb_handlers *h = upb_handlers_new();
- upb_textprinter_reghandlers(h, md);
- upb_textprinter_reset(p, upb_stringsink_bytesink(&strsink), single_line);
-
- upb_status status = UPB_STATUS_INIT;
- upb_msg_runhandlers(msg, md, h, p, &status);
- // None of {upb_msg_runhandlers, upb_textprinter, upb_stringsink} should be
- // capable of returning an error.
- assert(upb_ok(&status));
- upb_status_uninit(&status);
-
- upb_stringsink_uninit(&strsink);
- upb_textprinter_free(p);
- upb_handlers_unref(h);
-}
-#endif
upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
- upb_status *status) {
+ void *owner, upb_status *status) {
upb_stringsrc strsrc;
upb_stringsrc_init(&strsrc);
upb_stringsrc_reset(&strsrc, str, len);
@@ -104,35 +37,20 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
upb_descreader_uninit(&r);
return NULL;
}
- upb_def **defs = upb_descreader_getdefs(&r, n);
+ upb_def **defs = upb_descreader_getdefs(&r, owner, n);
upb_def **defscopy = malloc(sizeof(upb_def*) * (*n));
memcpy(defscopy, defs, sizeof(upb_def*) * (*n));
upb_descreader_uninit(&r);
- // Set default accessors and layouts on all messages.
- for(int i = 0; i < *n; i++) {
- upb_def *def = defscopy[i];
- upb_msgdef *md = upb_dyncast_msgdef(def);
- if (!md) continue;
- // For field in msgdef:
- upb_msg_iter i;
- for(i = upb_msg_begin(md); !upb_msg_done(i); i = upb_msg_next(md, i)) {
- upb_fielddef *f = upb_msg_iter_field(i);
- upb_fielddef_setaccessor(f, upb_stdmsg_accessor(f));
- }
- upb_msgdef_layout(md);
- }
-
return defscopy;
}
bool upb_load_descriptor_into_symtab(upb_symtab *s, const char *str, size_t len,
upb_status *status) {
int n;
- upb_def **defs = upb_load_defs_from_descriptor(str, len, &n, status);
+ upb_def **defs = upb_load_defs_from_descriptor(str, len, &n, &defs, status);
if (!defs) return false;
- bool success = upb_symtab_add(s, defs, n, status);
- for(int i = 0; i < n; i++) upb_def_unref(defs[i]);
+ bool success = upb_symtab_add(s, defs, n, &defs, status);
free(defs);
return success;
}
diff --git a/upb/pb/glue.h b/upb/pb/glue.h
index ff8c85e..6179d8d 100644
--- a/upb/pb/glue.h
+++ b/upb/pb/glue.h
@@ -1,7 +1,7 @@
/*
* upb - a minimalist implementation of protocol buffers.
*
- * Copyright (c) 2011 Google Inc. See LICENSE for details.
+ * Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* upb's core components like upb_decoder and upb_msg are carefully designed to
@@ -34,25 +34,12 @@
extern "C" {
#endif
-// Decodes the given string, which must be in protobuf binary format, to the
-// given upb_msg with msgdef "md", storing the status of the operation in "s".
-bool upb_strtomsg(const char *str, size_t len, void *msg,
- const upb_msgdef *md, bool allow_jit, upb_status *s);
-
-// Parses the given file into a new message of the given type. Caller owns
-// the returned message (or NULL if an error occurred).
-void *upb_filetonewmsg(const char *fname, const upb_msgdef *md, upb_status *s);
-
-//void upb_msgtotext(struct _upb_string *str, void *msg,
-// struct _upb_msgdef *md, bool single_line);
-
-
// Loads all defs from the given protobuf binary descriptor, setting default
// accessors and a default layout on all messages. The caller owns the
// returned array of defs, which will be of length *n. On error NULL is
// returned and status is set (if non-NULL).
upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
- upb_status *status);
+ void *owner, upb_status *status);
// Like the previous but also adds the loaded defs to the given symtab.
bool upb_load_descriptor_into_symtab(upb_symtab *symtab, const char *str,
diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c
index 3f68f90..0d9c967 100644
--- a/upb/pb/textprinter.c
+++ b/upb/pb/textprinter.c
@@ -96,7 +96,7 @@ err:
const upb_fielddef *f = upb_value_getfielddef(fval); \
uint64_t start_ofs = upb_bytesink_getoffset(p->sink); \
CHECK(upb_textprinter_indent(p)); \
- CHECK(upb_bytesink_writestr(p->sink, f->name)); \
+ CHECK(upb_bytesink_writestr(p->sink, upb_fielddef_name(f))); \
CHECK(upb_bytesink_writestr(p->sink, ": ")); \
CHECK(upb_bytesink_printf(p->sink, fmt, upb_value_get ## member(val))); \
CHECK(upb_textprinter_endfield(p)); \
@@ -124,7 +124,8 @@ static upb_flow_t upb_textprinter_putenum(void *_p, upb_value fval,
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
const upb_fielddef *f = upb_value_getfielddef(fval);
- upb_enumdef *enum_def = upb_downcast_enumdef(f->def);
+ const upb_enumdef *enum_def =
+ upb_downcast_enumdef_const(upb_fielddef_subdef(f));
const char *label = upb_enumdef_iton(enum_def, upb_value_getint32(val));
if (label) {
CHECK(upb_bytesink_writestr(p->sink, label));
@@ -157,7 +158,7 @@ static upb_sflow_t upb_textprinter_startsubmsg(void *_p, upb_value fval) {
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
const upb_fielddef *f = upb_value_getfielddef(fval);
CHECK(upb_textprinter_indent(p));
- CHECK(upb_bytesink_printf(p->sink, "%s {", f->name));
+ CHECK(upb_bytesink_printf(p->sink, "%s {", upb_fielddef_name(f)));
if (!p->single_line)
CHECK(upb_bytesink_putc(p->sink, '\n'));
p->indent_depth++;
diff --git a/upb/pb/varint.h b/upb/pb/varint.h
index 815a7a1..c0e0134 100644
--- a/upb/pb/varint.h
+++ b/upb/pb/varint.h
@@ -19,6 +19,16 @@
extern "C" {
#endif
+// A list of types as they are encoded on-the-wire.
+typedef enum {
+ UPB_WIRE_TYPE_VARINT = 0,
+ UPB_WIRE_TYPE_64BIT = 1,
+ UPB_WIRE_TYPE_DELIMITED = 2,
+ UPB_WIRE_TYPE_START_GROUP = 3,
+ UPB_WIRE_TYPE_END_GROUP = 4,
+ UPB_WIRE_TYPE_32BIT = 5,
+} upb_wiretype_t;
+
// The maximum number of bytes that it takes to encode a 64-bit varint.
// Note that with a better encoding this could be 9 (TODO: write up a
// wiki document about this).
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback