diff options
Diffstat (limited to 'upb')
-rw-r--r-- | upb/msg.c | 91 | ||||
-rw-r--r-- | upb/msg.h | 25 | ||||
-rw-r--r-- | upb/pb/glue.c | 2 |
3 files changed, 62 insertions, 56 deletions
@@ -278,58 +278,40 @@ NEXTFUNC(8) NEXTFUNC(4) NEXTFUNC(1) -#define STDMSG(type) { static upb_accessor_vtbl vtbl = {NULL, &upb_stdmsg_startsubmsg, \ - &upb_stdmsg_set ## type, &upb_stdmsg_has, &upb_stdmsg_get ## type, \ - NULL, NULL, NULL}; return &vtbl; } -#define STDMSG_R(type, size) { static upb_accessor_vtbl vtbl = { \ - &upb_stdmsg_startseq, &upb_stdmsg_startsubmsg_r, &upb_stdmsg_set ## type ## _r, \ - &upb_stdmsg_has, &upb_stdmsg_getptr, &upb_stdmsg_seqbegin, \ - &upb_stdmsg_ ## size ## byte_seqnext, &upb_stdmsg_seqget ## type}; \ +#define STDMSG(type, size) { static upb_accessor_vtbl vtbl = { \ + &upb_stdmsg_startsubmsg, \ + &upb_stdmsg_set ## type, \ + &upb_stdmsg_startseq, \ + &upb_stdmsg_startsubmsg_r, \ + &upb_stdmsg_set ## type ## _r, \ + &upb_stdmsg_has, \ + &upb_stdmsg_getptr, \ + &upb_stdmsg_get ## type, \ + &upb_stdmsg_seqbegin, \ + &upb_stdmsg_ ## size ## byte_seqnext, \ + &upb_stdmsg_seqget ## type}; \ return &vtbl; } upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f) { - if (upb_isseq(f)) { - switch (f->type) { - case UPB_TYPE(DOUBLE): STDMSG_R(double, 8) - case UPB_TYPE(FLOAT): STDMSG_R(float, 4) - case UPB_TYPE(UINT64): - case UPB_TYPE(FIXED64): STDMSG_R(uint64, 8) - case UPB_TYPE(INT64): - case UPB_TYPE(SFIXED64): - case UPB_TYPE(SINT64): STDMSG_R(int64, 8) - case UPB_TYPE(INT32): - case UPB_TYPE(SINT32): - case UPB_TYPE(ENUM): - case UPB_TYPE(SFIXED32): STDMSG_R(int32, 4) - case UPB_TYPE(UINT32): - case UPB_TYPE(FIXED32): STDMSG_R(uint32, 4) - case UPB_TYPE(BOOL): STDMSG_R(bool, 1) - case UPB_TYPE(STRING): - case UPB_TYPE(BYTES): - case UPB_TYPE(GROUP): - case UPB_TYPE(MESSAGE): STDMSG_R(str, 8) // TODO: 32-bit - } - } else { - switch (f->type) { - case UPB_TYPE(DOUBLE): STDMSG(double) - case UPB_TYPE(FLOAT): STDMSG(float) - case UPB_TYPE(UINT64): - case UPB_TYPE(FIXED64): STDMSG(uint64) - case UPB_TYPE(INT64): - case UPB_TYPE(SFIXED64): - case UPB_TYPE(SINT64): STDMSG(int64) - case UPB_TYPE(INT32): - case UPB_TYPE(SINT32): - case UPB_TYPE(ENUM): - case UPB_TYPE(SFIXED32): STDMSG(int32) - case UPB_TYPE(UINT32): - case UPB_TYPE(FIXED32): STDMSG(uint32) - case UPB_TYPE(BOOL): STDMSG(bool) - case UPB_TYPE(STRING): - case UPB_TYPE(BYTES): - case UPB_TYPE(GROUP): - case UPB_TYPE(MESSAGE): STDMSG(str) - } + switch (f->type) { + case UPB_TYPE(DOUBLE): STDMSG(double, 8) + case UPB_TYPE(FLOAT): STDMSG(float, 4) + case UPB_TYPE(UINT64): + case UPB_TYPE(FIXED64): STDMSG(uint64, 8) + case UPB_TYPE(INT64): + case UPB_TYPE(SFIXED64): + case UPB_TYPE(SINT64): STDMSG(int64, 8) + case UPB_TYPE(INT32): + case UPB_TYPE(SINT32): + case UPB_TYPE(ENUM): + case UPB_TYPE(SFIXED32): STDMSG(int32, 4) + case UPB_TYPE(UINT32): + case UPB_TYPE(FIXED32): STDMSG(uint32, 4) + case UPB_TYPE(BOOL): STDMSG(bool, 1) + case UPB_TYPE(STRING): + case UPB_TYPE(BYTES): + case UPB_TYPE(GROUP): + case UPB_TYPE(MESSAGE): STDMSG(str, 8) // TODO: 32-bit } return NULL; } @@ -337,10 +319,15 @@ upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f) { static void upb_accessors_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) { (void)c; if (f->accessor) { - upb_fhandlers_setstartseq(fh, f->accessor->appendseq); - upb_fhandlers_setvalue(fh, f->accessor->set); - upb_fhandlers_setstartsubmsg(fh, f->accessor->appendsubmsg); upb_fhandlers_setfval(fh, f->fval); + if (upb_isseq(f)) { + upb_fhandlers_setstartseq(fh, f->accessor->startseq); + upb_fhandlers_setvalue(fh, f->accessor->append); + upb_fhandlers_setstartsubmsg(fh, f->accessor->appendsubmsg); + } else { + upb_fhandlers_setvalue(fh, f->accessor->set); + upb_fhandlers_setstartsubmsg(fh, f->accessor->startsubmsg); + } } } @@ -51,12 +51,17 @@ INLINE bool upb_seq_done(void *iter) { return iter == NULL; } typedef struct _upb_accessor_vtbl { // Writers. These take an fval as a parameter because the callbacks are used // as upb_handlers, but the fval is always the fielddef for that field. - upb_startfield_handler *appendseq; // Repeated fields only. - upb_startfield_handler *appendsubmsg; // Submsg fields (repeated or no). - upb_value_handler *set; // Scalar fields (repeated or no). + upb_startfield_handler *startsubmsg; // Non-repeated submsg fields. + upb_value_handler *set; // Non-repeated scalar fields. + upb_startfield_handler *startseq; // Repeated fields only. + upb_startfield_handler *appendsubmsg; // Repeated submsg fields. + upb_value_handler *append; // Repeated scalar fields. + + // TODO: expect to also need endsubmsg and endseq. // Readers. upb_has_reader *has; + upb_value_reader *getseq; upb_value_reader *get; upb_seqbegin_handler *seqbegin; upb_seqnext_handler *seqnext; @@ -82,6 +87,10 @@ upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f); // defaults (but not strings, submessages, or arrays). void upb_msg_clear(void *msg, upb_msgdef *md); +INLINE void upb_msg_clearbit(void *msg, upb_fielddef *f) { + ((char*)msg)[f->hasbit / 8] &= ~(1 << (f->hasbit % 8)); +} + // Could add a method that recursively clears submessages, strings, and // arrays if desired. This could be a win if you wanted to merge without // needing hasbits, because during parsing you would never clear submessages @@ -94,10 +103,16 @@ INLINE bool upb_msg_has(void *m, upb_fielddef *f) { // May only be called for fields that have accessors. INLINE upb_value upb_msg_get(void *m, upb_fielddef *f) { - assert(f->accessor); + assert(f->accessor && !upb_isseq(f)); return f->accessor->get(m, f->fval); } +// May only be called for fields that have accessors. +INLINE upb_value upb_msg_getseq(void *m, upb_fielddef *f) { + assert(f->accessor && upb_isseq(f)); + return f->accessor->getseq(m, f->fval); +} + INLINE void upb_msg_set(void *m, upb_fielddef *f, upb_value val) { assert(f->accessor); f->accessor->set(m, f->fval, val); @@ -182,6 +197,7 @@ upb_flow_t upb_stdmsg_setuint32(void *c, upb_value fval, upb_value val); upb_flow_t upb_stdmsg_setdouble(void *c, upb_value fval, upb_value val); upb_flow_t upb_stdmsg_setfloat(void *c, upb_value fval, upb_value val); upb_flow_t upb_stdmsg_setbool(void *c, upb_value fval, upb_value val); +upb_flow_t upb_stdmsg_setptr(void *c, upb_value fval, upb_value val); // Value writers for repeated fields: the closure points to a standard array // struct, appends the value to the end of the array, resizing with realloc() @@ -199,6 +215,7 @@ upb_flow_t upb_stdmsg_setuint32_r(void *c, upb_value fval, upb_value val); upb_flow_t upb_stdmsg_setdouble_r(void *c, upb_value fval, upb_value val); upb_flow_t upb_stdmsg_setfloat_r(void *c, upb_value fval, upb_value val); upb_flow_t upb_stdmsg_setbool_r(void *c, upb_value fval, upb_value val); +upb_flow_t upb_stdmsg_setptr_r(void *c, upb_value fval, upb_value val); // Writers for C strings (NULL-terminated): we can find a char* at a known // offset from the closure "c". Calls realloc() on the pointer to allocate diff --git a/upb/pb/glue.c b/upb/pb/glue.c index dfd9e88..6b52435 100644 --- a/upb/pb/glue.c +++ b/upb/pb/glue.c @@ -89,6 +89,8 @@ void upb_read_descriptor(upb_symtab *symtab, const char *str, size_t len, if (upb_ok(status)) upb_symtab_add(symtab, defs, n, status); + for(int i = 0; i < n; i++) upb_def_unref(defs[i]); + upb_descreader_uninit(&r); upb_stringsrc_uninit(&strsrc); upb_decoder_uninit(&d); |