summaryrefslogtreecommitdiff
path: root/pbstream.c
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-02-25 22:11:53 -0800
committerJoshua Haberman <joshua@reverberate.org>2009-02-25 22:11:53 -0800
commite6b461c84af646e3cb93e1c9fc965f2da4b92f12 (patch)
tree9f09d5af45392355ddf281201ba72289d9781769 /pbstream.c
parent73978bfc74666fb13c6e65f8c9c4cec90de24236 (diff)
More tests and bugfixes -- parses its first proto!
Diffstat (limited to 'pbstream.c')
-rw-r--r--pbstream.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/pbstream.c b/pbstream.c
index c8711e7..82fc4d2 100644
--- a/pbstream.c
+++ b/pbstream.c
@@ -159,7 +159,9 @@ WVTOV_DELIMITED(MESSAGE);
static pbstream_status_t get_STRING(struct pbstream_parse_state *s, char *buf,
struct pbstream_value *d) {
uint32_t tmp;
- CHECK(get_v_uint32_t(&buf, &tmp));
+ char *b = buf;
+ CHECK(get_v_uint32_t(&b, &tmp));
+ s->offset += (b-buf); /* advance past length varint. */
wvtov_STRING(tmp, &d->v.delimited, s->offset);
s->offset = d->v.delimited.offset + d->v.delimited.len; /* skip string */
/* we leave UTF-8 validation to the client. */
@@ -169,7 +171,9 @@ static pbstream_status_t get_STRING(struct pbstream_parse_state *s, char *buf,
static pbstream_status_t get_BYTES(struct pbstream_parse_state *s, char *buf,
struct pbstream_value *d) {
uint32_t tmp;
- CHECK(get_v_uint32_t(&buf, &tmp));
+ char *b = buf;
+ CHECK(get_v_uint32_t(&b, &tmp));
+ s->offset += (b-buf); /* advance past length varint. */
wvtov_BYTES(tmp, &d->v.delimited, s->offset);
s->offset = d->v.delimited.offset + d->v.delimited.len; /* skip bytes */
return PBSTREAM_STATUS_OK;
@@ -179,9 +183,11 @@ static pbstream_status_t get_MESSAGE(struct pbstream_parse_state *s, char *buf,
struct pbstream_value *d) {
/* We're entering a sub-message. */
uint32_t tmp;
+ char *b = buf;
CHECK(get_v_uint32_t(&buf, &tmp));
+ s->offset += (b-buf); /* advance past length varint. */
wvtov_MESSAGE(tmp, &d->v.delimited, s->offset);
- s->offset = d->v.delimited.offset; /* skip past only the tag. */
+ /* Unlike STRING and BYTES, we *don't* advance past delimited here. */
if (unlikely(++s->top == s->limit)) {
/* Stack has grown beyond its limit, must reallocate. */
int cur_size = s->top - s->base;
@@ -254,7 +260,8 @@ static struct pbstream_field *find_field(struct pbstream_fieldset* fs,
pbstream_field_number_t num)
{
/* TODO: a hybrid array/hashtable structure. */
- if(num < fs->num_fields) return &fs->fields[num];
+ /* TODO: can zero be a tag number? */
+ if(num <= fs->num_fields) return &fs->fields[num-1];
else return NULL;
}
@@ -277,7 +284,7 @@ pbstream_status_t pbstream_parse_field(struct pbstream_parse_state *s,
struct pbstream_tag tag;
CHECK(parse_tag(&b, &tag));
- size_t val_offset = s->offset + (b-buf);
+ s->offset += (b-buf);
struct pbstream_field *fd = find_field(s->top->fieldset, tag.field_number);
pbstream_status_t unknown_value_status;
if(unlikely(!fd)) {
@@ -297,22 +304,25 @@ pbstream_status_t pbstream_parse_field(struct pbstream_parse_state *s,
unknown_value:
wv->type = tag.wire_type;
- CHECK(parse_unknown_value(&b, val_offset, wv));
+ CHECK(parse_unknown_value(&b, s->offset, wv));
s->offset += (b-buf);
return unknown_value_status;
}
void pbstream_init_parser(
struct pbstream_parse_state *state,
- struct pbstream_fieldset *toplevel_fieldset,
- void *user_data)
+ struct pbstream_fieldset *toplevel_fieldset)
{
state->offset = 0;
- state->user_data = user_data;
- /* Initial stack of <300b most protobufs are unlikely to nest >20 deep. */
+ /* Initial stack of <300b, most protobufs are unlikely to nest >20 deep. */
const int initial_stack = 20;
state->top = state->base = malloc(sizeof(*state->base) * initial_stack);
state->limit = state->base + initial_stack;
state->top->fieldset = toplevel_fieldset;
state->top->end_offset = SIZE_MAX;
}
+
+void pbstream_free_parser(struct pbstream_parse_state *state)
+{
+ free(state->base);
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback