diff options
-rw-r--r-- | src/upb_data.c | 4 | ||||
-rw-r--r-- | src/upb_data.h | 21 | ||||
-rw-r--r-- | tests/test_table.cc | 19 | ||||
-rw-r--r-- | tests/test_vs_proto2.cc | 111 | ||||
-rw-r--r-- | tests/tests.c | 6 |
5 files changed, 93 insertions, 68 deletions
diff --git a/src/upb_data.c b/src/upb_data.c index 58aee8a..1bb76aa 100644 --- a/src/upb_data.c +++ b/src/upb_data.c @@ -290,13 +290,17 @@ static union upb_value_ptr get_value_ptr(upb_msg *msg, struct upb_fielddef *f) if(upb_isarray(f)) { if(!upb_msg_has(msg, f)) { if(!*p.arr || !upb_data_only(*p.data)) { + printf("Initializing array field " UPB_STRFMT "\n", UPB_STRARG(f->name)); if(*p.arr) upb_array_unref(*p.arr, f); *p.arr = upb_array_new(); + } else { + printf("REUSING array field " UPB_STRFMT "\n", UPB_STRARG(f->name)); } upb_array_truncate(*p.arr); upb_msg_sethas(msg, f); } else { + printf("APPENDING TO EXISTING array field " UPB_STRFMT "\n", UPB_STRARG(f->name)); assert(*p.arr); } upb_arraylen_t oldlen = upb_array_len(*p.arr); diff --git a/src/upb_data.h b/src/upb_data.h index 88ca9af..15e87c5 100644 --- a/src/upb_data.h +++ b/src/upb_data.h @@ -27,6 +27,10 @@ #include "upb_atomic.h" #include "upb_def.h" +#ifdef __cplusplus +extern "C" { +#endif + struct upb_msgdef; struct upb_fielddef; @@ -298,6 +302,13 @@ INLINE void upb_strcpyc(upb_strptr dest, const char *src) { // Returns a new string whose contents are a copy of s. upb_strptr upb_strdup(upb_strptr s); +// Like upb_strdup(), but duplicates a given buffer and length. +INLINE upb_strptr upb_strduplen(const void *src, upb_strlen_t len) { + upb_strptr s = upb_string_new(); + upb_strcpylen(s, src, len); + return s; +} + // Like upb_strdup(), but duplicates a C NULL-terminated string. upb_strptr upb_strdupc(const char *src); @@ -397,7 +408,8 @@ INLINE union upb_value_ptr _upb_array_getptr(upb_array *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]}; + union upb_value_ptr p; + p._void = &a->common.elements.uint8[elem * type_size]; return p; } @@ -459,7 +471,8 @@ void _upb_msg_free(upb_msg *msg, struct upb_msgdef *md); // INTERNAL-ONLY: // Returns a pointer to the given field. INLINE union upb_value_ptr _upb_msg_getptr(upb_msg *msg, struct upb_fielddef *f) { - union upb_value_ptr p = {._void = &msg->data[f->byte_offset]}; + union upb_value_ptr p; + p._void = &msg->data[f->byte_offset]; return p; } @@ -505,4 +518,8 @@ void upb_msgparser_reset(struct upb_msgparser *mp, upb_msg *m); size_t upb_msgparser_parse(struct upb_msgparser *mp, upb_strptr str, struct upb_status *status); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/tests/test_table.cc b/tests/test_table.cc index c903fff..7f8510b 100644 --- a/tests/test_table.cc +++ b/tests/test_table.cc @@ -1,6 +1,7 @@ #undef NDEBUG /* ensure tests always assert. */ #include "upb_table.h" +#include "upb_data.h" #include "test_util.h" #include <assert.h> #include <map> @@ -31,13 +32,6 @@ double get_usertime() return usage.ru_utime.tv_sec + (usage.ru_utime.tv_usec/1000000.0); } -struct upb_string *get_upbstring(const string& key) { - struct upb_string *str = upb_string_new(); - upb_string_resize(str, key.size()); - memcpy(str->ptr, key.c_str(), key.size()); - return str; -} - /* num_entries must be a power of 2. */ void test_strtable(const vector<string>& keys, uint32_t num_to_insert) { @@ -51,31 +45,34 @@ void test_strtable(const vector<string>& keys, uint32_t num_to_insert) all.insert(key); struct strtable_entry e; e.value = key[0]; - e.e.key = get_upbstring(key); + upb_strptr str = upb_strduplen(key.c_str(), key.size()); + e.e.key = str; upb_strtable_insert(&table, &e.e); + upb_string_unref(str); // The table still owns a ref. m[key] = key[0]; } /* Test correctness. */ for(uint32_t i = 0; i < keys.size(); i++) { const string& key = keys[i]; - struct upb_string *str = get_upbstring(key); + upb_strptr str = upb_strduplen(key.c_str(), key.size()); struct strtable_entry *e = (struct strtable_entry*)upb_strtable_lookup(&table, str); if(m.find(key) != m.end()) { /* Assume map implementation is correct. */ assert(e); - assert(upb_streql(e->e.key, get_upbstring(key))); + assert(upb_streql(e->e.key, str)); assert(e->value == key[0]); assert(m[key] == key[0]); } else { assert(e == NULL); } + upb_string_unref(str); } struct strtable_entry *e; for(e = (struct strtable_entry*)upb_strtable_begin(&table); e; e = (struct strtable_entry*)upb_strtable_next(&table, &e->e)) { - string tmp(e->e.key->ptr, e->e.key->byte_len); + string tmp(upb_string_getrobuf(e->e.key), upb_strlen(e->e.key)); std::set<string>::iterator i = all.find(tmp); assert(i != all.end()); all.erase(i); diff --git a/tests/test_vs_proto2.cc b/tests/test_vs_proto2.cc index 58c8e50..63dc0f0 100644 --- a/tests/test_vs_proto2.cc +++ b/tests/test_vs_proto2.cc @@ -4,10 +4,9 @@ #include <stdio.h> #include <stdlib.h> #include <google/protobuf/descriptor.h> -#include "upb_parse.h" +#include "upb_data.h" #include "upb_def.h" -#include "upb_msg.h" -#include "upb_mm.h" +#include "upb_parse.h" int num_assertions = 0; #define ASSERT(expr) do { \ @@ -18,58 +17,61 @@ int num_assertions = 0; #include MESSAGE_HFILE void compare(const google::protobuf::Message& proto2_msg, - struct upb_msg *upb_msg); + upb_msg *upb_msg, struct upb_msgdef *upb_md); void compare_arrays(const google::protobuf::Reflection *r, const google::protobuf::Message& proto2_msg, const google::protobuf::FieldDescriptor *proto2_f, - struct upb_msg *upb_msg, struct upb_fielddef *upb_f) + upb_msg *upb_msg, struct upb_fielddef *upb_f) { - struct upb_array *arr = *upb_msg_getptr(upb_msg, upb_f).arr; - ASSERT(arr->len == (upb_arraylen_t)r->FieldSize(proto2_msg, proto2_f)); - for(upb_arraylen_t i = 0; i < arr->len; i++) { - union upb_value_ptr p = upb_array_getelementptr(arr, i); + ASSERT(upb_msg_has(upb_msg, upb_f)); + upb_array *arr = upb_msg_get(upb_msg, upb_f).arr; + ASSERT(upb_array_len(arr) == (upb_arraylen_t)r->FieldSize(proto2_msg, proto2_f)); + for(upb_arraylen_t i = 0; i < upb_array_len(arr); i++) { + union upb_value v = upb_array_get(arr, upb_f, i); switch(upb_f->type) { default: ASSERT(false); case UPB_TYPE(DOUBLE): - ASSERT(r->GetRepeatedDouble(proto2_msg, proto2_f, i) == *p._double); + ASSERT(r->GetRepeatedDouble(proto2_msg, proto2_f, i) == v._double); break; case UPB_TYPE(FLOAT): - ASSERT(r->GetRepeatedFloat(proto2_msg, proto2_f, i) == *p._float); + ASSERT(r->GetRepeatedFloat(proto2_msg, proto2_f, i) == v._float); break; case UPB_TYPE(INT64): case UPB_TYPE(SINT64): case UPB_TYPE(SFIXED64): - ASSERT(r->GetRepeatedInt64(proto2_msg, proto2_f, i) == *p.int64); + ASSERT(r->GetRepeatedInt64(proto2_msg, proto2_f, i) == v.int64); break; case UPB_TYPE(UINT64): case UPB_TYPE(FIXED64): - ASSERT(r->GetRepeatedUInt64(proto2_msg, proto2_f, i) == *p.uint64); + ASSERT(r->GetRepeatedUInt64(proto2_msg, proto2_f, i) == v.uint64); break; case UPB_TYPE(SFIXED32): case UPB_TYPE(SINT32): case UPB_TYPE(INT32): case UPB_TYPE(ENUM): - ASSERT(r->GetRepeatedInt32(proto2_msg, proto2_f, i) == *p.int32); + ASSERT(r->GetRepeatedInt32(proto2_msg, proto2_f, i) == v.int32); break; case UPB_TYPE(FIXED32): case UPB_TYPE(UINT32): - ASSERT(r->GetRepeatedUInt32(proto2_msg, proto2_f, i) == *p.uint32); + ASSERT(r->GetRepeatedUInt32(proto2_msg, proto2_f, i) == v.uint32); break; case UPB_TYPE(BOOL): - ASSERT(r->GetRepeatedBool(proto2_msg, proto2_f, i) == *p._bool); + ASSERT(r->GetRepeatedBool(proto2_msg, proto2_f, i) == v._bool); break; case UPB_TYPE(STRING): case UPB_TYPE(BYTES): { std::string str = r->GetRepeatedString(proto2_msg, proto2_f, i); - std::string str2((*p.str)->ptr, (*p.str)->byte_len); + std::string str2(upb_string_getrobuf(v.str), upb_strlen(v.str)); ASSERT(str == str2); break; } case UPB_TYPE(GROUP): case UPB_TYPE(MESSAGE): - compare(r->GetRepeatedMessage(proto2_msg, proto2_f, i), *p.msg); + ASSERT(upb_dyncast_msgdef(upb_f->def) != NULL); + compare(r->GetRepeatedMessage(proto2_msg, proto2_f, i), + v.msg, upb_downcast_msgdef(upb_f->def)); } } } @@ -77,97 +79,101 @@ void compare_arrays(const google::protobuf::Reflection *r, void compare_values(const google::protobuf::Reflection *r, const google::protobuf::Message& proto2_msg, const google::protobuf::FieldDescriptor *proto2_f, - struct upb_msg *upb_msg, struct upb_fielddef *upb_f) + upb_msg *upb_msg, struct upb_fielddef *upb_f) { - union upb_value_ptr p = upb_msg_getptr(upb_msg, upb_f); + union upb_value v = upb_msg_get(upb_msg, upb_f); switch(upb_f->type) { default: ASSERT(false); case UPB_TYPE(DOUBLE): - ASSERT(r->GetDouble(proto2_msg, proto2_f) == *p._double); + ASSERT(r->GetDouble(proto2_msg, proto2_f) == v._double); break; case UPB_TYPE(FLOAT): - ASSERT(r->GetFloat(proto2_msg, proto2_f) == *p._float); + ASSERT(r->GetFloat(proto2_msg, proto2_f) == v._float); break; case UPB_TYPE(INT64): case UPB_TYPE(SINT64): case UPB_TYPE(SFIXED64): - ASSERT(r->GetInt64(proto2_msg, proto2_f) == *p.int64); + ASSERT(r->GetInt64(proto2_msg, proto2_f) == v.int64); break; case UPB_TYPE(UINT64): case UPB_TYPE(FIXED64): - ASSERT(r->GetUInt64(proto2_msg, proto2_f) == *p.uint64); + ASSERT(r->GetUInt64(proto2_msg, proto2_f) == v.uint64); break; case UPB_TYPE(SFIXED32): case UPB_TYPE(SINT32): case UPB_TYPE(INT32): case UPB_TYPE(ENUM): - ASSERT(r->GetInt32(proto2_msg, proto2_f) == *p.int32); + ASSERT(r->GetInt32(proto2_msg, proto2_f) == v.int32); break; case UPB_TYPE(FIXED32): case UPB_TYPE(UINT32): - ASSERT(r->GetUInt32(proto2_msg, proto2_f) == *p.uint32); + ASSERT(r->GetUInt32(proto2_msg, proto2_f) == v.uint32); break; case UPB_TYPE(BOOL): - ASSERT(r->GetBool(proto2_msg, proto2_f) == *p._bool); + ASSERT(r->GetBool(proto2_msg, proto2_f) == v._bool); break; case UPB_TYPE(STRING): case UPB_TYPE(BYTES): { std::string str = r->GetString(proto2_msg, proto2_f); - std::string str2((*p.str)->ptr, (*p.str)->byte_len); + std::string str2(upb_string_getrobuf(v.str), upb_strlen(v.str)); ASSERT(str == str2); break; } case UPB_TYPE(GROUP): case UPB_TYPE(MESSAGE): - compare(r->GetMessage(proto2_msg, proto2_f), *p.msg); + compare(r->GetMessage(proto2_msg, proto2_f), + v.msg, upb_downcast_msgdef(upb_f->def)); } } void compare(const google::protobuf::Message& proto2_msg, - struct upb_msg *upb_msg) + upb_msg *upb_msg, struct upb_msgdef *upb_md) { const google::protobuf::Reflection *r = proto2_msg.GetReflection(); const google::protobuf::Descriptor *d = proto2_msg.GetDescriptor(); - struct upb_msgdef *def = upb_msg->def; - ASSERT((upb_field_count_t)d->field_count() == def->num_fields); - for(upb_field_count_t i = 0; i < def->num_fields; i++) { - struct upb_fielddef *upb_f = &def->fields[i]; + ASSERT((upb_field_count_t)d->field_count() == upb_md->num_fields); + for(upb_field_count_t i = 0; i < upb_md->num_fields; i++) { + struct upb_fielddef *upb_f = &upb_md->fields[i]; const google::protobuf::FieldDescriptor *proto2_f = d->FindFieldByNumber(upb_f->number); // Make sure the definitions are equal. ASSERT(upb_f); ASSERT(proto2_f); ASSERT(upb_f->number == proto2_f->number()); - ASSERT(std::string(upb_f->name->ptr, upb_f->name->byte_len) == + ASSERT(std::string(upb_string_getrobuf(upb_f->name), + upb_strlen(upb_f->name)) == proto2_f->name()); ASSERT(upb_f->type == proto2_f->type()); ASSERT(upb_isarray(upb_f) == proto2_f->is_repeated()); - if(!upb_msg_isset(upb_msg, upb_f)) { + if(!upb_msg_has(upb_msg, upb_f)) { if(upb_isarray(upb_f)) ASSERT(r->FieldSize(proto2_msg, proto2_f) == 0); else ASSERT(r->HasField(proto2_msg, proto2_f) == false); } else { - if(upb_isarray(upb_f)) + if(upb_isarray(upb_f)) { compare_arrays(r, proto2_msg, proto2_f, upb_msg, upb_f); - else + } else { + ASSERT(r->HasField(proto2_msg, proto2_f) == true); compare_values(r, proto2_msg, proto2_f, upb_msg, upb_f); + } } } } -void parse_and_compare(MESSAGE_CIDENT *proto2_msg, struct upb_msg *upb_msg, - struct upb_string *str) +void parse_and_compare(MESSAGE_CIDENT *proto2_msg, + upb_msg *upb_msg, struct upb_msgdef *upb_md, + upb_strptr str) { // Parse to both proto2 and upb. - ASSERT(proto2_msg->ParseFromArray(str->ptr, str->byte_len)); + ASSERT(proto2_msg->ParseFromArray(upb_string_getrobuf(str), upb_strlen(str))); struct upb_status status = UPB_STATUS_INIT; - upb_msg_parsestr(upb_msg, str->ptr, str->byte_len, &status); + upb_msg_parsestr(upb_msg, upb_md, str, &status); ASSERT(upb_ok(&status)); - compare(*proto2_msg, upb_msg); + compare(*proto2_msg, upb_msg, upb_md); } int main(int argc, char *argv[]) @@ -189,8 +195,8 @@ int main(int argc, char *argv[]) // Initialize upb state, parse descriptor. struct upb_status status = UPB_STATUS_INIT; struct upb_symtab *c = upb_symtab_new(); - struct upb_string *fds = upb_strreadfile(MESSAGE_DESCRIPTOR_FILE); - if(!fds) { + upb_strptr fds = upb_strreadfile(MESSAGE_DESCRIPTOR_FILE); + if(upb_string_isnull(fds)) { fprintf(stderr, "Couldn't read " MESSAGE_DESCRIPTOR_FILE ".\n"); return 1; } @@ -202,7 +208,7 @@ int main(int argc, char *argv[]) } upb_string_unref(fds); - struct upb_string *proto_name = upb_strdupc(MESSAGE_NAME); + upb_strptr proto_name = upb_strdupc(MESSAGE_NAME); struct upb_msgdef *def = upb_downcast_msgdef(upb_symtab_lookup(c, proto_name)); if(!def) { fprintf(stderr, "Error finding symbol '" UPB_STRFMT "'.\n", @@ -212,20 +218,21 @@ int main(int argc, char *argv[]) upb_string_unref(proto_name); // Read the message data itself. - struct upb_string *str = upb_strreadfile(MESSAGE_FILE); - if(!str) { + upb_strptr str = upb_strreadfile(MESSAGE_FILE); + if(upb_string_isnull(str)) { fprintf(stderr, "Error reading " MESSAGE_FILE "\n"); return 1; } // Run twice to test proper object reuse. MESSAGE_CIDENT proto2_msg; - struct upb_msg *upb_msg = upb_msg_new(def); - parse_and_compare(&proto2_msg, upb_msg, str); - parse_and_compare(&proto2_msg, upb_msg, str); + upb_msg *upb_msg = upb_msg_new(def); + parse_and_compare(&proto2_msg, upb_msg, def, str); + parse_and_compare(&proto2_msg, upb_msg, def, str); printf("All tests passed, %d assertions.\n", num_assertions); - upb_msg_unref(upb_msg); + upb_msg_unref(upb_msg, def); + upb_def_unref(UPB_UPCAST(def)); upb_string_unref(str); upb_symtab_unref(c); diff --git a/tests/tests.c b/tests/tests.c index 9479e82..cd7a4f0 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -230,8 +230,8 @@ static void test_get_f_uint32_t() static void test_upb_symtab() { struct upb_symtab *s = upb_symtab_new(); ASSERT(s); - upb_string *descriptor = upb_strreadfile("tests/test.proto.pb"); - if(!descriptor) { + upb_strptr descriptor = upb_strreadfile("tests/test.proto.pb"); + if(upb_string_isnull(descriptor)) { fprintf(stderr, "Couldn't read input file tests/test.proto.pb\n"); exit(1); } @@ -242,7 +242,7 @@ static void test_upb_symtab() { // Test cycle detection by making a cyclic def's main refcount go to zero // and then be incremented to one again. - upb_string *symname = upb_strdupc("A"); + upb_strptr symname = upb_strdupc("A"); struct upb_def *def = upb_symtab_lookup(s, symname); upb_string_unref(symname); ASSERT(def); |