diff options
Diffstat (limited to 'stream')
-rw-r--r-- | stream/upb_decoder.c | 42 | ||||
-rw-r--r-- | stream/upb_decoder.h | 38 | ||||
-rw-r--r-- | stream/upb_strstream.c | 44 | ||||
-rw-r--r-- | stream/upb_strstream.h | 12 |
4 files changed, 66 insertions, 70 deletions
diff --git a/stream/upb_decoder.c b/stream/upb_decoder.c index 3a279a1..78710b9 100644 --- a/stream/upb_decoder.c +++ b/stream/upb_decoder.c @@ -47,36 +47,6 @@ done: INLINE int32_t upb_zzdec_32(uint32_t n) { return (n >> 1) ^ -(int32_t)(n & 1); } INLINE int64_t upb_zzdec_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); } -// 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; - size_t end_offset; // For groups, 0. -} upb_decoder_frame; - -struct upb_decoder { - // Immutable state of the decoder. - upb_src src; - upb_dispatcher dispatcher; - upb_bytesrc *bytesrc; - upb_msgdef *toplevel_msgdef; - upb_decoder_frame stack[UPB_MAX_NESTING]; - - // Mutable state of the decoder. - - // Where we will store any errors that occur. - upb_status *status; - - // Stack entries store the offset where the submsg ends (for groups, 0). - upb_decoder_frame *top, *limit; - - // Current input buffer. - upb_string *buf; - - // The offset within the overall stream represented by the *beginning* of buf. - size_t buf_stream_offset; -}; - typedef struct { // Our current position in the data buffer. const char *ptr; @@ -279,8 +249,8 @@ void upb_decoder_run(upb_src *src, upb_status *status) { upb_string *str = NULL; // TODO: handle UPB_SKIPSUBMSG -#define CHECK_FLOW(expr) if ((expr) != UPB_CONTINUE) goto err -#define CHECK(expr) if (!expr) goto err; +#define CHECK_FLOW(expr) if ((expr) == UPB_BREAK) { assert(!upb_ok(status)); goto err; } +#define CHECK(expr) if (!expr) { assert(!upb_ok(status)); goto err; } CHECK_FLOW(upb_dispatch_startmsg(&d->dispatcher)); @@ -300,6 +270,7 @@ void upb_decoder_run(upb_src *src, upb_status *status) { if (!upb_decode_tag(d, &state, &tag)) { if (status->code == UPB_EOF && d->top == d->stack) { // Normal end-of-file. + printf("Normal end-of-file!\n"); upb_clearerr(status); CHECK_FLOW(upb_dispatch_endmsg(&d->dispatcher)); upb_string_unref(str); @@ -397,18 +368,16 @@ void upb_decoder_sethandlers(upb_src *src, upb_handlers *handlers) { d->top->end_offset = 0; } -upb_decoder *upb_decoder_new(upb_msgdef *msgdef) { +void upb_decoder_init(upb_decoder *d, upb_msgdef *msgdef) { static upb_src_vtbl vtbl = { &upb_decoder_sethandlers, &upb_decoder_run, }; - upb_decoder *d = malloc(sizeof(*d)); upb_src_init(&d->src, &vtbl); upb_dispatcher_init(&d->dispatcher); d->toplevel_msgdef = msgdef; d->limit = &d->stack[UPB_MAX_NESTING]; d->buf = NULL; - return d; } void upb_decoder_reset(upb_decoder *d, upb_bytesrc *bytesrc) { @@ -421,9 +390,8 @@ void upb_decoder_reset(upb_decoder *d, upb_bytesrc *bytesrc) { d->buf = NULL; } -void upb_decoder_free(upb_decoder *d) { +void upb_decoder_uninit(upb_decoder *d) { upb_string_unref(d->buf); - free(d); } upb_src *upb_decoder_src(upb_decoder *d) { return &d->src; } diff --git a/stream/upb_decoder.h b/stream/upb_decoder.h index 6ba4d77..0684ea2 100644 --- a/stream/upb_decoder.h +++ b/stream/upb_decoder.h @@ -27,14 +27,44 @@ extern "C" { /* upb_decoder *****************************************************************/ +// 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; + size_t end_offset; // For groups, 0. +} upb_decoder_frame; + +struct _upb_decoder { + // Immutable state of the decoder. + upb_src src; + upb_dispatcher dispatcher; + upb_bytesrc *bytesrc; + upb_msgdef *toplevel_msgdef; + upb_decoder_frame stack[UPB_MAX_NESTING]; + + // Mutable state of the decoder. + + // Where we will store any errors that occur. + upb_status *status; + + // Stack entries store the offset where the submsg ends (for groups, 0). + upb_decoder_frame *top, *limit; + + // Current input buffer. + upb_string *buf; + + // The offset within the overall stream represented by the *beginning* of buf. + size_t buf_stream_offset; +}; + // A upb_decoder decodes the binary protocol buffer format, writing the data it // decodes to a upb_sink. -struct upb_decoder; -typedef struct upb_decoder upb_decoder; +struct _upb_decoder; +typedef struct _upb_decoder upb_decoder; // Allocates and frees a upb_decoder, respectively. -upb_decoder *upb_decoder_new(upb_msgdef *md); -void upb_decoder_free(upb_decoder *d); +void upb_decoder_init(upb_decoder *d, upb_msgdef *md); +void upb_decoder_uninit(upb_decoder *d); // Resets the internal state of an already-allocated decoder. This puts it in a // state where it has not seen any data, and expects the next data to be from diff --git a/stream/upb_strstream.c b/stream/upb_strstream.c index d3fd4e0..8a230ae 100644 --- a/stream/upb_strstream.c +++ b/stream/upb_strstream.c @@ -9,25 +9,6 @@ #include <stdlib.h> #include "upb_string.h" -struct upb_stringsrc { - upb_bytesrc bytesrc; - upb_string *str; - upb_strlen_t offset; -}; - -void upb_stringsrc_reset(upb_stringsrc *s, upb_string *str) { - if (str != s->str) { - if (s->str) upb_string_unref(s->str); - s->str = upb_string_getref(str); - } - s->bytesrc.eof = false; -} - -void upb_stringsrc_free(upb_stringsrc *s) { - if (s->str) upb_string_unref(s->str); - free(s); -} - static upb_strlen_t upb_stringsrc_read(upb_bytesrc *_src, void *buf, upb_strlen_t count, upb_status *status) { upb_stringsrc *src = (upb_stringsrc*)_src; @@ -45,27 +26,40 @@ static upb_strlen_t upb_stringsrc_read(upb_bytesrc *_src, void *buf, static bool upb_stringsrc_getstr(upb_bytesrc *_src, upb_string *str, upb_status *status) { upb_stringsrc *src = (upb_stringsrc*)_src; - if (src->offset == upb_string_len(str)) { + if (src->offset == upb_string_len(src->str)) { upb_seterr(status, UPB_EOF, ""); return false; } else { - upb_string_substr(str, src->str, 0, upb_string_len(src->str)); + upb_strlen_t len = upb_string_len(src->str) - src->offset; + upb_string_substr(str, src->str, src->offset, len); + src->offset += len; + assert(src->offset == upb_string_len(src->str)); return true; } } -upb_stringsrc *upb_stringsrc_new() { +void upb_stringsrc_init(upb_stringsrc *s) { static upb_bytesrc_vtbl bytesrc_vtbl = { upb_stringsrc_read, upb_stringsrc_getstr, }; - - upb_stringsrc *s = malloc(sizeof(*s)); s->str = NULL; upb_bytesrc_init(&s->bytesrc, &bytesrc_vtbl); - return s; } +void upb_stringsrc_reset(upb_stringsrc *s, upb_string *str) { + if (str != s->str) { + upb_string_unref(s->str); + s->str = upb_string_getref(str); + } + s->offset = 0; +} + +void upb_stringsrc_uninit(upb_stringsrc *s) { + upb_string_unref(s->str); +} + + upb_bytesrc *upb_stringsrc_bytesrc(upb_stringsrc *s) { return &s->bytesrc; } diff --git a/stream/upb_strstream.h b/stream/upb_strstream.h index d01d21f..1a8792b 100644 --- a/stream/upb_strstream.h +++ b/stream/upb_strstream.h @@ -18,12 +18,16 @@ extern "C" { /* upb_stringsrc **************************************************************/ -struct upb_stringsrc; -typedef struct upb_stringsrc upb_stringsrc; +struct _upb_stringsrc { + upb_bytesrc bytesrc; + upb_string *str; + upb_strlen_t offset; +}; +typedef struct _upb_stringsrc upb_stringsrc; // Create/free a stringsrc. -upb_stringsrc *upb_stringsrc_new(); -void upb_stringsrc_free(upb_stringsrc *s); +void upb_stringsrc_init(upb_stringsrc *s); +void upb_stringsrc_uninit(upb_stringsrc *s); // Resets the stringsrc to a state where it will vend the given string. The // stringsrc will take a reference on the string, so the caller need not ensure |