From 8465e5e65014ac080d62855f8abfd44acdf7beb2 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 2 Feb 2011 10:00:30 -0800 Subject: Gutted upb_msg a bit, re-adding only the essentials. --- core/upb_msg.h | 109 ++++++--------------------------------------------------- 1 file changed, 11 insertions(+), 98 deletions(-) (limited to 'core/upb_msg.h') diff --git a/core/upb_msg.h b/core/upb_msg.h index 815a7cb..0569039 100644 --- a/core/upb_msg.h +++ b/core/upb_msg.h @@ -1,9 +1,15 @@ /* * upb - a minimalist implementation of protocol buffers. * - * Copyright (c) 2010 Joshua Haberman. See LICENSE for details. + * Copyright (c) 2010-2011 Joshua Haberman. See LICENSE for details. * - * Data structure for storing a message of protobuf data. + * Data structure for storing a message of protobuf data. Unlike Google's + * protobuf, upb_msg and upb_array are reference counted instead of having + * exclusive ownership of their fields. This is a better match for dynamic + * languages where statements like a.b = other_b are normal. + * + * upb's parsers and serializers could also be used to populate and serialize + * other kinds of message objects (even one generated by Google's protobuf). */ #ifndef UPB_MSG_H @@ -17,24 +23,6 @@ extern "C" { #endif -upb_value upb_field_tryrecycle(upb_valueptr p, upb_value v, upb_fielddef *f, - upb_valuetype_t type); - -INLINE void _upb_value_ref(upb_value v) { upb_atomic_ref(v.refcount); } - -void _upb_field_free(upb_value v, upb_fielddef *f); -void _upb_elem_free(upb_value v, upb_fielddef *f); -INLINE void _upb_field_unref(upb_value v, upb_fielddef *f) { - assert(upb_field_ismm(f)); - if (v.refcount && upb_atomic_unref(v.refcount)) - _upb_field_free(v, f); -} -INLINE void _upb_elem_unref(upb_value v, upb_fielddef *f) { - assert(upb_elem_ismm(f)); - if (v.refcount && upb_atomic_unref(v.refcount)) - _upb_elem_free(v, f); -} - /* upb_array ******************************************************************/ typedef uint32_t upb_arraylen_t; @@ -63,47 +51,6 @@ INLINE uint32_t upb_array_len(upb_array *a) { return a->len; } -INLINE upb_value upb_array_get(upb_array *a, upb_fielddef *f, uint32_t elem) { - assert(elem < upb_array_len(a)); - return upb_value_read(_upb_array_getptr(a, f, elem), f->type); -} - -// For string or submessages, will release a ref on the previously set value. -// and take a ref on the new value. The array must already be at least "elem" -// long; to append use append_mutable. -INLINE void upb_array_set(upb_array *a, upb_fielddef *f, uint32_t elem, - upb_value val) { - assert(elem < upb_array_len(a)); - upb_valueptr p = _upb_array_getptr(a, f, elem); - if (upb_elem_ismm(f)) { - _upb_elem_unref(upb_value_read(p, f->type), f); - _upb_value_ref(val); - } - upb_value_write(p, val, f->type); -} - -INLINE void upb_array_resize(upb_array *a, upb_fielddef *f) { - if (a->len == a->size) { - a->len *= 2; - a->elements._void = realloc(a->elements._void, - a->len * upb_types[f->type].size); - } -} - -// Append an element to an array of string or submsg with the default value, -// returning it. This will try to reuse previously allocated memory. -INLINE upb_value upb_array_appendmutable(upb_array *a, upb_fielddef *f) { - - assert(upb_elem_ismm(f)); - upb_array_resize(a, f); - upb_valueptr p = _upb_array_getptr(a, f, a->len++); - upb_valuetype_t type = upb_elem_valuetype(f); - upb_value val = upb_value_read(p, type); - val = upb_field_tryrecycle(p, val, f, type); - return val; -} - - /* upb_msg ********************************************************************/ struct _upb_msg { @@ -111,19 +58,14 @@ struct _upb_msg { uint8_t data[4]; // We allocate the appropriate amount per message. }; -// INTERNAL-ONLY FUNCTIONS. - void _upb_msg_free(upb_msg *msg, upb_msgdef *md); -// Returns a pointer to the given field. INLINE upb_valueptr _upb_msg_getptr(upb_msg *msg, upb_fielddef *f) { upb_valueptr p; p._void = &msg->data[f->byte_offset]; return p; } -// PUBLIC FUNCTIONS. - // Creates a new msg of the given type. upb_msg *upb_msg_new(upb_msgdef *md); @@ -143,38 +85,9 @@ INLINE void upb_msg_clear(upb_msg *msg, upb_msgdef *md) { memset(msg->data, 0, md->set_flags_bytes); } -// Used to obtain an empty message of the given type, attempting to reuse the -// memory pointed to by msg if it has no other referents. -void upb_msg_recycle(upb_msg **_msg, upb_msgdef *md); - -// For a repeated field, appends the given scalar value (ie. not a message or -// array) to the field's array; for non-repeated fields, overwrites the -// existing value with this one. -// REQUIRES: !upb_issubmsg(f) -void upb_msg_appendval(upb_msg *msg, upb_fielddef *f, upb_value val); - -upb_msg *upb_msg_append_emptymsg(upb_msg *msg, upb_fielddef *f); - -// Returns the current value of the given field if set, or the default value if -// not set. The returned value is not mutable! (In practice this only matters -// for submessages and arrays). -INLINE upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) { - if (upb_msg_has(msg, f)) { - return upb_value_read(_upb_msg_getptr(msg, f), f->type); - } else { - return f->default_value; - } -} - -// If the given string, submessage, or array is already set, returns it. -// Otherwise sets it and returns an empty instance, attempting to reuse any -// previously allocated memory. -INLINE upb_value upb_msg_getmutable(upb_msg *msg, upb_fielddef *f); - -// Sets the current value of the field. If this is a string, array, or -// submessage field, releases a ref on the value (if any) that was previously -// set. -INLINE void upb_msg_set(upb_msg *msg, upb_fielddef *f, upb_value val); +// Registers a set of handlers that will populate this msgdef. +void upb_msg_register_handlers(upb_msg *msg, upb_msgdef *md, + upb_handlers *handlers); #ifdef __cplusplus } /* extern "C" */ -- cgit v1.2.3