Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework cbor_serialize_alloc to allocate exact buffer size upfront #251

Merged
merged 2 commits into from
Dec 28, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Rework and deprecate cbor_serialize_alloc
  • Loading branch information
PJK committed Dec 28, 2022
commit ce53b88a6fae7c376ca61296606ff17f8e310bed
33 changes: 8 additions & 25 deletions src/cbor/serialization.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,32 +147,15 @@ size_t cbor_serialized_size(const cbor_item_t *item) {

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;

// TODO: Would it be possible to tell the size upfront?
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);
size_t serialized_size = cbor_serialized_size(item);
if (serialized_size == 0) return 0;
*buffer = _CBOR_MALLOC(serialized_size);
if (*buffer == NULL) return 0;

if (tmp_bfr == NULL) {
_CBOR_FREE(bfr);
return 0;
}
bfr = tmp_bfr;
}
*buffer = bfr;
if (buffer_size != NULL) *buffer_size = bfr_size;
return written;
size_t written = cbor_serialize(item, *buffer, serialized_size);
assert(written == serialized_size);
if (buffer_size != NULL) *buffer_size = serialized_size;
return serialized_size;
}

size_t cbor_serialize_uint(const cbor_item_t *item, unsigned char *buffer,
Expand Down
2 changes: 1 addition & 1 deletion src/cbor/serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ cbor_serialized_size(const cbor_item_t *item);
* @return Length of the result. 0 on failure, in which case \p buffer is
* ``NULL``.
*/
_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_alloc(
_CBOR_NODISCARD CBOR_DEPRECATED CBOR_EXPORT size_t cbor_serialize_alloc(
const cbor_item_t *item, cbor_mutable_data *buffer, size_t *buffer_size);

/** Serialize an uint
Expand Down
11 changes: 8 additions & 3 deletions test/cbor_serialize_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
* it under the terms of the MIT license. See LICENSE for details.
*/

// cbor_serialize_alloc
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
Expand Down Expand Up @@ -353,8 +357,8 @@ static void test_auto_serialize(void **_CBOR_UNUSED(_state)) {

unsigned char *output;
size_t output_size;
assert_int_equal(37, cbor_serialize_alloc(item, &output, &output_size));
assert_int_equal(64, output_size);
assert_int_equal(cbor_serialize_alloc(item, &output, &output_size), 37);
assert_int_equal(output_size, 37);
assert_int_equal(cbor_serialized_size(item), 37);
assert_memory_equal(output, ((unsigned char[]){0x84, 0x1B}), 2);
cbor_decref(&item);
Expand All @@ -365,8 +369,9 @@ static void test_auto_serialize_no_size(void **_CBOR_UNUSED(_state)) {
cbor_item_t *item = cbor_build_uint8(1);

unsigned char *output;
assert_int_equal(1, cbor_serialize_alloc(item, &output, NULL));
assert_int_equal(cbor_serialize_alloc(item, &output, NULL), 1);
assert_memory_equal(output, ((unsigned char[]){0x01}), 1);
assert_int_equal(cbor_serialized_size(item), 1);
cbor_decref(&item);
_CBOR_FREE(output);
}
Expand Down