summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--upb/decode.c30
-rw-r--r--upb/msg.c15
-rw-r--r--upb/msg.h6
3 files changed, 25 insertions, 26 deletions
diff --git a/upb/decode.c b/upb/decode.c
index 275f26c..8d3b398 100644
--- a/upb/decode.c
+++ b/upb/decode.c
@@ -30,19 +30,26 @@ const uint8_t upb_desctype_to_fieldtype[] = {
/* Data pertaining to the parse. */
typedef struct {
- /* Current decoding pointer. Points to the beginning of a field until we
- * have finished decoding the whole field. */
- const char *ptr;
+ /* Parsing limit: either end of delimited region or end of buffer. */
+ const char *limit;
+
+ /* Signals how the parse ended:
+ * - when 0: parse ended at delimited limit.
+ * - when 1: parse ended due to end-of-stream.
+ * - otherwise: parse ended due to a terminating tag (either 0 or END_GROUP).
+ *
+ * In the last case, tag-1 is stored, to avoid conflicting with case 0. */
+ uint32_t parse_status;
+
+ upb_arena *arena;
} upb_decstate;
-/* Data pertaining to a single message frame. */
+/* Data passed by value to each parsing function. */
typedef struct {
- const char *limit;
- int32_t group_number; /* 0 if we are not parsing a group. */
-
- /* These members are unset for an unknown group frame. */
+ const char *ptr,
char *msg;
const upb_msglayout *m;
+ upb_decstate *state;
} upb_decframe;
#define CHK(x) if (!(x)) { return false; }
@@ -132,7 +139,7 @@ static void upb_set32(void *msg, size_t ofs, uint32_t val) {
static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame,
const char *start) {
- upb_msg_addunknown(frame->msg, start, d->ptr - start);
+ upb_msg_addunknown(frame->msg, start, d->ptr - start, d->arena);
return true;
}
@@ -559,10 +566,11 @@ static bool upb_decode_message(upb_decstate *d, const char *limit,
return true;
}
-bool upb_decode(const char *buf, size_t size, void *msg,
- const upb_msglayout *l) {
+bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
+ upb_arena *arena) {
upb_decstate state;
state.ptr = buf;
+ state.arena = arena;
return upb_decode_message(&state, buf + size, 0, msg, l);
}
diff --git a/upb/msg.c b/upb/msg.c
index ca2766c..31607b7 100644
--- a/upb/msg.c
+++ b/upb/msg.c
@@ -13,9 +13,6 @@
/* Used when a message is not extendable. */
typedef struct {
- /* TODO(haberman): use pointer tagging so we we are slim when known unknown
- * fields are not present. */
- upb_arena *arena;
char *unknown;
size_t unknown_len;
size_t unknown_size;
@@ -49,10 +46,6 @@ static upb_msg_internal_withext *upb_msg_getinternalwithext(
return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
}
-upb_arena *upb_msg_arena(const upb_msg *msg) {
- return upb_msg_getinternal_const(msg)->arena;
-}
-
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
upb_alloc *alloc = upb_arena_alloc(a);
void *mem = upb_malloc(alloc, upb_msg_sizeof(l));
@@ -70,7 +63,6 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
/* Initialize internal members. */
in = upb_msg_getinternal(msg);
- in->arena = a;
in->unknown = NULL;
in->unknown_len = 0;
in->unknown_size = 0;
@@ -99,10 +91,11 @@ upb_array *upb_array_new(upb_fieldtype_t type, upb_arena *a) {
return ret;
}
-void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len) {
- upb_msg_internal* in = upb_msg_getinternal(msg);
+void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
+ upb_arena *arena) {
+ upb_msg_internal *in = upb_msg_getinternal(msg);
if (len > in->unknown_size - in->unknown_len) {
- upb_alloc *alloc = upb_arena_alloc(in->arena);
+ upb_alloc *alloc = upb_arena_alloc(arena);
size_t need = in->unknown_size + len;
size_t newsize = UPB_MAX(in->unknown_size * 2, need);
in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
diff --git a/upb/msg.h b/upb/msg.h
index e46733f..7f1a6e7 100644
--- a/upb/msg.h
+++ b/upb/msg.h
@@ -58,10 +58,8 @@ typedef struct {
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
-/* Returns the arena for the given message. */
-upb_arena *upb_msg_arena(const upb_msg *msg);
-
-void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len);
+void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
+ upb_arena *arena);
const char *upb_msg_getunknown(const upb_msg *msg, size_t *len);
upb_array *upb_array_new(upb_fieldtype_t type, upb_arena *a);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback