size_t cbor_serialize_alloc(const cbor_item_t * item, unsigned char ** buffer, size_t * buffer_size) { size_t bfr_size = 32; unsigned char * bfr = _CBOR_MALLOC(bfr_size), * tmp_bfr; if (bfr == NULL) { return 0; } size_t written; /* This is waaay too optimistic - figure out something smarter (eventually) */ while ((written = cbor_serialize(item, bfr, bfr_size)) == 0) { if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, bfr_size)) { _CBOR_FREE(bfr); return 0; } tmp_bfr = _CBOR_REALLOC(bfr, bfr_size *= 2); if (tmp_bfr == NULL) { _CBOR_FREE(bfr); return 0; } bfr = tmp_bfr; } *buffer = bfr; *buffer_size = bfr_size; return written; }
bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee) { assert(cbor_isa_array(array)); struct _cbor_array_metadata *metadata = (struct _cbor_array_metadata *) &array->metadata; cbor_item_t **data = (cbor_item_t **) array->data; if (cbor_array_is_definite(array)) { /* Do not reallocate definite arrays */ if (metadata->end_ptr >= metadata->allocated) return false; data[metadata->end_ptr++] = pushee; } else { /* Exponential realloc */ if (metadata->end_ptr >= metadata->allocated) { size_t new_allocation = (size_t)(CBOR_BUFFER_GROWTH * (metadata->allocated)); new_allocation = new_allocation ? new_allocation : 1; unsigned char * new_data = _CBOR_REALLOC(array->data, new_allocation * sizeof(cbor_item_t *)); if (new_data == NULL) return false; array->data = new_data; metadata->allocated = new_allocation; } ((cbor_item_t **)array->data)[metadata->end_ptr++] = pushee; } cbor_incref(pushee); return true; }