summaryrefslogtreecommitdiff
path: root/stream
diff options
context:
space:
mode:
Diffstat (limited to 'stream')
-rw-r--r--stream/upb_decoder.c42
-rw-r--r--stream/upb_decoder.h38
-rw-r--r--stream/upb_strstream.c44
-rw-r--r--stream/upb_strstream.h12
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
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback