summaryrefslogtreecommitdiff
path: root/src/upb_msg.h
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2011-02-22 11:31:32 -0800
committerJoshua Haberman <joshua@reverberate.org>2011-02-22 11:31:32 -0800
commit6b574175dd43735a26f171de6b34c3f15bb50f12 (patch)
tree65c221be25cefb9d54c78e12e0ff641346bd272b /src/upb_msg.h
parentfd184f0df2e5e428873eadfaf1ae829d2e4d8e51 (diff)
Prevent the default message from getting mutated.
If a Lua program references the default message, it will be copied into a mutable object.
Diffstat (limited to 'src/upb_msg.h')
-rw-r--r--src/upb_msg.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/upb_msg.h b/src/upb_msg.h
index ff8489c..468af24 100644
--- a/src/upb_msg.h
+++ b/src/upb_msg.h
@@ -10,6 +10,8 @@
*
* 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).
+ *
+ * TODO: consider properly supporting const instances.
*/
#ifndef UPB_MSG_H
@@ -204,12 +206,16 @@ upb_msg *upb_msg_new(upb_msgdef *md);
INLINE void upb_msg_unref(upb_msg *msg, upb_msgdef *md) {
if (msg && upb_atomic_unref(&msg->refcount)) _upb_msg_free(msg, md);
}
+
INLINE upb_msg *upb_msg_getref(upb_msg *msg) {
assert(msg);
upb_atomic_ref(&msg->refcount);
return msg;
}
+// Modifies *msg to point to a newly initialized msg instance. If the msg had
+// no other referents, reuses the same msg, otherwise allocates a new one.
+// The caller *must* own a ref on the msg prior to calling this method!
void upb_msg_recycle(upb_msg **msg, upb_msgdef *msgdef);
// Tests whether the given field is explicitly set, or whether it will return a
@@ -240,9 +246,17 @@ INLINE bool upb_msg_has(upb_msg *msg, upb_fielddef *f) {
//
// For the moment we go with (2). Google's protobuf does (3), which is likely
// part of the reason we beat it in some benchmarks.
+//
+// If the branchiness of (2) is too great, this could be mitigated with cmov
+// (both values and the conditional are cheap to calculate, much cheaper than
+// the cost of a misprediction).
// For submessages and strings, the returned value is not owned.
-INLINE upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) {
+upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f);
+
+// A specialized version of the previous that is cheaper because it doesn't
+// support submessages or arrays.
+INLINE upb_value upb_msg_getscalar(upb_msg *msg, upb_fielddef *f) {
if (upb_msg_has(msg, f)) {
return upb_value_read(_upb_msg_getptr(msg, f), upb_field_valuetype(f));
} else {
@@ -250,6 +264,9 @@ INLINE upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) {
}
}
+// Sets the given field to the given value. If the field is a string, array,
+// or submessage, releases the ref on any object we may have been referencing
+// and takes a ref on the new object (if any).
void upb_msg_set(upb_msg *msg, upb_fielddef *f, upb_value val);
// Unsets all field values back to their defaults.
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback