summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-02-25 15:33:04 -0800
committerJoshua Haberman <joshua@reverberate.org>2009-02-25 15:34:54 -0800
commitafe132eb10575c31e856b7339942d9259f55d315 (patch)
treedda68993e1980ad10cceb57c467372da0fe3af5b
parent446d7c27ee55f86515e37f8350f7018223676d01 (diff)
Remove DYNARRAY for the stack (wasn't buying much).
-rw-r--r--dynarray.h32
-rw-r--r--pbstream.c38
-rw-r--r--pbstream.h4
3 files changed, 22 insertions, 52 deletions
diff --git a/dynarray.h b/dynarray.h
deleted file mode 100644
index 9ff1289..0000000
--- a/dynarray.h
+++ /dev/null
@@ -1,32 +0,0 @@
-
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#define DEFINE_DYNARRAY(name, type) \
- type *name; \
- int name ## _len; \
- int name ## _size;
-
-#define RESIZE_DYNARRAY(name, desired_len) { \
- int orig_size = name ## _size; \
- while(name ## _size < (desired_len)) \
- name ## _size *= 2; \
- /* don't bother shrinking for now. when/if we do, we'll want to bake in \
- * some kind of hysteresis so that we don't shrink until we've been under \
- * for a while. */ \
- if(name ## _size != orig_size) \
- name = realloc(name, name ## _size * sizeof(*name)); \
- name ## _len = desired_len; \
-}
-
-#define INIT_DYNARRAY(name, initial_len, initial_size) \
- name ## _len = initial_len; \
- name ## _size = initial_size; \
- name = realloc(NULL, name ## _size * sizeof(*name))
-
-#define FREE_DYNARRAY(name) \
- free(name);
-
-#define DYNARRAY_GET_TOP(name) \
- (&name[name ## _len - 1])
-
diff --git a/pbstream.c b/pbstream.c
index 5cdff40..ae61df8 100644
--- a/pbstream.c
+++ b/pbstream.c
@@ -4,6 +4,7 @@
* Copyright (c) 2008-2009 Joshua Haberman. See LICENSE for details.
*/
+#include <stdlib.h>
#include <string.h>
#include "pbstream.h"
@@ -181,10 +182,16 @@ static pbstream_status_t get_MESSAGE(struct pbstream_parse_state *s, char *buf,
CHECK(get_v_uint32_t(&buf, &tmp));
wvtov_MESSAGE(tmp, &d->v.delimited, s->offset);
s->offset = d->v.delimited.offset; /* skip past only the tag. */
- RESIZE_DYNARRAY(s->stack, s->stack_len+1);
- struct pbstream_parse_stack_frame *frame = DYNARRAY_GET_TOP(s->stack);
- frame->message_descriptor = d->field_descriptor->message;
- frame->end_offset = d->v.delimited.offset + d->v.delimited.len;
+ if (unlikely(++s->top == s->limit)) {
+ /* Stack has grown beyond its limit, must reallocate. */
+ int cur_size = s->top - s->base;
+ int new_size = cur_size * 2;
+ s->base = realloc(s->base, new_size * sizeof(*s->top));
+ s->top = s->base + cur_size;
+ s->limit = s->base + new_size;
+ }
+ s->top->message_descriptor = d->field_descriptor->message;
+ s->top->end_offset = d->v.delimited.offset + d->v.delimited.len;
return PBSTREAM_STATUS_OK;
}
@@ -243,7 +250,7 @@ static pbstream_status_t parse_unknown_value(
return PBSTREAM_STATUS_OK;
}
-static struct pbstream_field_descriptor *find_field_descriptor(
+static struct pbstream_field_descriptor *find_field(
struct pbstream_message_descriptor* md,
pbstream_field_number_t field_number)
{
@@ -257,30 +264,27 @@ pbstream_status_t parse_field(struct pbstream_parse_state *s, char *buf,
struct pbstream_value *val,
struct pbstream_wire_value *wv)
{
- struct pbstream_parse_stack_frame *frame = DYNARRAY_GET_TOP(s->stack);
- struct pbstream_message_descriptor *md = frame->message_descriptor;
- struct pbstream_tag tag;
- struct pbstream_field_descriptor *fd;
- struct pbstream_type_info *info;
- pbstream_status_t unknown_value_status;
char *b = buf;
-
- if(unlikely(s->offset >= frame->end_offset)) {
+ /* Check for end-of-message at the current stack depth. */
+ if(unlikely(s->offset >= s->top->end_offset)) {
/* If the end offset isn't an exact field boundary, the pb is corrupt. */
- if(unlikely(s->offset != frame->end_offset))
+ if(unlikely(s->offset != s->top->end_offset))
return PBSTREAM_ERROR_BAD_SUBMESSAGE_END;
- RESIZE_DYNARRAY(s->stack, s->stack_len-1);
+ s->top--;
return PBSTREAM_STATUS_SUBMESSAGE_END;
}
+ struct pbstream_tag tag;
CHECK(parse_tag(&b, &tag));
size_t val_offset = s->offset + (b-buf);
- fd = find_field_descriptor(md, tag.field_number);
+ struct pbstream_field_descriptor *fd = find_field(s->top->message_descriptor,
+ tag.field_number);
+ pbstream_status_t unknown_value_status;
if(unlikely(!fd)) {
unknown_value_status = PBSTREAM_ERROR_UNKNOWN_VALUE;
goto unknown_value;
}
- info = &type_info[fd->type];
+ struct pbstream_type_info *info = &type_info[fd->type];
if(unlikely(tag.wire_type != info->expected_wire_type)) {
unknown_value_status = PBSTREAM_ERROR_MISMATCHED_TYPE;
goto unknown_value;
diff --git a/pbstream.h b/pbstream.h
index b2f8ff8..9cc9578 100644
--- a/pbstream.h
+++ b/pbstream.h
@@ -6,8 +6,6 @@
#include <stdint.h>
#include <stdbool.h>
-#include <stdlib.h>
-#include "dynarray.h"
/* A list of types as they can appear in a .proto file. */
typedef enum pbstream_type {
@@ -136,7 +134,7 @@ struct pbstream_parse_stack_frame {
struct pbstream_parse_state {
size_t offset;
void *user_data;
- DEFINE_DYNARRAY(stack, struct pbstream_parse_stack_frame);
+ struct pbstream_parse_stack_frame *base, *top, *limit;
};
/* Call this once before parsing to initialize the data structures.
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback