From f9efbcd5d6798229455584843e1817ef44cb4ab0 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 13 Dec 2019 23:28:25 -0800 Subject: [PATCH] Added missing append fallback. --- tests/test_generated_code.c | 20 ++++++++++++++++++++ upb/msg.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/tests/test_generated_code.c b/tests/test_generated_code.c index 9d8be79ef2..3d1f518b4c 100644 --- a/tests/test_generated_code.c +++ b/tests/test_generated_code.c @@ -301,9 +301,29 @@ static void test_int32_map() { upb_arena_free(arena); } +void test_repeated() { + upb_arena *arena = upb_arena_new(); + protobuf_test_messages_proto3_TestAllTypesProto3 *msg = + protobuf_test_messages_proto3_TestAllTypesProto3_new(arena); + size_t size; + const int *elems; + + protobuf_test_messages_proto3_TestAllTypesProto3_add_repeated_int32( + msg, 5, arena); + + elems = protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32( + msg, &size); + + ASSERT(size == 1); + ASSERT(elems[0] == 5); + + upb_arena_free(arena); +} + int run_tests(int argc, char *argv[]) { test_scalars(); test_string_map(); test_int32_map(); + test_repeated(); return 0; } diff --git a/upb/msg.c b/upb/msg.c index 756c6b5cac..db4de0983a 100644 --- a/upb/msg.c +++ b/upb/msg.c @@ -137,21 +137,44 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { return true; } -void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, - upb_fieldtype_t type, upb_arena *arena) { +static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type, + upb_arena *arena) { upb_array *arr = *arr_ptr; if (!arr) { arr = _upb_array_new(arena, type); if (!arr) return NULL; *arr_ptr = arr; } + return arr; +} +static bool resize_array(upb_array *arr, size_t size, upb_arena *arena) { if (size > arr->size && !_upb_array_realloc(arr, size, arena)) { - return NULL; + return false; } arr->len = size; - return _upb_array_ptr(arr); + return true; +} + +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + upb_fieldtype_t type, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, type, arena); + return arr && resize_array(arr, size, arena) ? _upb_array_ptr(arr) : NULL; +} + +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + upb_fieldtype_t type, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, type, arena); + size_t elem = arr->len; + int lg2 = _upb_fieldtype_to_sizelg2[type]; + char *data; + + if (!arr || !resize_array(arr, elem + 1, arena)) return false; + + data = _upb_array_ptr(arr); + memcpy(data + (elem << lg2), value, 1 << lg2); + return true; } /** upb_map *******************************************************************/