summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-12-31 18:19:05 -0800
committerJoshua Haberman <joshua@reverberate.org>2009-12-31 18:19:05 -0800
commitc33d51581abab1e2770080535cbcc2bf936cc5f2 (patch)
tree62935c58c1549e4af87d171242baf48f65dca86b
parentf6cc21bc2daf657621fbc82e8ec3475eaee82d1f (diff)
upbc compiles and links! But probably doesn't work yet.
-rw-r--r--src/upb.h28
-rw-r--r--src/upb_data.c138
-rw-r--r--src/upb_data.h34
-rw-r--r--src/upb_parse.c117
-rw-r--r--src/upb_parse.h10
5 files changed, 201 insertions, 126 deletions
diff --git a/src/upb.h b/src/upb.h
index 158d631..e130dd8 100644
--- a/src/upb.h
+++ b/src/upb.h
@@ -13,6 +13,7 @@
#include <stdint.h>
#include <stdio.h> // only for size_t.
#include "descriptor_const.h"
+#include "upb_atomic.h"
#ifdef __cplusplus
extern "C" {
@@ -124,13 +125,14 @@ struct upb_tag {
// INTERNAL-ONLY: never refer to these types with a tag ("union", "struct").
// Always use the typedefs.
-union upb_string;
-union upb_array;
-struct upb_msg;
+union _upb_string;
+union _upb_array;
+struct _upb_msg;
-typedef union upb_string upb_string;
-typedef union upb_array upb_array;
-typedef struct upb_msg upb_msg;
+typedef union _upb_string upb_string;
+typedef union _upb_array upb_array;
+typedef struct _upb_msg upb_msg;
+typedef upb_atomic_refcount_t upb_data;
// A single .proto value. The owner must have an out-of-band way of knowing
// the type, so that it knows which union member to use.
@@ -142,9 +144,10 @@ union upb_value {
uint32_t uint32;
uint64_t uint64;
bool _bool;
- union upb_string *str;
- union upb_array *arr;
- struct upb_msg *msg;
+ upb_string *str;
+ upb_array *arr;
+ upb_msg *msg;
+ upb_data *data;
};
// A pointer to a .proto value. The owner must have an out-of-band way of
@@ -158,9 +161,10 @@ union upb_value_ptr {
uint32_t *uint32;
uint64_t *uint64;
bool *_bool;
- union upb_string **str;
- union upb_array **arr;
- struct upb_msg **msg;
+ upb_string **str;
+ upb_array **arr;
+ upb_msg **msg;
+ upb_data **data;
void *_void;
};
diff --git a/src/upb_data.c b/src/upb_data.c
index 595015f..084a03c 100644
--- a/src/upb_data.c
+++ b/src/upb_data.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include "upb_data.h"
#include "upb_def.h"
+#include "upb_parse.h"
static uint32_t round_up_to_pow2(uint32_t v)
{
@@ -51,6 +52,18 @@ static void check_not_frozen(upb_data *d) {
if(upb_data_hasflag(d, UPB_DATA_FROZEN)) abort();
}
+
+/* upb_string *******************************************************************/
+
+upb_string *upb_string_new() {
+ upb_string *s = malloc(sizeof(upb_refcounted_string));
+ data_init(&s->common.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
+ s->refcounted.byte_size = 0;
+ s->common.byte_len = 0;
+ s->common.ptr = NULL;
+ return s;
+}
+
static upb_strlen_t string_get_bytesize(upb_string *s) {
if(upb_data_hasflag(&s->common.base, UPB_DATA_REFCOUNTED)) {
return s->refcounted.byte_size;
@@ -68,18 +81,6 @@ static void string_set_bytesize(upb_string *s, upb_strlen_t newsize) {
}
}
-
-/* upb_string *******************************************************************/
-
-upb_string *upb_string_new() {
- upb_string *s = malloc(sizeof(upb_refcounted_string));
- data_init(&s->common.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
- s->refcounted.byte_size = 0;
- s->common.byte_len = 0;
- s->common.ptr = NULL;
- return s;
-}
-
void _upb_string_free(upb_string *s)
{
if(string_get_bytesize(s) != 0) free(s->common.ptr);
@@ -136,11 +137,6 @@ void upb_strcat(upb_string *s, upb_string *append) {
upb_string_getrobuf(append), append_len);
}
-void upb_strcpy(upb_string *dest, upb_string *src) {
- upb_strlen_t src_len = upb_strlen(src);
- memcpy(upb_string_getrwbuf(dest, src_len), upb_string_getrobuf(src), src_len);
-}
-
upb_string *upb_strslice(upb_string *s, int offset, int len) {
upb_string *slice = upb_string_new();
len = UPB_MIN((upb_strlen_t)len, upb_strlen(s) - (upb_strlen_t)offset);
@@ -165,6 +161,15 @@ int upb_strcmp(upb_string *s1, upb_string *s2) {
/* upb_array ******************************************************************/
+upb_array *upb_array_new() {
+ upb_array *a = malloc(sizeof(upb_refcounted_array));
+ data_init(&a->common.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
+ a->refcounted.size = 0;
+ a->common.len = 0;
+ a->common.elements._void = NULL;
+ return a;
+}
+
// ONLY handles refcounted arrays for the moment.
void _upb_array_free(upb_array *a, struct upb_fielddef *f)
{
@@ -178,9 +183,42 @@ void _upb_array_free(upb_array *a, struct upb_fielddef *f)
free(a);
}
+static upb_arraylen_t array_get_size(upb_array *a) {
+ if(upb_data_hasflag(&a->common.base, UPB_DATA_REFCOUNTED)) {
+ return a->refcounted.size;
+ } else {
+ return (a->norefcount.size_and_flags & 0xFFFFFFF8) >> 3;
+ }
+}
+
+static void array_set_size(upb_array *a, upb_arraylen_t newsize) {
+ if(upb_data_hasflag(&a->common.base, UPB_DATA_REFCOUNTED)) {
+ a->refcounted.size = newsize;
+ } else {
+ a->norefcount.size_and_flags &= 0x7;
+ a->norefcount.size_and_flags |= (newsize << 3);
+ }
+}
+
+void upb_array_resize(upb_array *a, upb_strlen_t len) {
+ check_not_frozen(&a->common.base);
+ if(array_get_size(a) < len) {
+ // Need to resize.
+ size_t new_size = round_up_to_pow2(len);
+ a->common.elements._void = realloc(a->common.elements._void, new_size);
+ array_set_size(a, new_size);
+ }
+ a->common.len = len;
+}
+
+
/* upb_msg ********************************************************************/
+static void upb_msg_sethas(upb_msg *msg, struct upb_fielddef *f) {
+ msg->data[f->field_index/8] |= (1 << (f->field_index % 8));
+}
+
upb_msg *upb_msg_new(struct upb_msgdef *md) {
upb_msg *msg = malloc(md->size);
memset(msg, 0, md->size);
@@ -219,74 +257,75 @@ struct upb_msgparser {
/* Helper function that returns a pointer to where the next value for field "f"
* should be stored, taking into account whether f is an array that may need to
* be allocated or resized. */
-static union upb_value_ptr get_value_ptr(struct upb_msg *msg,
- struct upb_fielddef *f)
+static union upb_value_ptr get_value_ptr(upb_msg *msg, struct upb_fielddef *f)
{
- union upb_value_ptr p = upb_msg_getptr(msg, f);
+ union upb_value_ptr p = _upb_msg_getptr(msg, f);
if(upb_isarray(f)) {
- if(!upb_msg_isset(msg, f)) {
- if(!*p.arr || !upb_mmhead_only(&((*p.arr)->mmhead))) {
+ if(!upb_msg_has(msg, f)) {
+ if(!*p.arr || !upb_data_only(*p.data)) {
if(*p.arr)
- upb_array_unref(*p.arr);
- *p.arr = upb_array_new(f);
+ upb_array_unref(*p.arr, f);
+ *p.arr = upb_array_new();
}
upb_array_truncate(*p.arr);
- upb_msg_set(msg, f);
+ upb_msg_sethas(msg, f);
}
- p = upb_array_append(*p.arr);
+ upb_arraylen_t oldlen = upb_array_len(*p.arr);
+ upb_array_resize(*p.arr, oldlen + 1);
+ p = _upb_array_getptr(*p.arr, f, oldlen);
}
return p;
}
-/* Callbacks for the stream parser. */
+// Callbacks for the stream parser.
+// TODO: implement these in terms of public interfaces.
static bool value_cb(void *udata, struct upb_msgdef *msgdef,
struct upb_fielddef *f, union upb_value val)
{
(void)msgdef;
struct upb_msgparser *mp = udata;
- struct upb_msg *msg = mp->top->msg;
+ upb_msg *msg = mp->top->msg;
union upb_value_ptr p = get_value_ptr(msg, f);
- upb_msg_set(msg, f);
+ upb_msg_sethas(msg, f);
upb_value_write(p, val, f->type);
return true;
}
static bool str_cb(void *udata, struct upb_msgdef *msgdef,
- struct upb_fielddef *f, uint8_t *str, size_t avail_len,
+ struct upb_fielddef *f, const uint8_t *str, size_t avail_len,
size_t total_len)
{
(void)msgdef;
struct upb_msgparser *mp = udata;
- struct upb_msg *msg = mp->top->msg;
+ upb_msg *msg = mp->top->msg;
union upb_value_ptr p = get_value_ptr(msg, f);
- upb_msg_set(msg, f);
+ upb_msg_sethas(msg, f);
if(avail_len != total_len) abort(); /* TODO: support streaming. */
- if(!*p.str || !upb_mmhead_only(&((*p.str)->mmhead))) {
+ if(!*p.str || !upb_data_only(*p.data)) {
if(*p.str)
upb_string_unref(*p.str);
*p.str = upb_string_new();
}
- upb_string_resize(*p.str, total_len);
- memcpy((*p.str)->ptr, str, avail_len);
- (*p.str)->byte_len = avail_len;
+ upb_strcpylen(*p.str, str, avail_len);
return true;
}
static void start_cb(void *udata, struct upb_fielddef *f)
{
struct upb_msgparser *mp = udata;
- struct upb_msg *oldmsg = mp->top->msg;
+ upb_msg *oldmsg = mp->top->msg;
union upb_value_ptr p = get_value_ptr(oldmsg, f);
- if(upb_isarray(f) || !upb_msg_isset(oldmsg, f)) {
- if(!*p.msg || !upb_mmhead_only(&((*p.msg)->mmhead))) {
+ if(upb_isarray(f) || !upb_msg_has(oldmsg, f)) {
+ struct upb_msgdef *md = upb_downcast_msgdef(f->def);
+ if(!*p.msg || !upb_data_only(*p.data)) {
if(*p.msg)
- upb_msg_unref(*p.msg);
- *p.msg = upb_msg_new(upb_downcast_msgdef(f->def));
+ upb_msg_unref(*p.msg, md);
+ *p.msg = upb_msg_new(md);
}
- upb_msg_clear(*p.msg);
- upb_msg_set(oldmsg, f);
+ upb_msg_clear(*p.msg, md);
+ upb_msg_sethas(oldmsg, f);
}
mp->top++;
@@ -308,10 +347,9 @@ struct upb_msgparser *upb_msgparser_new(struct upb_msgdef *def)
return mp;
}
-void upb_msgparser_reset(struct upb_msgparser *s, struct upb_msg *msg, bool byref)
+void upb_msgparser_reset(struct upb_msgparser *s, upb_msg *msg)
{
upb_cbparser_reset(s->s, s);
- s->byref = byref;
s->top = s->stack;
s->top->msg = msg;
}
@@ -322,13 +360,13 @@ void upb_msgparser_free(struct upb_msgparser *s)
free(s);
}
-void upb_msg_parsestr(struct upb_msg *msg, void *buf, size_t len,
+void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_string *str,
struct upb_status *status)
{
- struct upb_msgparser *mp = upb_msgparser_new(msg->def);
- upb_msgparser_reset(mp, msg, false);
- upb_msg_clear(msg);
- upb_msgparser_parse(mp, buf, len, status);
+ struct upb_msgparser *mp = upb_msgparser_new(md);
+ upb_msgparser_reset(mp, msg);
+ upb_msg_clear(msg, md);
+ upb_msgparser_parse(mp, str, status);
upb_msgparser_free(mp);
}
diff --git a/src/upb_data.h b/src/upb_data.h
index b3bbb3c..872f237 100644
--- a/src/upb_data.h
+++ b/src/upb_data.h
@@ -35,7 +35,8 @@ struct upb_fielddef;
// The "base class" of strings, arrays, and messages. Contains a few flags and
// possibly a reference count. None of the functions for upb_data are public,
// but some of the constants are.
-typedef upb_atomic_refcount_t upb_data;
+
+// typedef upb_atomic_refcount_t upb_data;
// The flags in upb_data.
typedef enum {
@@ -196,7 +197,7 @@ typedef struct {
uint32_t byte_size;
} upb_refcounted_string;
-union upb_string {
+union _upb_string {
upb_norefcount_string norefcount;
upb_string_common common;
upb_refcounted_string refcounted;
@@ -265,8 +266,22 @@ INLINE bool upb_streql(upb_string *s1, upb_string *s2) {
// Like strcmp().
int upb_strcmp(upb_string *s1, upb_string *s2);
+// Like upb_strcpy, but copies from a buffer and length.
+INLINE void upb_strcpylen(upb_string *dest, const void *src, upb_strlen_t len) {
+ memcpy(upb_string_getrwbuf(dest, len), src, len);
+}
+
// Replaces the contents of "dest" with the contents of "src".
-void upb_strcpy(upb_string *dest, upb_string *src);
+INLINE void upb_strcpy(upb_string *dest, upb_string *src) {
+ upb_strcpylen(dest, upb_string_getrobuf(src), upb_strlen(src));
+}
+
+// Like upb_strcpy, but copies from a NULL-terminated string.
+INLINE void upb_strcpyc(upb_string *dest, const char *src) {
+ // This does two passes over src, but that is necessary unless we want to
+ // repeatedly re-allocate dst, which seems worse.
+ upb_strcpylen(dest, src, strlen(src));
+}
// Returns a new string whose contents are a copy of s.
upb_string *upb_strdup(upb_string *s);
@@ -323,7 +338,7 @@ typedef struct {
upb_arraylen_t size;
} upb_refcounted_array;
-union upb_array {
+union _upb_array {
upb_norefcount_array norefcount;
upb_array_common common;
upb_refcounted_array refcounted;
@@ -395,12 +410,17 @@ INLINE size_t upb_array_len(upb_array *a) {
return a->common.len;
}
+INLINE void upb_array_truncate(upb_array *a) {
+ a->common.len = 0;
+}
+
+
/* upb_msg ********************************************************************/
// Note that some inline functions for upb_msg are defined in upb_def.h since
// they rely on the defs.
-struct upb_msg {
+struct _upb_msg {
upb_data base;
uint8_t data[4]; // We allocate the appropriate amount per message.
};
@@ -444,7 +464,9 @@ INLINE union upb_value upb_msg_get(upb_msg *msg, struct upb_fielddef *f) {
// and will drop a ref on whatever was there before.
void upb_msg_set(upb_msg *msg, struct upb_fielddef *f, union upb_value val);
-void upb_msg_clear(upb_msg *msg, struct upb_msgdef *md);
+INLINE void upb_msg_clear(upb_msg *msg, struct upb_msgdef *md) {
+ memset(msg->data, 0, md->set_flags_bytes);
+}
/* Parsing ********************************************************************/
diff --git a/src/upb_parse.c b/src/upb_parse.c
index b9cad5a..32332d9 100644
--- a/src/upb_parse.c
+++ b/src/upb_parse.c
@@ -18,12 +18,14 @@
// generation, because the generated code would want to inline these functions.
// The same applies to the functions to read .proto values below.
-uint8_t *upb_get_v_uint64_t_full(uint8_t *buf, uint8_t *end, uint64_t *val,
- struct upb_status *status);
+const uint8_t *upb_get_v_uint64_t_full(const uint8_t *buf, const uint8_t *end,
+ uint64_t *val,
+ struct upb_status *status);
// Gets a varint (wire type: UPB_WIRE_TYPE_VARINT).
-INLINE uint8_t *upb_get_v_uint64_t(uint8_t *buf, uint8_t *end, uint64_t *val,
- struct upb_status *status)
+INLINE const uint8_t *upb_get_v_uint64_t(const uint8_t *buf, const uint8_t *end,
+ uint64_t *val,
+ struct upb_status *status)
{
// We inline this common case (1-byte varints), if that fails we dispatch to
// the full (non-inlined) version.
@@ -36,20 +38,21 @@ INLINE uint8_t *upb_get_v_uint64_t(uint8_t *buf, uint8_t *end, uint64_t *val,
}
// Gets a varint -- called when we only need 32 bits of it.
-INLINE uint8_t *upb_get_v_uint32_t(uint8_t *buf, uint8_t *end,
- uint32_t *val, struct upb_status *status)
+INLINE const uint8_t *upb_get_v_uint32_t(const uint8_t *buf, const uint8_t *end,
+ uint32_t *val,
+ struct upb_status *status)
{
uint64_t val64;
- uint8_t *ret = upb_get_v_uint64_t(buf, end, &val64, status);
+ const uint8_t *ret = upb_get_v_uint64_t(buf, end, &val64, status);
*val = (uint32_t)val64; // Discard the high bits.
return ret;
}
// Gets a fixed-length 32-bit integer (wire type: UPB_WIRE_TYPE_32BIT).
-INLINE uint8_t *upb_get_f_uint32_t(uint8_t *buf, uint8_t *end,
- uint32_t *val, struct upb_status *status)
+INLINE const uint8_t *upb_get_f_uint32_t(const uint8_t *buf, const uint8_t *end,
+ uint32_t *val, struct upb_status *status)
{
- uint8_t *uint32_end = buf + sizeof(uint32_t);
+ const uint8_t *uint32_end = buf + sizeof(uint32_t);
if(uint32_end > end) {
status->code = UPB_STATUS_NEED_MORE_DATA;
return end;
@@ -65,10 +68,11 @@ INLINE uint8_t *upb_get_f_uint32_t(uint8_t *buf, uint8_t *end,
}
// Gets a fixed-length 64-bit integer (wire type: UPB_WIRE_TYPE_64BIT).
-INLINE uint8_t *upb_get_f_uint64_t(uint8_t *buf, uint8_t *end,
- uint64_t *val, struct upb_status *status)
+INLINE const uint8_t *upb_get_f_uint64_t(const uint8_t *buf, const uint8_t *end,
+ uint64_t *val,
+ struct upb_status *status)
{
- uint8_t *uint64_end = buf + sizeof(uint64_t);
+ const uint8_t *uint64_end = buf + sizeof(uint64_t);
if(uint64_end > end) {
status->code = UPB_STATUS_NEED_MORE_DATA;
return end;
@@ -84,10 +88,11 @@ INLINE uint8_t *upb_get_f_uint64_t(uint8_t *buf, uint8_t *end,
return uint64_end;
}
-INLINE uint8_t *upb_skip_v_uint64_t(uint8_t *buf, uint8_t *end,
- struct upb_status *status)
+INLINE const uint8_t *upb_skip_v_uint64_t(const uint8_t *buf,
+ const uint8_t *end,
+ struct upb_status *status)
{
- uint8_t *const maxend = buf + 10;
+ const uint8_t *const maxend = buf + 10;
uint8_t last = 0x80;
for(; buf < (uint8_t*)end && (last & 0x80); buf++)
last = *buf;
@@ -102,10 +107,11 @@ INLINE uint8_t *upb_skip_v_uint64_t(uint8_t *buf, uint8_t *end,
return buf;
}
-INLINE uint8_t *upb_skip_f_uint32_t(uint8_t *buf, uint8_t *end,
- struct upb_status *status)
+INLINE const uint8_t *upb_skip_f_uint32_t(const uint8_t *buf,
+ const uint8_t *end,
+ struct upb_status *status)
{
- uint8_t *uint32_end = buf + sizeof(uint32_t);
+ const uint8_t *uint32_end = buf + sizeof(uint32_t);
if(uint32_end > end) {
status->code = UPB_STATUS_NEED_MORE_DATA;
return end;
@@ -113,10 +119,11 @@ INLINE uint8_t *upb_skip_f_uint32_t(uint8_t *buf, uint8_t *end,
return uint32_end;
}
-INLINE uint8_t *upb_skip_f_uint64_t(uint8_t *buf, uint8_t *end,
- struct upb_status *status)
+INLINE const uint8_t *upb_skip_f_uint64_t(const uint8_t *buf,
+ const uint8_t *end,
+ struct upb_status *status)
{
- uint8_t *uint64_end = buf + sizeof(uint64_t);
+ const uint8_t *uint64_end = buf + sizeof(uint64_t);
if(uint64_end > end) {
status->code = UPB_STATUS_NEED_MORE_DATA;
return end;
@@ -137,8 +144,8 @@ INLINE int64_t upb_zzdec_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); }
// // not contain the entire value UPB_STATUS_NEED_MORE_DATA is returned).
// // On success, a pointer will be returned to the first byte that was
// // not consumed.
-// uint8_t *upb_get_INT32(uint8_t *buf, uint8_t *end, int32_t *d,
-// struct upb_status *status);
+// const uint8_t *upb_get_INT32(const uint8_t *buf, const uint8_t *end,
+// int32_t *d, struct upb_status *status);
//
// // Given an already read wire value s (source), convert it to a .proto
// // value and return it.
@@ -151,10 +158,10 @@ INLINE int64_t upb_zzdec_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); }
INLINE val_t upb_wvtov_ ## type(wire_t s)
#define GET(type, v_or_f, wire_t, val_t, member_name) \
- INLINE uint8_t *upb_get_ ## type(uint8_t *buf, uint8_t *end, val_t *d, \
- struct upb_status *status) { \
+ INLINE const uint8_t *upb_get_ ## type(const uint8_t *buf, const uint8_t *end, \
+ val_t *d, struct upb_status *status) { \
wire_t tmp = 0; \
- uint8_t *ret = upb_get_ ## v_or_f ## _ ## wire_t(buf, end, &tmp, status); \
+ const uint8_t *ret = upb_get_ ## v_or_f ## _ ## wire_t(buf, end, &tmp, status); \
*d = upb_wvtov_ ## type(tmp); \
return ret; \
}
@@ -192,11 +199,11 @@ T(FLOAT, f, uint32_t, float, _float) {
#undef T
// Parses a tag, places the result in *tag.
-INLINE uint8_t *parse_tag(uint8_t *buf, uint8_t *end, struct upb_tag *tag,
- struct upb_status *status)
+INLINE const uint8_t *parse_tag(const uint8_t *buf, const uint8_t *end,
+ struct upb_tag *tag, struct upb_status *status)
{
uint32_t tag_int;
- uint8_t *ret = upb_get_v_uint32_t(buf, end, &tag_int, status);
+ const uint8_t *ret = upb_get_v_uint32_t(buf, end, &tag_int, status);
tag->wire_type = (upb_wire_type_t)(tag_int & 0x07);
tag->field_number = tag_int >> 3;
return ret;
@@ -207,10 +214,10 @@ INLINE uint8_t *parse_tag(uint8_t *buf, uint8_t *end, struct upb_tag *tag,
* Parses a 64-bit varint that is known to be >= 2 bytes (the inline version
* handles 1 and 2 byte varints).
*/
-uint8_t *upb_get_v_uint64_t_full(uint8_t *buf, uint8_t *end, uint64_t *val,
- struct upb_status *status)
+const uint8_t *upb_get_v_uint64_t_full(const uint8_t *buf, const uint8_t *end,
+ uint64_t *val, struct upb_status *status)
{
- uint8_t *const maxend = buf + 10;
+ const uint8_t *const maxend = buf + 10;
uint8_t last = 0x80;
*val = 0;
int bitpos;
@@ -231,9 +238,10 @@ uint8_t *upb_get_v_uint64_t_full(uint8_t *buf, uint8_t *end, uint64_t *val,
return buf;
}
-uint8_t *upb_parse_wire_value(uint8_t *buf, uint8_t *end, upb_wire_type_t wt,
- union upb_wire_value *wv,
- struct upb_status *status)
+const uint8_t *upb_parse_wire_value(uint8_t *buf, uint8_t *end,
+ upb_wire_type_t wt,
+ union upb_wire_value *wv,
+ struct upb_status *status)
{
switch(wt) {
case UPB_WIRE_TYPE_VARINT:
@@ -252,8 +260,9 @@ uint8_t *upb_parse_wire_value(uint8_t *buf, uint8_t *end, upb_wire_type_t wt,
* Advances buf past the current wire value (of type wt), saving the result in
* outbuf.
*/
-static uint8_t *skip_wire_value(uint8_t *buf, uint8_t *end, upb_wire_type_t wt,
- struct upb_status *status)
+static const uint8_t *skip_wire_value(const uint8_t *buf, const uint8_t *end,
+ upb_wire_type_t wt,
+ struct upb_status *status)
{
switch(wt) {
case UPB_WIRE_TYPE_VARINT:
@@ -272,8 +281,10 @@ static uint8_t *skip_wire_value(uint8_t *buf, uint8_t *end, upb_wire_type_t wt,
}
}
-static uint8_t *upb_parse_value(uint8_t *buf, uint8_t *end, upb_field_type_t ft,
- union upb_value_ptr v, struct upb_status *status)
+static const uint8_t *upb_parse_value(const uint8_t *buf, const uint8_t *end,
+ upb_field_type_t ft,
+ union upb_value_ptr v,
+ struct upb_status *status)
{
#define CASE(t, member_name) \
case UPB_TYPE(t): return upb_get_ ## t(buf, end, v.member_name, status);
@@ -349,7 +360,7 @@ void upb_cbparser_reset(struct upb_cbparser *p, void *udata)
p->top->end_offset = 0;
}
-static void *get_msgend(struct upb_cbparser *p, uint8_t *start)
+static const void *get_msgend(struct upb_cbparser *p, const uint8_t *start)
{
if(p->top->end_offset > 0)
return start + (p->top->end_offset - p->completed_offset);
@@ -357,7 +368,7 @@ static void *get_msgend(struct upb_cbparser *p, uint8_t *start)
return (void*)UINTPTR_MAX; // group.
}
-static bool isgroup(void *submsg_end)
+static bool isgroup(const void *submsg_end)
{
return submsg_end == (void*)UINTPTR_MAX;
}
@@ -374,9 +385,9 @@ INLINE bool upb_check_type(upb_wire_type_t wt, upb_field_type_t ft) {
* Pushes a new stack frame for a submessage with the given len (which will
* be zero if the submessage is a group).
*/
-static uint8_t *push(struct upb_cbparser *p, uint8_t *start,
- uint32_t submsg_len, struct upb_fielddef *f,
- struct upb_status *status)
+static const uint8_t *push(struct upb_cbparser *p, const uint8_t *start,
+ uint32_t submsg_len, struct upb_fielddef *f,
+ struct upb_status *status)
{
p->top++;
if(p->top >= p->limit) {
@@ -397,7 +408,7 @@ static uint8_t *push(struct upb_cbparser *p, uint8_t *start,
* Pops a stack frame, returning a pointer for where the next submsg should
* end (or a pointer that is out of range for a group).
*/
-static void *pop(struct upb_cbparser *p, uint8_t *start)
+static const void *pop(struct upb_cbparser *p, const uint8_t *start)
{
if(p->end_cb) p->end_cb(p->udata);
p->top--;
@@ -405,18 +416,18 @@ static void *pop(struct upb_cbparser *p, uint8_t *start)
}
-size_t upb_cbparser_parse(struct upb_cbparser *p, void *_buf, size_t len,
+size_t upb_cbparser_parse(struct upb_cbparser *p, upb_string *str,
struct upb_status *status)
{
// buf is our current offset, moves from start to end.
- uint8_t *buf = _buf;
- uint8_t *const start = buf; // ptr equivalent of p->completed_offset
- uint8_t *end = buf + len;
+ const uint8_t *buf = (uint8_t*)upb_string_getrobuf(str);
+ const uint8_t *const start = buf; // ptr equivalent of p->completed_offset
+ const uint8_t *const end = buf + upb_strlen(str);
// When we have fully parsed a tag/value pair, we advance this.
- uint8_t *completed = buf;
+ const uint8_t *completed = buf;
- uint8_t *submsg_end = get_msgend(p, start);
+ const uint8_t *submsg_end = get_msgend(p, start);
struct upb_msgdef *msgdef = p->top->msgdef;
bool keep_going = true;
@@ -453,7 +464,7 @@ size_t upb_cbparser_parse(struct upb_cbparser *p, void *_buf, size_t len,
int32_t delim_len;
buf = upb_get_INT32(buf, end, &delim_len, status);
CHECK_STATUS();
- uint8_t *delim_end = buf + delim_len;
+ const uint8_t *delim_end = buf + delim_len;
if(f && f->type == UPB_TYPE(MESSAGE)) {
submsg_end = push(p, start, delim_end - start, f, status);
msgdef = p->top->msgdef;
diff --git a/src/upb_parse.h b/src/upb_parse.h
index 12e04e1..7086204 100644
--- a/src/upb_parse.h
+++ b/src/upb_parse.h
@@ -40,7 +40,7 @@ typedef bool (*upb_value_cb)(void *udata, struct upb_msgdef *msgdef,
// available at str. If the client is streaming and the current buffer ends in
// the middle of the string, this number could be less than total_len.
typedef bool (*upb_str_cb)(void *udata, struct upb_msgdef *msgdef,
- struct upb_fielddef *f, uint8_t *str,
+ struct upb_fielddef *f, const uint8_t *str,
size_t avail_len, size_t total_len);
// The start and end callbacks are called when a submessage begins and ends,
@@ -80,7 +80,7 @@ void upb_cbparser_reset(struct upb_cbparser *p, void *udata);
//
// TODO: see if we can provide the following guarantee efficiently:
// retval will always be >= len. */
-size_t upb_cbparser_parse(struct upb_cbparser *p, void *buf, size_t len,
+size_t upb_cbparser_parse(struct upb_cbparser *p, upb_string *str,
struct upb_status *status);
/* Pick parser interface. ************************************************/
@@ -117,10 +117,10 @@ struct upb_pickparser *upb_pickparser_new(struct upb_msgdef *msgdef,
char *fields[],
upb_pp_value_cb value_cb,
upb_pp_str_cb str_cb);
-void upb_pickparser_free(struct upb_cbparser *p);
+void upb_pickparser_free(struct upb_pickparser *p);
void upb_pickparser_reset(struct upb_pickparser *p, void *udata);
-size_t upb_cbparser_parse(struct upb_cbparser *p, void *buf, size_t len,
- struct upb_status *status);
+size_t upb_pickparser_parse(struct upb_pickparser *p, upb_string *str,
+ struct upb_status *status);
#ifdef __cplusplus
} /* extern "C" */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback