Pass the upb_fielddef* to the endmsg callback.

pull/13171/head
Joshua Haberman 14 years ago
parent 4d65852909
commit abfc897b50
  1. 18
      src/upb_decoder.c
  2. 4
      src/upb_decoder.h
  3. 2
      src/upb_def.c
  4. 3
      src/upb_msg.c
  5. 8
      src/upb_stream.h
  6. 13
      src/upb_stream_vtbl.h
  7. 3
      src/upb_textprinter.c
  8. 9
      tests/test_stream.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;

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

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

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

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

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

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

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

Loading…
Cancel
Save