diff options
Diffstat (limited to 'src/upb_array.h')
-rw-r--r-- | src/upb_array.h | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/src/upb_array.h b/src/upb_array.h index 732c4aa..b5eb22d 100644 --- a/src/upb_array.h +++ b/src/upb_array.h @@ -32,11 +32,12 @@ extern "C" { struct upb_string; /* Returns a pointer to an array element. Does not perform a bounds check! */ -INLINE union upb_value_ptr upb_array_getelementptr( - struct upb_array *arr, upb_arraylen_t n, upb_field_type_t type) +INLINE union upb_value_ptr upb_array_getelementptr(struct upb_array *arr, + upb_arraylen_t n) { union upb_value_ptr ptr; - ptr._void = (void*)((char*)arr->elements._void + n*upb_type_info[type].size); + ptr._void = UPB_INDEX(arr->elements._void, n, + upb_type_info[arr->fielddef->type].size); return ptr; } @@ -66,26 +67,22 @@ INLINE uint32_t upb_round_up_to_pow2(uint32_t v) return v; } -/* Resizes array to be "len" elements long (reallocating if necessary). */ -INLINE bool upb_array_resize(struct upb_array *arr, upb_arraylen_t newlen) +INLINE union upb_value_ptr upb_array_append(struct upb_array *arr) { - size_t type_size = upb_type_info[arr->fielddef->type].size; - bool dropped = false; - bool ref = arr->size == 0; /* Ref'ing external memory. */ - void *data = arr->elements._void; - if(arr->size < newlen) { - /* Need to resize. */ - arr->size = UPB_MAX(4, upb_round_up_to_pow2(newlen)); - arr->elements._void = realloc(ref ? NULL : data, arr->size * type_size); + size_t size = upb_type_info[arr->fielddef->type].size; + upb_arraylen_t oldlen = arr->len; + if(oldlen == arr->size) { + arr->size = UPB_MAX(4, upb_round_up_to_pow2(oldlen+1)); + arr->elements._void = realloc(arr->elements._void, arr->size * size); + memset((char*)arr->elements._void + (arr->len*size), 0, (arr->size - arr->len) * size); } - if(ref) { - /* Need to take referenced data and copy it to memory we own. */ - memcpy(arr->elements._void, data, UPB_MIN(arr->len, newlen) * type_size); - dropped = true; - } - /* TODO: fill with defaults. */ - arr->len = newlen; - return dropped; + arr->len++; + return upb_array_getelementptr(arr, oldlen); +} + +INLINE void upb_array_truncate(struct upb_array *arr) +{ + arr->len = 0; } #ifdef __cplusplus |