|
|
|
@ -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.
|
|
|
|
|