summaryrefslogtreecommitdiff
path: root/src/upb_msg.c
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-08-27 11:10:13 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-08-27 11:10:13 -0700
commitf17ed90f7704d77e3eb59a6f6b693ab4c598936a (patch)
tree48c0b69db3984577d77219eb861783b6bed16d24 /src/upb_msg.c
parentb276aa78b6d04a35420ce699ae51771550b97d11 (diff)
Some cleanup and reformatting, fixed the benchmarks.
Diffstat (limited to 'src/upb_msg.c')
-rw-r--r--src/upb_msg.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/upb_msg.c b/src/upb_msg.c
index 80602dd..f977527 100644
--- a/src/upb_msg.c
+++ b/src/upb_msg.c
@@ -156,11 +156,16 @@ static union upb_value_ptr get_value_ptr(struct upb_msg *msg,
{
union upb_value_ptr p = upb_msg_getptr(msg, f);
if(upb_isarray(f)) {
- bool isset = upb_msg_isset(msg, f);
- size_t len = isset ? (*p.arr)->len : 0;
- if(!isset) *p.arr = upb_array_new(f);
- upb_array_resize(*p.arr, len+1);
- p = upb_array_getelementptr(*p.arr, len, f->type);
+ if(!upb_msg_isset(msg, f)) {
+ if(!*p.arr || !upb_mmhead_only(&((*p.arr)->mmhead))) {
+ if(*p.arr)
+ upb_array_unref(*p.arr);
+ *p.arr = upb_array_new(f);
+ }
+ upb_array_truncate(*p.arr);
+ upb_msg_set(msg, f);
+ }
+ p = upb_array_append(*p.arr);
}
return p;
}
@@ -202,7 +207,11 @@ static void str_cb(void *udata, uint8_t *str,
upb_msg_set(msg, f);
if(avail_len != total_len) abort(); /* TODO: support streaming. */
//bool byref = avail_len == total_len && mp->byref;
- *p.str = upb_string_new();
+ if(!*p.str || !upb_mmhead_only(&((*p.str)->mmhead))) {
+ if(*p.str)
+ upb_string_unref(*p.str);
+ *p.str = upb_string_new();
+ }
//if(byref) {
// upb_strdrop(*p.str);
// (*p.str)->ptr = (char*)str;
@@ -220,16 +229,19 @@ static void submsg_start_cb(void *udata, void *user_field_desc)
struct upb_msg_fielddef *f = user_field_desc;
struct upb_msg *oldmsg = mp->top->msg;
union upb_value_ptr p = get_value_ptr(oldmsg, f);
- struct upb_msg **submsg = p.msg;
- //if(*submsg && upb_mmhead_only(&((*submsg)->mmhead))) {
- // /* We can reuse the existing submsg. */
- //} else {
- *submsg = upb_msg_new(f->ref.msg);
- //}
- upb_msg_clear(*submsg);
- upb_msg_set(oldmsg, f);
+
+ if(upb_isarray(f) || !upb_msg_isset(oldmsg, f)) {
+ if(!*p.msg || !upb_mmhead_only(&((*p.msg)->mmhead))) {
+ if(*p.msg)
+ upb_msg_unref(*p.msg);
+ *p.msg = upb_msg_new(f->ref.msg);
+ }
+ upb_msg_clear(*p.msg);
+ upb_msg_set(oldmsg, f);
+ }
+
mp->top++;
- mp->top->msg = *submsg;
+ mp->top->msg = *p.msg;
}
static void submsg_end_cb(void *udata)
@@ -248,6 +260,7 @@ upb_status_t upb_msg_parsestr(struct upb_msg *msg, void *buf, size_t len)
struct upb_msg_parser mp;
upb_msg_parser_reset(&mp, msg, false);
size_t read;
+ upb_msg_clear(msg);
upb_status_t ret = upb_msg_parser_parse(&mp, buf, len, &read);
return ret;
}
@@ -337,7 +350,7 @@ static size_t get_msgsize(struct upb_msgsizes *sizes, struct upb_msg *m)
union upb_value_ptr p = upb_msg_getptr(m, f);
if(upb_isarray(f)) {
for(int32_t j = (*p.arr)->len - 1; j >= 0; j--) {
- union upb_value_ptr elem = upb_array_getelementptr((*p.arr), j, f->type);
+ union upb_value_ptr elem = upb_array_getelementptr(*p.arr, j);
/* TODO: for packed arrays tag size goes outside the loop. */
size += upb_get_tag_size(fd->number);
size += get_valuesize(sizes, elem, f, fd);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback