summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/upb_decoder.c18
-rw-r--r--src/upb_decoder.h4
-rw-r--r--src/upb_def.c2
-rw-r--r--src/upb_msg.c3
-rw-r--r--src/upb_stream.h8
-rw-r--r--src/upb_stream_vtbl.h13
-rw-r--r--src/upb_textprinter.c3
-rw-r--r--tests/test_stream.c9
8 files changed, 36 insertions, 24 deletions
diff --git a/src/upb_decoder.c b/src/upb_decoder.c
index 7db8243..f028297 100644
--- a/src/upb_decoder.c
+++ b/src/upb_decoder.c
@@ -197,9 +197,8 @@ static upb_flow_t upb_push(upb_decoder *d, upb_fielddef *f,
UPB_GROUP_END_OFFSET :
d->buf_stream_offset + (d->ptr - upb_string_getrobuf(d->buf)) +
upb_value_getint32(submsg_len);
- upb_msgdef *md = upb_downcast_msgdef(f->def);
- d->top->msgdef = md;
- d->msgdef = md;
+ d->top->f = f;
+ d->msgdef = upb_downcast_msgdef(f->def);
upb_dstate_setmsgend(d);
upb_flow_t ret = upb_dispatch_startsubmsg(&d->dispatcher, f);
if (ret == UPB_SKIPSUBMSG) {
@@ -217,9 +216,9 @@ static upb_flow_t upb_push(upb_decoder *d, upb_fielddef *f,
static upb_flow_t upb_pop(upb_decoder *d) {
--d->top;
+ d->msgdef = upb_downcast_msgdef(d->top->f->def);
upb_dstate_setmsgend(d);
- d->msgdef = d->top->msgdef;
- return upb_dispatch_endsubmsg(&d->dispatcher);
+ return upb_dispatch_endsubmsg(&d->dispatcher, d->top->f);
}
void upb_decoder_run(upb_src *src, upb_status *status) {
@@ -228,7 +227,7 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
d->ptr = NULL;
d->end = NULL; // Force a buffer pull.
d->submsg_end = (void*)0x1; // But don't let end-of-message get triggered.
- d->msgdef = d->top->msgdef;
+ d->msgdef = upb_downcast_msgdef(d->top->f->def);
// TODO: handle UPB_SKIPSUBMSG
#define CHECK_FLOW(expr) if ((expr) == UPB_BREAK) { /*assert(!upb_ok(status));*/ goto callback_err; }
@@ -373,9 +372,6 @@ void upb_decoder_sethandlers(upb_src *src, upb_handlers *handlers) {
upb_dispatcher_reset(&d->dispatcher, handlers, true);
d->top = d->stack;
d->buf_stream_offset = 0;
- // The top-level message is not delimited (we can keep receiving data for it
- // indefinitely), so we treat it like a group.
- d->top->end_offset = 0;
}
void upb_decoder_init(upb_decoder *d, upb_msgdef *msgdef) {
@@ -385,7 +381,9 @@ void upb_decoder_init(upb_decoder *d, upb_msgdef *msgdef) {
};
upb_src_init(&d->src, &vtbl);
upb_dispatcher_init(&d->dispatcher);
- d->stack[0].msgdef = msgdef;
+ d->f.def = UPB_UPCAST(msgdef);
+ d->stack[0].f = &d->f;
+ // Never want to end top-level message, so treat it like a group.
d->stack[0].end_offset = UPB_GROUP_END_OFFSET;
d->limit = &d->stack[UPB_MAX_NESTING];
d->buf = NULL;
diff --git a/src/upb_decoder.h b/src/upb_decoder.h
index 6a9f7cc..98b1b94 100644
--- a/src/upb_decoder.h
+++ b/src/upb_decoder.h
@@ -30,7 +30,7 @@ extern "C" {
// The decoder keeps a stack with one entry per level of recursion.
// upb_decoder_frame is one frame of that stack.
typedef struct {
- upb_msgdef *msgdef;
+ upb_fielddef *f;
size_t end_offset; // For groups, 0.
} upb_decoder_frame;
@@ -69,6 +69,8 @@ struct _upb_decoder {
// Where we will store any errors that occur.
upb_status *status;
+ // A fake fielddef for storing the msgdef for the top-level message.
+ upb_fielddef f;
upb_decoder_frame stack[UPB_MAX_NESTING];
};
diff --git a/src/upb_def.c b/src/upb_def.c
index b12ed14..3b21443 100644
--- a/src/upb_def.c
+++ b/src/upb_def.c
@@ -1471,7 +1471,7 @@ static void upb_baredecoder_run(upb_src *src, upb_status *status) {
}
// Detect end-of-submessage.
while(d->offset >= *top) {
- CHECK(upb_dispatch_endsubmsg(&d->dispatcher));
+ CHECK(upb_dispatch_endsubmsg(&d->dispatcher, &f));
d->offset = *(top--);
}
}
diff --git a/src/upb_msg.c b/src/upb_msg.c
index 951b5e0..89913dd 100644
--- a/src/upb_msg.c
+++ b/src/upb_msg.c
@@ -270,7 +270,8 @@ static upb_flow_t upb_msgpopulator_startsubmsg(void *_p, upb_fielddef *f,
return UPB_CONTINUE;
}
-static upb_flow_t upb_msgpopulator_endsubmsg(void *_p) {
+static upb_flow_t upb_msgpopulator_endsubmsg(void *_p, upb_fielddef *f) {
+ (void)f;
upb_msgpopulator *p = _p;
--p->top;
return UPB_CONTINUE;
diff --git a/src/upb_stream.h b/src/upb_stream.h
index 229cf86..34e2710 100644
--- a/src/upb_stream.h
+++ b/src/upb_stream.h
@@ -98,7 +98,8 @@ typedef upb_flow_t (*upb_value_handler_t)(void *closure,
typedef upb_flow_t (*upb_startsubmsg_handler_t)(void *closure,
struct _upb_fielddef *f,
upb_handlers *delegate_to);
-typedef upb_flow_t (*upb_endsubmsg_handler_t)(void *closure);
+typedef upb_flow_t (*upb_endsubmsg_handler_t)(void *closure,
+ struct _upb_fielddef *f);
typedef upb_flow_t (*upb_unknownval_handler_t)(void *closure,
upb_field_number_t fieldnum,
upb_value val);
@@ -126,7 +127,7 @@ typedef upb_flow_t (*upb_unknownval_handler_t)(void *closure,
// return UPB_CONTINUE;
// }
//
-// static upb_flow_t endsubmsg(void *closure) {
+// static upb_flow_t endsubmsg(void *closure, upb_fielddef *f) {
// // Called when a submessage ends.
// return UPB_CONTINUE;
// }
@@ -207,7 +208,8 @@ INLINE upb_flow_t upb_dispatch_startmsg(upb_dispatcher *d);
INLINE upb_flow_t upb_dispatch_endmsg(upb_dispatcher *d);
INLINE upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
struct _upb_fielddef *f);
-INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d);
+INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d,
+ struct _upb_fielddef *f);
INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d, struct _upb_fielddef *f,
upb_value val);
INLINE upb_flow_t upb_dispatch_unknownval(upb_dispatcher *d,
diff --git a/src/upb_stream_vtbl.h b/src/upb_stream_vtbl.h
index 10ee917..e9a4043 100644
--- a/src/upb_stream_vtbl.h
+++ b/src/upb_stream_vtbl.h
@@ -186,6 +186,12 @@ INLINE upb_flow_t upb_startsubmsg_nop(void *closure, struct _upb_fielddef *f,
return UPB_CONTINUE;
}
+INLINE upb_flow_t upb_endsubmsg_nop(void *closure, struct _upb_fielddef *f) {
+ (void)closure;
+ (void)f;
+ return UPB_CONTINUE;
+}
+
INLINE upb_flow_t upb_unknownval_nop(void *closure, upb_field_number_t fieldnum,
upb_value val) {
(void)closure;
@@ -199,7 +205,7 @@ INLINE void upb_register_handlerset(upb_handlers *h, upb_handlerset *set) {
if (!set->endmsg) set->endmsg = &upb_nop;
if (!set->value) set->value = &upb_value_nop;
if (!set->startsubmsg) set->startsubmsg = &upb_startsubmsg_nop;
- if (!set->endsubmsg) set->endsubmsg = &upb_nop;
+ if (!set->endsubmsg) set->endsubmsg = &upb_endsubmsg_nop;
if (!set->unknownval) set->unknownval = &upb_unknownval_nop;
h->set = set;
}
@@ -264,7 +270,8 @@ INLINE upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
return ret;
}
-INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d) {
+INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d,
+ struct _upb_fielddef *f) {
upb_flow_t ret;
if (--d->top->depth == 0) {
ret = d->top->handlers.set->endmsg(d->top->handlers.closure);
@@ -273,7 +280,7 @@ INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d) {
--d->top;
assert(d->top >= d->stack);
}
- return d->top->handlers.set->endsubmsg(d->top->handlers.closure);
+ return d->top->handlers.set->endsubmsg(d->top->handlers.closure, f);
}
INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d,
diff --git a/src/upb_textprinter.c b/src/upb_textprinter.c
index 894a1ea..c0fb944 100644
--- a/src/upb_textprinter.c
+++ b/src/upb_textprinter.c
@@ -107,8 +107,9 @@ err:
return UPB_BREAK;
}
-static upb_flow_t upb_textprinter_endsubmsg(void *_p)
+static upb_flow_t upb_textprinter_endsubmsg(void *_p, upb_fielddef *f)
{
+ (void)f;
upb_textprinter *p = _p;
p->indent_depth--;
upb_textprinter_indent(p);
diff --git a/tests/test_stream.c b/tests/test_stream.c
index 468d40c..8a136fd 100644
--- a/tests/test_stream.c
+++ b/tests/test_stream.c
@@ -53,7 +53,8 @@ static upb_flow_t startsubmsg(void *closure, struct _upb_fielddef *f,
}
}
-static upb_flow_t endsubmsg(void *closure) {
+static upb_flow_t endsubmsg(void *closure, struct _upb_fielddef *f) {
+ (void)f;
test_data *d = closure;
strappendf(d->str, "endsubmsg\n");
return UPB_CONTINUE;
@@ -99,9 +100,9 @@ static void test_dispatcher() {
data.should_delegate = false;
upb_dispatch_startsubmsg(&d, NULL);
upb_dispatch_value(&d, NULL, val);
- upb_dispatch_endsubmsg(&d);
- upb_dispatch_endsubmsg(&d);
- upb_dispatch_endsubmsg(&d);
+ upb_dispatch_endsubmsg(&d, NULL);
+ upb_dispatch_endsubmsg(&d, NULL);
+ upb_dispatch_endsubmsg(&d, NULL);
upb_dispatch_endmsg(&d);
upb_string expected = UPB_STACK_STRING(
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback