diff options
author | Joshua Haberman <joshua@reverberate.org> | 2011-02-22 11:31:32 -0800 |
---|---|---|
committer | Joshua Haberman <joshua@reverberate.org> | 2011-02-22 11:31:32 -0800 |
commit | 6b574175dd43735a26f171de6b34c3f15bb50f12 (patch) | |
tree | 65c221be25cefb9d54c78e12e0ff641346bd272b /src/upb_msg.c | |
parent | fd184f0df2e5e428873eadfaf1ae829d2e4d8e51 (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.c')
-rw-r--r-- | src/upb_msg.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/upb_msg.c b/src/upb_msg.c index 211004c..27170f5 100644 --- a/src/upb_msg.c +++ b/src/upb_msg.c @@ -161,6 +161,26 @@ void upb_msg_set(upb_msg *msg, upb_fielddef *f, upb_value val) { return upb_value_write(ptr, val, upb_field_valuetype(f)); } +upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) { + if (!upb_msg_has(msg, f)) { + upb_value val = f->default_value; + if (upb_issubmsg(f)) { + // TODO: handle arrays also, which must be treated similarly. + upb_msgdef *md = upb_downcast_msgdef(f->def); + upb_msg *m = upb_msg_new(md); + // Copy all set bits and values, except the refcount. + memcpy(m , upb_value_getmsg(val), md->size); + upb_atomic_refcount_init(&m->refcount, 0); // The msg will take a ref. + upb_value_setmsg(&val, m); + } + upb_msg_set(msg, f, val); + return val; + } else { + return upb_value_read(_upb_msg_getptr(msg, f), upb_field_valuetype(f)); + } +} + + static upb_valueptr upb_msg_getappendptr(upb_msg *msg, upb_fielddef *f) { upb_valueptr p = _upb_msg_getptr(msg, f); if (upb_isarray(f)) { |