summaryrefslogtreecommitdiff
path: root/src/upb_stream.h
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2011-05-08 13:05:12 -0700
committerJoshua Haberman <jhaberman@gmail.com>2011-05-08 13:05:12 -0700
commitf74534b42ac9ac8b0ff496cb0da83f1201bbf8da (patch)
treecf20bb7160a6f37cecd5c2cb4222c03b88e4fcde /src/upb_stream.h
parent4a99abba123fc1d2bef62778846a1f27b2012de0 (diff)
Decoder redesign in preparation for packed fields and start/endseq.
Diffstat (limited to 'src/upb_stream.h')
-rw-r--r--src/upb_stream.h46
1 files changed, 24 insertions, 22 deletions
diff --git a/src/upb_stream.h b/src/upb_stream.h
index d024675..e749964 100644
--- a/src/upb_stream.h
+++ b/src/upb_stream.h
@@ -88,11 +88,12 @@ upb_sflow_t upb_startsubmsg_nop(void *closure, upb_value fval);
upb_flow_t upb_endsubmsg_nop(void *closure, upb_value fval);
upb_flow_t upb_unknownval_nop(void *closure, upb_field_number_t fieldnum,
upb_value val);
-
-typedef struct {
+struct _upb_decoder;
+typedef struct _upb_fieldent {
bool junk;
upb_fieldtype_t type;
bool repeated;
+ bool is_repeated_primitive;
uint32_t number;
// For upb_issubmsg(f) only, the index into the msgdef array of the submsg.
// -1 if unset (indicates that submsg should be skipped).
@@ -106,23 +107,26 @@ typedef struct {
uint32_t jit_pclabel;
uint32_t jit_pclabel_notypecheck;
uint32_t jit_submsg_done_pclabel;
-} upb_handlers_fieldent;
+ void (*decode)(struct _upb_decoder *d, struct _upb_fieldent *f);
+} upb_fieldent;
-typedef struct _upb_handlers_msgent {
+typedef struct _upb_msgent {
upb_startmsg_handler_t startmsg;
upb_endmsg_handler_t endmsg;
upb_unknownval_handler_t unknownval;
- // Maps field number -> upb_handlers_fieldent.
+ // Maps field number -> upb_fieldent.
upb_inttable fieldtab;
uint32_t jit_startmsg_pclabel;
uint32_t jit_endofbuf_pclabel;
uint32_t jit_endofmsg_pclabel;
uint32_t jit_unknownfield_pclabel;
- upb_handlers_fieldent *endgroup_f; // NULL if not a group.
+ bool is_group;
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;
-} upb_handlers_msgent;
+} upb_msgent;
typedef struct {
upb_msgdef *msgdef;
@@ -131,10 +135,10 @@ typedef struct {
struct _upb_handlers {
// Array of msgdefs, [0]=toplevel.
- upb_handlers_msgent *msgs;
+ upb_msgent *msgs;
int msgs_len, msgs_size;
upb_msgdef *toplevel_msgdef; // We own a ref.
- upb_handlers_msgent *msgent;
+ upb_msgent *msgent;
upb_handlers_frame stack[UPB_MAX_TYPE_DEPTH], *top, *limit;
bool should_jit;
};
@@ -272,12 +276,11 @@ void upb_handlers_typed_push(upb_handlers *h, upb_field_number_t fieldnum,
upb_fieldtype_t type, bool repeated);
void upb_handlers_typed_pop(upb_handlers *h);
-INLINE upb_handlers_msgent *upb_handlers_getmsgent(upb_handlers *h,
- upb_handlers_fieldent *f) {
+INLINE upb_msgent *upb_handlers_getmsgent(upb_handlers *h, upb_fieldent *f) {
assert(f->msgent_index != -1);
return &h->msgs[f->msgent_index];
}
-upb_handlers_fieldent *upb_handlers_lookup(upb_inttable *dispatch_table, upb_field_number_t fieldnum);
+upb_fieldent *upb_handlers_lookup(upb_inttable *dispatch_table, upb_field_number_t fieldnum);
/* upb_dispatcher *************************************************************/
@@ -298,11 +301,12 @@ upb_handlers_fieldent *upb_handlers_lookup(upb_inttable *dispatch_table, upb_fie
// consumed, like if this is a submessage of a larger stream.
typedef struct {
- upb_handlers_fieldent *f;
+ upb_fieldent *f;
void *closure;
// Relative to the beginning of this buffer.
// For groups and the top-level: UINT32_MAX.
uint32_t end_offset;
+ bool is_packed; // == !upb_issubmsg(f) && end_offset != UPB_REPATEDEND
} upb_dispatcher_frame;
typedef struct {
@@ -311,7 +315,7 @@ typedef struct {
upb_handlers *handlers;
// Msg and dispatch table for the current level.
- upb_handlers_msgent *msgent;
+ upb_msgent *msgent;
upb_inttable *dispatch_table;
// The number of startsubmsg calls without a corresponding endsubmsg call.
@@ -342,8 +346,6 @@ INLINE bool upb_dispatcher_noframe(upb_dispatcher *d) {
}
-typedef upb_handlers_fieldent upb_dispatcher_field;
-
void upb_dispatcher_init(upb_dispatcher *d, upb_handlers *h);
void upb_dispatcher_reset(upb_dispatcher *d, void *top_closure, uint32_t top_end_offset);
void upb_dispatcher_uninit(upb_dispatcher *d);
@@ -352,20 +354,20 @@ upb_flow_t upb_dispatch_startmsg(upb_dispatcher *d);
void upb_dispatch_endmsg(upb_dispatcher *d, upb_status *status);
// Looks up a field by number for the current message.
-INLINE upb_dispatcher_field *upb_dispatcher_lookup(upb_dispatcher *d,
- upb_field_number_t n) {
- return (upb_dispatcher_field*)upb_inttable_fastlookup(
- d->dispatch_table, n, sizeof(upb_dispatcher_field));
+INLINE upb_fieldent *upb_dispatcher_lookup(upb_dispatcher *d,
+ upb_field_number_t n) {
+ return (upb_fieldent*)upb_inttable_fastlookup(
+ d->dispatch_table, n, sizeof(upb_fieldent));
}
// Dispatches values or submessages -- the client is responsible for having
// previously looked up the field.
upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
- upb_dispatcher_field *f,
+ upb_fieldent *f,
size_t userval);
upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d);
-INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d, upb_dispatcher_field *f,
+INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d, upb_fieldent *f,
upb_value val) {
if (upb_dispatcher_skipping(d)) return UPB_SKIPSUBMSG;
upb_flow_t flow = f->cb.value(d->top->closure, f->fval, val);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback