summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/upb.h16
-rw-r--r--src/upb_data.c77
-rw-r--r--src/upb_data.h103
-rw-r--r--src/upb_def.c39
-rw-r--r--src/upb_text.c2
-rw-r--r--tools/upbc.c53
6 files changed, 168 insertions, 122 deletions
diff --git a/src/upb.h b/src/upb.h
index 2809418..2c0a23d 100644
--- a/src/upb.h
+++ b/src/upb.h
@@ -125,11 +125,10 @@ struct upb_tag {
// INTERNAL-ONLY: never refer to these types with a tag ("union", "struct").
// Always use the typedefs.
-union _upb_array;
struct _upb_msg;
-typedef union _upb_array upb_array;
typedef struct _upb_msg upb_msg;
+
typedef upb_atomic_refcount_t upb_data;
typedef uint32_t upb_strlen_t;
@@ -143,6 +142,15 @@ typedef union {
upb_data *base;
} upb_strptr;
+typedef uint32_t upb_arraylen_t;
+
+typedef union {
+ // Must be first, for the UPB_STATIC_ARRAY_PTR_INIT() macro.
+ struct upb_norefcount_array *norefcount;
+ struct upb_refcounted_array *refcounted;
+ upb_data *base;
+} upb_arrayptr;
+
// A single .proto value. The owner must have an out-of-band way of knowing
// the type, so that it knows which union member to use.
union upb_value {
@@ -154,7 +162,7 @@ union upb_value {
uint64_t uint64;
bool _bool;
upb_strptr str;
- upb_array *arr;
+ upb_arrayptr arr;
upb_msg *msg;
upb_data *data;
};
@@ -171,7 +179,7 @@ union upb_value_ptr {
uint64_t *uint64;
bool *_bool;
upb_strptr *str;
- upb_array **arr;
+ upb_arrayptr *arr;
upb_msg **msg;
upb_data **data;
void *_void;
diff --git a/src/upb_data.c b/src/upb_data.c
index 58aee8a..a0a588a 100644
--- a/src/upb_data.c
+++ b/src/upb_data.c
@@ -57,11 +57,11 @@ static void check_not_frozen(upb_data *d) {
/* upb_string *******************************************************************/
-static char *_upb_string_setptr(upb_strptr s, char *ptr) {
+void _upb_string_setptr(upb_strptr s, char *ptr) {
if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED))
- return s.refcounted->ptr = ptr;
+ s.refcounted->ptr = ptr;
else
- return s.norefcount->ptr = ptr;
+ s.norefcount->ptr = ptr;
}
static void _upb_string_set_bytelen(upb_strptr s, upb_strlen_t newlen) {
@@ -182,64 +182,79 @@ int upb_strcmp(upb_strptr s1, upb_strptr s2) {
/* upb_array ******************************************************************/
-upb_array *upb_array_new() {
- upb_array *a = malloc(sizeof(upb_refcounted_array));
- data_init(&a->common.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
- a->refcounted.size = 0;
- a->common.len = 0;
- a->common.elements._void = NULL;
+static void _upb_array_setptr(upb_arrayptr a, void *ptr) {
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED))
+ a.refcounted->elements._void = ptr;
+ else
+ a.norefcount->elements._void = ptr;
+}
+
+static void _upb_array_setlen(upb_arrayptr a, upb_strlen_t newlen) {
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED)) {
+ a.refcounted->len = newlen;
+ } else {
+ a.norefcount->len = newlen;
+ }
+}
+
+upb_arrayptr upb_array_new() {
+ upb_arrayptr a;
+ a.refcounted = malloc(sizeof(struct upb_refcounted_array));
+ data_init(a.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
+ a.refcounted->size = 0;
+ a.refcounted->len = 0;
+ a.refcounted->elements._void = NULL;
return a;
}
// ONLY handles refcounted arrays for the moment.
-void _upb_array_free(upb_array *a, struct upb_fielddef *f)
+void _upb_array_free(upb_arrayptr a, struct upb_fielddef *f)
{
if(upb_elem_ismm(f)) {
- for(upb_arraylen_t i = 0; i < a->refcounted.size; i++) {
+ for(upb_arraylen_t i = 0; i < a.refcounted->size; i++) {
union upb_value_ptr p = _upb_array_getptr(a, f, i);
if(!*p.data) continue;
data_elem_unref(p, f);
}
}
- if(a->refcounted.size != 0) free(a->common.elements._void);
- free(a);
+ if(a.refcounted->size != 0) free(a.refcounted->elements._void);
+ free(a.refcounted);
}
-static upb_arraylen_t array_get_size(upb_array *a) {
- if(upb_data_hasflag(&a->common.base, UPB_DATA_REFCOUNTED)) {
- return a->refcounted.size;
+static upb_arraylen_t array_get_size(upb_arrayptr a) {
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED)) {
+ return a.refcounted->size;
} else {
- return (a->norefcount.size_and_flags & 0xFFFFFFF8) >> 3;
+ return (a.norefcount->base.v & 0xFFFFFFF8) >> 3;
}
}
-static void array_set_size(upb_array *a, upb_arraylen_t newsize) {
- if(upb_data_hasflag(&a->common.base, UPB_DATA_REFCOUNTED)) {
- a->refcounted.size = newsize;
+static void array_set_size(upb_arrayptr a, upb_arraylen_t newsize) {
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED)) {
+ a.refcounted->size = newsize;
} else {
- a->norefcount.size_and_flags &= 0x7;
- a->norefcount.size_and_flags |= (newsize << 3);
+ a.norefcount->base.v &= 0x7;
+ a.norefcount->base.v |= (newsize << 3);
}
}
-void upb_array_resize(upb_array *a, struct upb_fielddef *f, upb_strlen_t len) {
- check_not_frozen(&a->common.base);
+void upb_array_resize(upb_arrayptr a, struct upb_fielddef *f, upb_strlen_t len) {
+ check_not_frozen(a.base);
size_t type_size = upb_type_info[f->type].size;
upb_arraylen_t old_size = array_get_size(a);
if(old_size < len) {
// Need to resize.
size_t new_size = round_up_to_pow2(len);
- a->common.elements._void = realloc(a->common.elements._void, new_size * type_size);
+ _upb_array_setptr(a, realloc(_upb_array_getptr_raw(a, 0, 0)._void, new_size * type_size));
array_set_size(a, new_size);
- memset(UPB_INDEX(a->common.elements._void, old_size, type_size),
+ memset(_upb_array_getptr_raw(a, old_size, type_size)._void,
0,
(new_size - old_size) * type_size);
}
- a->common.len = len;
+ _upb_array_setlen(a, len);
}
-
/* upb_msg ********************************************************************/
static void upb_msg_sethas(upb_msg *msg, struct upb_fielddef *f) {
@@ -289,15 +304,15 @@ static union upb_value_ptr get_value_ptr(upb_msg *msg, struct upb_fielddef *f)
union upb_value_ptr p = _upb_msg_getptr(msg, f);
if(upb_isarray(f)) {
if(!upb_msg_has(msg, f)) {
- if(!*p.arr || !upb_data_only(*p.data)) {
- if(*p.arr)
+ if(upb_array_isnull(*p.arr) || !upb_data_only(*p.data)) {
+ if(!upb_array_isnull(*p.arr))
upb_array_unref(*p.arr, f);
*p.arr = upb_array_new();
}
upb_array_truncate(*p.arr);
upb_msg_sethas(msg, f);
} else {
- assert(*p.arr);
+ assert(!upb_array_isnull(*p.arr));
}
upb_arraylen_t oldlen = upb_array_len(*p.arr);
upb_array_resize(*p.arr, f, oldlen + 1);
diff --git a/src/upb_data.h b/src/upb_data.h
index 88ca9af..7e24d7e 100644
--- a/src/upb_data.h
+++ b/src/upb_data.h
@@ -209,9 +209,7 @@ upb_strptr upb_string_getref(upb_strptr s, int ref_flags);
#define UPB_STRING_NULL_INITIALIZER {NULL}
static const upb_strptr UPB_STRING_NULL = UPB_STRING_NULL_INITIALIZER;
-INLINE bool upb_string_isnull(upb_strptr s) {
- return s.base == NULL;
-}
+INLINE bool upb_string_isnull(upb_strptr s) { return s.base == NULL; }
// The caller releases a ref on src, which it must previously have owned a ref
// on.
@@ -339,69 +337,77 @@ typedef struct upb_norefcount_string upb_static_string;
/* upb_array ******************************************************************/
-typedef uint32_t upb_arraylen_t;
-
// The comments attached to upb_string above also apply here.
-typedef struct {
- upb_data base;
- upb_arraylen_t len;
- union upb_value_ptr elements;
-} upb_array_common;
-
-typedef struct {
- uint32_t size_and_flags;
+struct upb_norefcount_array {
+ upb_data base; // We co-opt the refcount for the size.
upb_arraylen_t len;
union upb_value_ptr elements;
-} upb_norefcount_array;
+};
-typedef struct {
+struct upb_refcounted_array {
upb_data base;
upb_arraylen_t len;
union upb_value_ptr elements;
upb_arraylen_t size;
-} upb_refcounted_array;
-
-union _upb_array {
- upb_norefcount_array norefcount;
- upb_array_common common;
- upb_refcounted_array refcounted;
};
-// This type can be used either to perform read-only access on an array,
-// or to statically define a non-reference-counted static array.
-#define UPB_DEFINE_MSG_ARRAY(type) \
-typedef struct type ## _array { \
- upb_data base; \
- upb_arraylen_t len;\
- type **elements; \
-} type ## _array; \
+typedef struct upb_norefcount_array upb_static_array;
+#define UPB_STATIC_ARRAY_INIT(arr, len) {{0 | UPB_DATA_FROZEN}, len, {._void=arr}}
+#define UPB_STATIC_ARRAY_PTR_TYPED_INIT(static_arr) {{&static_arr}}
+
+#define UPB_ARRAY_NULL_INITIALIZER {NULL}
+static const upb_arrayptr UPB_ARRAY_NULL = UPB_ARRAY_NULL_INITIALIZER;
+INLINE bool upb_array_isnull(upb_arrayptr a) { return a.base == NULL; }
+INLINE bool upb_array_ptreql(upb_arrayptr a1, upb_arrayptr a2) {
+ return a1.base == a2.base;
+}
-#define UPB_MSG_ARRAY(type) struct type ## _array
+#define UPB_MSG_ARRAYPTR(type) type ## _array
+#define UPB_DEFINE_MSG_ARRAY(type) \
+typedef struct { upb_arrayptr ptr; } UPB_MSG_ARRAYPTR(type); \
+INLINE upb_arraylen_t type ## _array_len(UPB_MSG_ARRAYPTR(type) a) { \
+ return upb_array_len(a.ptr); \
+} \
+INLINE type* type ## _array_get(UPB_MSG_ARRAYPTR(type) a, upb_arraylen_t elem) { \
+ return *(type**)_upb_array_getptr_raw(a.ptr, elem, sizeof(void*))._void; \
+}
// Constructs a newly-allocated, reference-counted array which starts out
// empty. Caller owns one ref on it.
-upb_array *upb_array_new(void);
+upb_arrayptr upb_array_new(void);
// Returns the current number of elements in the array.
-INLINE size_t upb_array_len(upb_array *a) {
- return a->common.len;
+INLINE size_t upb_array_len(upb_arrayptr a) {
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED))
+ return a.refcounted->len;
+ else
+ return a.norefcount->len;
}
// INTERNAL-ONLY:
// Frees the given message and releases references on members.
-void _upb_array_free(upb_array *a, struct upb_fielddef *f);
+void _upb_array_free(upb_arrayptr a, struct upb_fielddef *f);
// INTERNAL-ONLY:
// Returns a pointer to the given elem.
-INLINE union upb_value_ptr _upb_array_getptr(upb_array *a,
+INLINE union upb_value_ptr _upb_array_getptr_raw(upb_arrayptr a,
+ upb_arraylen_t elem,
+ size_t type_size) {
+ union upb_value_ptr p;
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED))
+ p._void = &a.refcounted->elements.uint8[elem * type_size];
+ else
+ p._void = &a.norefcount->elements.uint8[elem * type_size];
+ return p;
+}
+
+INLINE union upb_value_ptr _upb_array_getptr(upb_arrayptr a,
struct upb_fielddef *f,
upb_arraylen_t elem) {
- size_t type_size = upb_type_info[f->type].size;
- union upb_value_ptr p = {._void = &a->common.elements.uint8[elem * type_size]};
- return p;
+ return _upb_array_getptr_raw(a, elem, upb_type_info[f->type].size);
}
-INLINE union upb_value upb_array_get(upb_array *a, struct upb_fielddef *f,
+INLINE union upb_value upb_array_get(upb_arrayptr a, struct upb_fielddef *f,
upb_arraylen_t elem) {
assert(elem < upb_array_len(a));
return upb_value_read(_upb_array_getptr(a, f, elem), f->type);
@@ -409,33 +415,36 @@ INLINE union upb_value upb_array_get(upb_array *a, struct upb_fielddef *f,
// The caller releases a ref on the given array, which it must previously have
// owned a ref on.
-INLINE void upb_array_unref(upb_array *a, struct upb_fielddef *f) {
- if(_upb_data_unref(&a->common.base)) _upb_array_free(a, f);
+INLINE void upb_array_unref(upb_arrayptr a, struct upb_fielddef *f) {
+ if(_upb_data_unref(a.base)) _upb_array_free(a, f);
}
#if 0
// Returns an array to which caller owns a ref, and contains the same contents
// as src. The returned value may be a copy of src, if the requested flags
// were incompatible with src's.
-INLINE upb_array *upb_array_getref(upb_array *src, int ref_flags);
+INLINE upb_arrayptr upb_array_getref(upb_arrayptr src, int ref_flags);
// Sets the given element in the array to val. The current length of the array
// must be greater than elem. If the field type is dynamic, the array will
// take a ref on val and release a ref on what was previously in the array.
-INLINE void upb_array_set(upb_array *a, struct upb_fielddef *f, int elem,
+INLINE void upb_array_set(upb_arrayptr a, struct upb_fielddef *f, int elem,
union upb_value val);
// Note that array_append will attempt to take a reference on the given value,
// so to avoid a copy use append_default and get.
-INLINE void upb_array_append(upb_array *a, struct upb_fielddef *f,
+INLINE void upb_array_append(upb_arrayptr a, struct upb_fielddef *f,
union upb_value val);
-INLINE void upb_array_append_default(upb_array *a, struct upb_fielddef *f,
+INLINE void upb_array_append_default(upb_arrayptr a, struct upb_fielddef *f,
union upb_value val);
#endif
-INLINE void upb_array_truncate(upb_array *a) {
- a->common.len = 0;
+INLINE void upb_array_truncate(upb_arrayptr a) {
+ if(upb_data_hasflag(a.base, UPB_DATA_REFCOUNTED))
+ a.refcounted->len = 0;
+ else
+ a.norefcount->len = 0;
}
diff --git a/src/upb_def.c b/src/upb_def.c
index 4f57407..24a57a6 100644
--- a/src/upb_def.c
+++ b/src/upb_def.c
@@ -364,12 +364,14 @@ static struct upb_enumdef *enumdef_new(google_protobuf_EnumDescriptorProto *ed,
{
struct upb_enumdef *e = malloc(sizeof(*e));
upb_def_init(&e->base, UPB_DEF_ENUM, fqname);
- int num_values = ed->set_flags.has.value ? ed->value->len : 0;
+ int num_values = ed->set_flags.has.value ?
+ google_protobuf_EnumValueDescriptorProto_array_len(ed->value) : 0;
upb_strtable_init(&e->ntoi, num_values, sizeof(struct ntoi_ent));
upb_inttable_init(&e->iton, num_values, sizeof(struct iton_ent));
for(int i = 0; i < num_values; i++) {
- google_protobuf_EnumValueDescriptorProto *value = ed->value->elements[i];
+ google_protobuf_EnumValueDescriptorProto *value =
+ google_protobuf_EnumValueDescriptorProto_array_get(ed->value, i);
struct ntoi_ent ntoi_ent = {{value->name, 0}, value->number};
struct iton_ent iton_ent = {{value->number, 0}, value->name};
upb_strtable_insert(&e->ntoi, &ntoi_ent.e);
@@ -521,20 +523,22 @@ static void insert_message(struct upb_strtable *t,
upb_strptr fqname = try_define(t, base, name, status);
if(upb_string_isnull(fqname)) return;
- int num_fields = d->set_flags.has.field ? d->field->len : 0;
+ int num_fields = d->set_flags.has.field ?
+ google_protobuf_FieldDescriptorProto_array_len(d->field) : 0;
struct symtab_ent e;
e.e.key = fqname;
// Gather our list of fields, sorting if necessary.
struct upb_fielddef **fielddefs = malloc(sizeof(*fielddefs) * num_fields);
for (int i = 0; i < num_fields; i++) {
- google_protobuf_FieldDescriptorProto *fd = d->field->elements[i];
+ google_protobuf_FieldDescriptorProto *fd =
+ google_protobuf_FieldDescriptorProto_array_get(d->field, i);
fielddefs[i] = fielddef_new(fd);
}
- if(sort) fielddef_sort(fielddefs, d->field->len);
+ if(sort) fielddef_sort(fielddefs, num_fields);
// Create the msgdef with that list of fields.
- e.def = UPB_UPCAST(msgdef_new(fielddefs, d->field->len, fqname, status));
+ e.def = UPB_UPCAST(msgdef_new(fielddefs, num_fields, fqname, status));
// Cleanup.
for (int i = 0; i < num_fields; i++) fielddef_free(fielddefs[i]);
@@ -546,12 +550,12 @@ static void insert_message(struct upb_strtable *t,
/* Add nested messages and enums. */
if(d->set_flags.has.nested_type)
- for(unsigned int i = 0; i < d->nested_type->len; i++)
- insert_message(t, d->nested_type->elements[i], fqname, sort, status);
+ for(unsigned int i = 0; i < google_protobuf_DescriptorProto_array_len(d->nested_type); i++)
+ insert_message(t, google_protobuf_DescriptorProto_array_get(d->nested_type, i), fqname, sort, status);
if(d->set_flags.has.enum_type)
- for(unsigned int i = 0; i < d->enum_type->len; i++)
- insert_enum(t, d->enum_type->elements[i], fqname, status);
+ for(unsigned int i = 0; i < google_protobuf_EnumDescriptorProto_array_len(d->enum_type); i++)
+ insert_enum(t, google_protobuf_EnumDescriptorProto_array_get(d->enum_type, i), fqname, status);
error:
// Free the ref we got from try_define().
@@ -618,12 +622,12 @@ static void addfd(struct upb_strtable *addto, struct upb_strtable *existingdefs,
}
if(fd->set_flags.has.message_type)
- for(unsigned int i = 0; i < fd->message_type->len; i++)
- insert_message(addto, fd->message_type->elements[i], pkg, sort, status);
+ for(unsigned int i = 0; i < google_protobuf_DescriptorProto_array_len(fd->message_type); i++)
+ insert_message(addto, google_protobuf_DescriptorProto_array_get(fd->message_type, i), pkg, sort, status);
if(fd->set_flags.has.enum_type)
- for(unsigned int i = 0; i < fd->enum_type->len; i++)
- insert_enum(addto, fd->enum_type->elements[i], pkg, status);
+ for(unsigned int i = 0; i < google_protobuf_EnumDescriptorProto_array_len(fd->enum_type); i++)
+ insert_enum(addto, google_protobuf_EnumDescriptorProto_array_get(fd->enum_type, i), pkg, status);
upb_string_unref(pkg);
@@ -686,8 +690,9 @@ struct upb_symtab *upb_symtab_new()
upb_strtable_init(&s->psymtab, 16, sizeof(struct symtab_ent));
// Add descriptor.proto types to private symtable so we can parse descriptors.
+ // We know there is only 1.
google_protobuf_FileDescriptorProto *fd =
- upb_file_descriptor_set->file->elements[0]; // We know there is only 1.
+ google_protobuf_FileDescriptorProto_array_get(upb_file_descriptor_set->file, 0);
struct upb_status status = UPB_STATUS_INIT;
addfd(&s->psymtab, &s->symtab, fd, false, &status);
if(!upb_ok(&status)) {
@@ -782,8 +787,8 @@ void upb_symtab_addfds(struct upb_symtab *s,
{ // Read lock scope
upb_rwlock_rdlock(&s->lock);
- for(uint32_t i = 0; i < fds->file->len; i++) {
- addfd(&tmp, &s->symtab, fds->file->elements[i], true, status);
+ for(uint32_t i = 0; i < google_protobuf_FileDescriptorProto_array_len(fds->file); i++) {
+ addfd(&tmp, &s->symtab, google_protobuf_FileDescriptorProto_array_get(fds->file, i), true, status);
if(!upb_ok(status)) {
free_symtab(&tmp);
upb_rwlock_unlock(&s->lock);
diff --git a/src/upb_text.c b/src/upb_text.c
index 225b344..3981715 100644
--- a/src/upb_text.c
+++ b/src/upb_text.c
@@ -92,7 +92,7 @@ static void printmsg(struct upb_text_printer *printer,
if(!upb_msg_has(msg, f)) continue;
union upb_value v = upb_msg_get(msg, f);
if(upb_isarray(f)) {
- upb_array *arr = v.arr;
+ upb_arrayptr arr = v.arr;
for(uint32_t j = 0; j < upb_array_len(arr); j++) {
union upb_value elem = upb_array_get(arr, f, j);
printval(printer, elem, f, stream);
diff --git a/tools/upbc.c b/tools/upbc.c
index b1fd0d9..1341800 100644
--- a/tools/upbc.c
+++ b/tools/upbc.c
@@ -158,8 +158,10 @@ static void write_h(struct upb_def *defs[], int num_defs, char *outfile_name,
upb_strptr msg_name = upb_strdup(UPB_UPCAST(m)->fqname);
to_cident(msg_name);
fprintf(stream, "struct " UPB_STRFMT ";\n", UPB_STRARG(msg_name));
- fprintf(stream, "typedef struct " UPB_STRFMT "\n " UPB_STRFMT ";\n\n",
+ fprintf(stream, "typedef struct " UPB_STRFMT "\n " UPB_STRFMT ";\n",
UPB_STRARG(msg_name), UPB_STRARG(msg_name));
+ fprintf(stream, "UPB_DEFINE_MSG_ARRAY(" UPB_STRFMT ")\n\n",
+ UPB_STRARG(msg_name));
upb_string_unref(msg_name);
}
@@ -189,7 +191,7 @@ static void write_h(struct upb_def *defs[], int num_defs, char *outfile_name,
upb_strptr type_name = upb_strdup(f->def->fqname);
to_cident(type_name);
if(f->label == UPB_LABEL(REPEATED)) {
- fprintf(stream, " UPB_MSG_ARRAY(" UPB_STRFMT ")* " UPB_STRFMT ";\n",
+ fprintf(stream, " UPB_MSG_ARRAYPTR(" UPB_STRFMT ") " UPB_STRFMT ";\n",
UPB_STRARG(type_name), UPB_STRARG(f->name));
} else {
fprintf(stream, " " UPB_STRFMT "* " UPB_STRFMT ";\n",
@@ -197,7 +199,7 @@ static void write_h(struct upb_def *defs[], int num_defs, char *outfile_name,
}
upb_string_unref(type_name);
} else if(f->label == UPB_LABEL(REPEATED)) {
- fprintf(stream, " upb_array* " UPB_STRFMT ";\n", UPB_STRARG(f->name));
+ fprintf(stream, " upb_arrayptr " UPB_STRFMT ";\n", UPB_STRARG(f->name));
} else {
static char* c_types[] = {
"", "double", "float", "int64_t", "uint64_t", "int32_t", "uint64_t",
@@ -209,9 +211,7 @@ static void write_h(struct upb_def *defs[], int num_defs, char *outfile_name,
c_types[f->type], UPB_STRARG(f->name));
}
}
- fputs("};\n", stream);
- fprintf(stream, "UPB_DEFINE_MSG_ARRAY(" UPB_STRFMT ")\n\n",
- UPB_STRARG(msg_name));
+ fputs("};\n\n", stream);
upb_string_unref(msg_name);
}
@@ -241,7 +241,7 @@ struct typetable_entry {
struct array {
int offset;
int len;
- upb_array *ptr; /* So we can find it later. */
+ upb_arrayptr ptr; /* So we can find it later. */
} *arrays;
int arrays_size, arrays_len;
};
@@ -287,7 +287,7 @@ static void add_strings_from_msg(upb_msg *msg, struct upb_msgdef *md,
if(!upb_msg_has(msg, f)) continue;
union upb_value p = upb_msg_get(msg, f);
if(upb_isarray(f)) {
- upb_array *arr = p.arr;
+ upb_arrayptr arr = p.arr;
for(uint32_t j = 0; j < upb_array_len(arr); j++)
add_strings_from_value(upb_array_get(arr, f, j), f, t);
} else {
@@ -345,7 +345,7 @@ static void add_submsgs(upb_msg *msg, struct upb_msgdef *md,
union upb_value v = upb_msg_get(msg, f);
if(upb_isarray(f)) {
if(upb_isstring(f)) continue; /* Handled by a different code-path. */
- upb_array *arr = v.arr;
+ upb_arrayptr arr = v.arr;
/* Add to our list of arrays for this type. */
struct typetable_entry *arr_type_e =
@@ -475,11 +475,11 @@ static void write_message_c(upb_msg *msg, struct upb_msgdef *md,
fprintf(stream, "};\n");
int cum_offset = 0;
- fprintf(stream, "static UPB_MSG_ARRAY(" UPB_STRFMT ") " UPB_STRFMT "_arrays[%d] = {\n",
- UPB_STRARG(e->cident), UPB_STRARG(e->cident), e->arrays_len);
+ fprintf(stream, "static upb_static_array " UPB_STRFMT "_arrays[%d] = {\n",
+ UPB_STRARG(e->cident), e->arrays_len);
for(int i = 0; i < e->arrays_len; i++) {
struct array *arr = &e->arrays[i];
- fprintf(stream, " {.elements = &" UPB_STRFMT "_array_elems[%d], .len=%d},\n",
+ fprintf(stream, " UPB_STATIC_ARRAY_INIT(&" UPB_STRFMT "_array_elems[%d], %d),\n",
UPB_STRARG(e->cident), cum_offset, arr->len);
cum_offset += arr->len;
}
@@ -515,7 +515,12 @@ static void write_message_c(upb_msg *msg, struct upb_msgdef *md,
union upb_value val = upb_msg_get(msgdata, f);
fprintf(stream, " ." UPB_STRFMT " = ", UPB_STRARG(f->name));
if(!upb_msg_has(msgdata, f)) {
- if(upb_isstring(f) && !upb_isarray(f)) {
+ if(upb_isarray(f) && upb_issubmsg(f)) {
+ // This is gross and needs cleanup.
+ fputs("{UPB_ARRAY_NULL_INITIALIZER}, /* Not set. */", stream);
+ } else if(upb_isarray(f)) {
+ fputs("UPB_ARRAY_NULL_INITIALIZER, /* Not set. */", stream);
+ } else if(upb_isstring(f)) {
fputs("UPB_STRING_NULL_INITIALIZER, /* Not set. */", stream);
} else {
fputs("0, /* Not set. */", stream);
@@ -536,13 +541,13 @@ static void write_message_c(upb_msg *msg, struct upb_msgdef *md,
assert(type_e);
int arr_num = -1;
for(int k = 0; k < type_e->arrays_len; k++) {
- if(type_e->arrays[k].ptr == val.arr) {
+ if(upb_array_ptreql(type_e->arrays[k].ptr, val.arr)) {
arr_num = k;
break;
}
}
assert(arr_num != -1);
- fprintf(stream, "&" UPB_STRFMT "_arrays[%d],", UPB_STRARG(type_e->cident), arr_num);
+ fprintf(stream, "UPB_STATIC_ARRAY_PTR_TYPED_INIT(" UPB_STRFMT "_arrays[%d]),", UPB_STRARG(type_e->cident), arr_num);
} else if(upb_issubmsg(f)) {
/* Find this submessage in the list of msgs for that type. */
struct typetable_entry *type_e = get_or_insert_typeentry(&types, f);
@@ -625,10 +630,14 @@ void error(char *err, ...)
void sort_fields_in_descriptor(google_protobuf_DescriptorProto *d)
{
- if(d->set_flags.has.field) upb_fielddef_sortfds(d->field->elements, d->field->len);
+ // XXX: modifying the array in place is totally not allowed.
+ if(d->set_flags.has.field) {
+ upb_fielddef_sortfds(_upb_array_getptr_raw(d->field.ptr, 0, 0)._void,
+ google_protobuf_FieldDescriptorProto_array_len(d->field));
+ }
if(d->set_flags.has.nested_type)
- for(uint32_t i = 0; i < d->nested_type->len; i++)
- sort_fields_in_descriptor(d->nested_type->elements[i]);
+ for(uint32_t i = 0; i < google_protobuf_DescriptorProto_array_len(d->nested_type); i++)
+ sort_fields_in_descriptor(google_protobuf_DescriptorProto_array_get(d->nested_type, i));
}
int main(int argc, char *argv[])
@@ -686,11 +695,11 @@ int main(int argc, char *argv[])
// this scheme.
//
// If/when we ever make upbc more general, we'll have to revisit this.
- for(uint32_t i = 0; i < fds->file->len; i++) {
- google_protobuf_FileDescriptorProto *fd = fds->file->elements[i];
+ for(uint32_t i = 0; i < google_protobuf_FileDescriptorProto_array_len(fds->file); i++) {
+ google_protobuf_FileDescriptorProto *fd = google_protobuf_FileDescriptorProto_array_get(fds->file, i);
if(!fd->set_flags.has.message_type) continue;
- for(uint32_t j = 0; j < fd->message_type->len; j++)
- sort_fields_in_descriptor(fd->message_type->elements[j]);
+ for(uint32_t j = 0; j < google_protobuf_DescriptorProto_array_len(fd->message_type); j++)
+ sort_fields_in_descriptor(google_protobuf_DescriptorProto_array_get(fd->message_type, j));
}
/* Emit output files. */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback