Skip to content
This repository was archived by the owner on Apr 9, 2020. It is now read-only.

Determine buffer size needed without encoding. #51

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 5 additions & 2 deletions include/cn-cbor/cn-cbor.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,13 @@ void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT);
/**
* Write a CBOR value and all of the child values.
*
* @param[in] buf The buffer into which to write
* @param[in] buf The buffer into which to write. May be NULL to
* determine the necessary size.
* @param[in] buf_offset The offset (in bytes) from the beginning of the buffer
* to start writing at
* @param[in] buf_size The total length (in bytes) of the buffer
* @param[in] buf_size The total length (in bytes) of the buffer. If buf is
* NULL, this is an upper limit and may be 0 to specify
* no limit.
* @param[in] cb [description]
* @return -1 on fail, or number of bytes written
*/
Expand Down
19 changes: 15 additions & 4 deletions src/cn-encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,20 @@ typedef struct _write_state
}

#define write_byte_and_data(b, data, sz) \
ws->buf[ws->offset++] = (b); \
memcpy(ws->buf+ws->offset, (data), (sz)); \
if(ws->buf) { \
ws->buf[ws->offset++] = (b); \
memcpy(ws->buf+ws->offset, (data), (sz)); \
} else { \
ws->offset++; \
} \
ws->offset += sz;

#define write_byte(b) \
ws->buf[ws->offset++] = (b); \
if(ws->buf) { \
ws->buf[ws->offset++] = (b); \
} else { \
ws->offset++; \
}

#define write_byte_ensured(b) \
ensure_writable(1); \
Expand Down Expand Up @@ -249,7 +257,9 @@ void _encoder_visitor(const cn_cbor *cb, int depth, void *context)
case CN_CBOR_BYTES:
CHECK(_write_positive(ws, cb->type, cb->length));
ensure_writable(cb->length);
memcpy(ws->buf+ws->offset, cb->v.str, cb->length);
if (ws->buf) {
memcpy(ws->buf+ws->offset, cb->v.str, cb->length);
}
ws->offset += cb->length;
break;

Expand Down Expand Up @@ -302,6 +312,7 @@ ssize_t cn_cbor_encoder_write(uint8_t *buf,
const cn_cbor *cb)
{
cn_write_state ws = { buf, buf_offset, buf_size };
if (!ws.buf && ws.size <= 0) { ws.size = (ssize_t)(((size_t)-1) / 2); }
_visit(cb, _encoder_visitor, _encoder_breaker, &ws);
if (ws.offset < 0) { return -1; }
return ws.offset - buf_offset;
Expand Down
13 changes: 13 additions & 0 deletions test/cbor_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ CTEST(cbor, parse)
size_t i;
unsigned char encoded[1024];
ssize_t enc_sz;
ssize_t enc_sz2;

for (i=0; i<sizeof(tests)/sizeof(char*); i++) {
ASSERT_TRUE(parse_hex(tests[i], &b));
Expand All @@ -125,7 +126,9 @@ CTEST(cbor, parse)
ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
ASSERT_NOT_NULL(cb);

enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If #49 is merged, the size passed here could change to enc_sz2 to also test that.

ASSERT_EQUAL(enc_sz, enc_sz2);
ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz);
free(b.ptr);
cn_cbor_free(cb CONTEXT_NULL);
Expand Down Expand Up @@ -164,6 +167,7 @@ CTEST(cbor, parse_normalize)
size_t i;
unsigned char encoded[1024];
ssize_t enc_sz;
ssize_t enc_sz2;

for (i=0; i<sizeof(basic_tests)/sizeof(char*); i+=2) {
ASSERT_TRUE(parse_hex(basic_tests[i], &b));
Expand All @@ -174,7 +178,9 @@ CTEST(cbor, parse_normalize)
ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
ASSERT_NOT_NULL(cb);

enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
ASSERT_EQUAL(enc_sz, enc_sz2);
ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz);
free(b.ptr);
free(b2.ptr);
Expand All @@ -195,7 +201,9 @@ CTEST(cbor, parse_normalize)
ASSERT_NULL(cb);
#endif /* CBOR_NO_FLOAT */

/* enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb); */
/* enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */
/* ASSERT_EQUAL(enc_sz, enc_sz2); */
/* ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); */
free(b.ptr);
free(b2.ptr);
Expand Down Expand Up @@ -258,13 +266,16 @@ CTEST(cbor, float)
size_t i;
unsigned char encoded[1024];
ssize_t enc_sz;
ssize_t enc_sz2;

for (i=0; i<sizeof(tests)/sizeof(char*); i++) {
ASSERT_TRUE(parse_hex(tests[i], &b));
cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
ASSERT_NOT_NULL(cb);

enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
ASSERT_EQUAL(enc_sz, enc_sz2);
ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz);

free(b.ptr);
Expand Down Expand Up @@ -446,6 +457,8 @@ CTEST(cbor, create_encode)
ASSERT_NOT_NULL(cdata);

ASSERT_TRUE(cn_cbor_mapput_int(map, 0, cdata, CONTEXT_NULL_COMMA NULL));
enc_sz = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), map);
ASSERT_EQUAL(7, enc_sz);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), map);
ASSERT_EQUAL(7, enc_sz);
}