summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/upb_msg.c44
-rw-r--r--core/upb_msg.h94
2 files changed, 84 insertions, 54 deletions
diff --git a/core/upb_msg.c b/core/upb_msg.c
index a0a5196..83191d2 100644
--- a/core/upb_msg.c
+++ b/core/upb_msg.c
@@ -53,6 +53,50 @@ void _upb_msg_free(upb_msg *msg, upb_msgdef *md) {
free(msg);
}
+void upb_msg_recycle(upb_msg **_msg, upb_msgdef *md);
+ upb_msg *msg = *_msg;
+ if(msg && upb_atomic_only(&msg->refcount)) {
+ upb_msg_clear(msg);
+ } else {
+ upb_msg_unref(msg);
+ *_msg = upb_msg_new();
+ }
+}
+
+void upb_msg_appendval(upb_msg *msg, upb_fielddef *f, upb_value val) {
+ upb_valueptr ptr;
+ if (upb_isarray(f)) {
+ }
+}
+
+INLINE upb_value upb_msg_getmutable(upb_msg *msg, upb_fielddef *f);
+ assert(upb_field_ismm(f));
+ upb_valueptr p = _upb_msg_getptr(msg, f);
+ upb_valuetype_t type = upb_field_valuetype(f);
+ upb_value val = upb_value_read(p, type);
+ if (!upb_msg_has(msg, f)) {
+ upb_msg_sethas(msg, f);
+ val = upb_field_tryrecycle(p, val, f, type);
+ }
+ return val;
+}
+
+INLINE void upb_msg_set(upb_msg *msg, upb_fielddef *f, upb_value val) {
+ upb_valueptr p = _upb_msg_getptr(msg, f);
+ upb_valuetype_t type = upb_field_valuetype(f);
+ if (upb_field_ismm(f)) {
+ _upb_field_unref(upb_value_read(p, type), f);
+ _upb_value_ref(val);
+ }
+ upb_msg_sethas(msg, f);
+ upb_value_write(p, val, upb_field_valuetype(f));
+}
+
+INLINE void upb_msg_sethas(upb_msg *msg, upb_fielddef *f) {
+ msg->data[f->field_index/8] |= (1 << (f->field_index % 8));
+}
+
+
upb_array *upb_array_new(void) {
upb_array *arr = malloc(sizeof(*arr));
upb_atomic_refcount_init(&arr->refcount, 1);
diff --git a/core/upb_msg.h b/core/upb_msg.h
index 2db67c0..815a7cb 100644
--- a/core/upb_msg.h
+++ b/core/upb_msg.h
@@ -45,17 +45,7 @@ struct _upb_array {
upb_valueptr elements;
};
-upb_array *upb_array_new(void);
-
-INLINE uint32_t upb_array_len(upb_array *a) {
- return a->len;
-}
-
void _upb_array_free(upb_array *a, upb_fielddef *f);
-INLINE void upb_array_unref(upb_array *a, upb_fielddef *f) {
- if (upb_atomic_unref(&a->refcount)) _upb_array_free(a, f);
-}
-
INLINE upb_valueptr _upb_array_getptr(upb_array *a, upb_fielddef *f,
uint32_t elem) {
upb_valueptr p;
@@ -63,6 +53,16 @@ INLINE upb_valueptr _upb_array_getptr(upb_array *a, upb_fielddef *f,
return p;
}
+upb_array *upb_array_new(void);
+
+INLINE void upb_array_unref(upb_array *a, upb_fielddef *f) {
+ if (upb_atomic_unref(&a->refcount)) _upb_array_free(a, f);
+}
+
+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);
@@ -93,6 +93,7 @@ INLINE void upb_array_resize(upb_array *a, upb_fielddef *f) {
// 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++);
@@ -110,8 +111,9 @@ struct _upb_msg {
uint8_t data[4]; // We allocate the appropriate amount per message.
};
-// Creates a new msg of the given type.
-upb_msg *upb_msg_new(upb_msgdef *md);
+// 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) {
@@ -120,9 +122,14 @@ INLINE upb_valueptr _upb_msg_getptr(upb_msg *msg, upb_fielddef *f) {
return p;
}
-void _upb_msg_free(upb_msg *msg, upb_msgdef *md);
+// PUBLIC FUNCTIONS.
+
+// Creates a new msg of the given type.
+upb_msg *upb_msg_new(upb_msgdef *md);
+
+// Unrefs the given message.
INLINE void upb_msg_unref(upb_msg *msg, upb_msgdef *md) {
- if (upb_atomic_unref(&msg->refcount)) _upb_msg_free(msg, md);
+ if (msg && upb_atomic_unref(&msg->refcount)) _upb_msg_free(msg, md);
}
// Tests whether the given field is explicitly set, or whether it will return a
@@ -131,12 +138,26 @@ INLINE bool upb_msg_has(upb_msg *msg, upb_fielddef *f) {
return (msg->data[f->field_index/8] & (1 << (f->field_index % 8))) != 0;
}
-INLINE void upb_msg_sethas(upb_msg *msg, upb_fielddef *f) {
- msg->data[f->field_index/8] |= (1 << (f->field_index % 8));
+// Unsets all field values back to their defaults.
+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.
+// 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);
@@ -148,47 +169,12 @@ INLINE upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) {
// 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) {
- assert(upb_field_ismm(f));
- upb_valueptr p = _upb_msg_getptr(msg, f);
- upb_valuetype_t type = upb_field_valuetype(f);
- upb_value val = upb_value_read(p, type);
- if (!upb_msg_has(msg, f)) {
- upb_msg_sethas(msg, f);
- val = upb_field_tryrecycle(p, val, f, type);
- }
- return val;
-}
+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) {
- upb_valueptr p = _upb_msg_getptr(msg, f);
- upb_valuetype_t type = upb_field_valuetype(f);
- if (upb_field_ismm(f)) {
- _upb_field_unref(upb_value_read(p, type), f);
- _upb_value_ref(val);
- }
- upb_msg_sethas(msg, f);
- upb_value_write(p, val, upb_field_valuetype(f));
-}
-
-// Unsets all field values back to their defaults.
-INLINE void upb_msg_clear(upb_msg *msg, upb_msgdef *md) {
- memset(msg->data, 0, md->set_flags_bytes);
-}
-
-// A convenience function for decoding an entire protobuf all at once, without
-// having to worry about setting up the appropriate objects.
-void upb_msg_decodestr(upb_msg *msg, upb_msgdef *md, upb_string *str,
- upb_status *status);
-
-// A convenience function for encoding an entire protobuf all at once. If an
-// error occurs, the null string is returned and the status object contains
-// the error.
-void upb_msg_encodestr(upb_msg *msg, upb_msgdef *md, upb_string *str,
- upb_status *status);
+INLINE void upb_msg_set(upb_msg *msg, upb_fielddef *f, upb_value val);
#ifdef __cplusplus
} /* extern "C" */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback