Merge pull request #3 from sbertin-telular/null_for_size_jimsch
Determine buffer size needed without encoding.
diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h
index 109eb9e..9a36ac5 100644
--- a/include/cn-cbor/cn-cbor.h
+++ b/include/cn-cbor/cn-cbor.h
@@ -299,10 +299,13 @@
/**
* 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
*/
diff --git a/src/cn-encoder.c b/src/cn-encoder.c
index 939c0e3..76ff50b 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -49,13 +49,20 @@
}
#define write_byte_and_data(b, data, sz) \
- ws->buf[ws->offset++] = (b); \
- memcpy(ws->buf + ws->offset, (data), (sz)); \
- ws->offset += 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) \
-{ if (ws->buf == NULL) ws->offset++; \
-else ws->buf[ws->offset++] = (b); }
+if(ws->buf) { \
+ ws->buf[ws->offset++] = (b); \
+} else { \
+ ws->offset++; \
+}
#define write_byte_ensured(b) \
ensure_writable(1); \
@@ -266,7 +273,9 @@
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;
@@ -320,6 +329,7 @@
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;
diff --git a/test/cbor_test.c b/test/cbor_test.c
index 3266631..857363b 100644
--- a/test/cbor_test.c
+++ b/test/cbor_test.c
@@ -132,6 +132,7 @@
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));
@@ -141,7 +142,9 @@
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(b.ptr, b.sz, encoded, enc_sz);
free(b.ptr);
cn_cbor_free(cb CONTEXT_NULL);
@@ -180,6 +183,7 @@
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));
@@ -190,7 +194,9 @@
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);
@@ -211,7 +217,9 @@
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);
@@ -274,13 +282,16 @@
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);
@@ -441,6 +452,8 @@
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);
}