cbor: add zero copy string deserialization
This commit is contained in:
parent
1c64d45b31
commit
d783d784c9
@ -403,6 +403,31 @@ static size_t decode_bytes(const cbor_stream_t *s, size_t offset, char *out, siz
|
||||
return (bytes_start + bytes_length);
|
||||
}
|
||||
|
||||
/* A zero copy version of decode_bytes.
|
||||
Will not null termiante input, but tell you the size of what you read.
|
||||
Great for reading byte strings which could contain nulls inside
|
||||
*/
|
||||
static size_t decode_bytes_no_copy(const cbor_stream_t *s, size_t offset, unsigned char **out, size_t *length)
|
||||
{
|
||||
CBOR_ENSURE_SIZE_READ(s, offset + 1);
|
||||
|
||||
if ((CBOR_TYPE(s, offset) != CBOR_BYTES && CBOR_TYPE(s, offset) != CBOR_TEXT) || !out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t bytes_length;
|
||||
size_t bytes_start = decode_int(s, offset, &bytes_length);
|
||||
|
||||
if (!bytes_start) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBOR_ENSURE_SIZE_READ(s, offset + bytes_start + bytes_length);
|
||||
*out = &(s->data[offset + bytes_start]);
|
||||
*length = bytes_length;
|
||||
return (bytes_start + bytes_length);
|
||||
}
|
||||
|
||||
size_t cbor_deserialize_int(const cbor_stream_t *stream, size_t offset, int *val)
|
||||
{
|
||||
CBOR_ENSURE_SIZE_READ(stream, offset + 1);
|
||||
@ -594,16 +619,23 @@ size_t cbor_deserialize_byte_string(const cbor_stream_t *stream, size_t offset,
|
||||
return decode_bytes(stream, offset, val, length);
|
||||
}
|
||||
|
||||
size_t cbor_deserialize_byte_string_no_copy(const cbor_stream_t *stream, size_t offset, unsigned char **val,
|
||||
size_t *length)
|
||||
{
|
||||
CBOR_ENSURE_SIZE_READ(stream, offset + 1);
|
||||
|
||||
if (CBOR_TYPE(stream, offset) != CBOR_BYTES) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return decode_bytes_no_copy(stream, offset, val, length);
|
||||
}
|
||||
|
||||
size_t cbor_serialize_byte_string(cbor_stream_t *stream, const char *val)
|
||||
{
|
||||
return encode_bytes(CBOR_BYTES, stream, val, strlen(val));
|
||||
}
|
||||
|
||||
size_t cbor_serialize_byte_stringl(cbor_stream_t *stream, const char *val, size_t length)
|
||||
{
|
||||
return encode_bytes(CBOR_BYTES, stream, val, length);
|
||||
}
|
||||
|
||||
size_t cbor_deserialize_unicode_string(const cbor_stream_t *stream, size_t offset, char *val,
|
||||
size_t length)
|
||||
{
|
||||
@ -616,6 +648,18 @@ size_t cbor_deserialize_unicode_string(const cbor_stream_t *stream, size_t offse
|
||||
return decode_bytes(stream, offset, val, length);
|
||||
}
|
||||
|
||||
size_t cbor_deserialize_unicode_string_no_copy(const cbor_stream_t *stream, size_t offset, unsigned char **val,
|
||||
size_t *length)
|
||||
{
|
||||
CBOR_ENSURE_SIZE_READ(stream, offset + 1);
|
||||
|
||||
if (CBOR_TYPE(stream, offset) != CBOR_TEXT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return decode_bytes_no_copy(stream, offset, val, length);
|
||||
}
|
||||
|
||||
size_t cbor_serialize_unicode_string(cbor_stream_t *stream, const char *val)
|
||||
{
|
||||
return encode_bytes(CBOR_TEXT, stream, val, strlen(val));
|
||||
|
||||
@ -365,16 +365,6 @@ size_t cbor_deserialize_double(const cbor_stream_t *stream, size_t offset,
|
||||
*/
|
||||
size_t cbor_serialize_byte_string(cbor_stream_t *stream, const char *val);
|
||||
|
||||
/**
|
||||
* @brief Serializes an arbitrary byte string
|
||||
*
|
||||
* @param[out] stream The destination stream for serializing the byte stream
|
||||
* @param[in] val The arbitrary byte string which may include null bytes
|
||||
* @param[in] length The size of the byte string in bytes
|
||||
*
|
||||
* @return Number of bytes written to stream @p stream
|
||||
*/
|
||||
size_t cbor_serialize_byte_stringl(cbor_stream_t *stream, const char *val, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Deserialize bytes from @p stream to @p val
|
||||
@ -391,6 +381,22 @@ size_t cbor_deserialize_byte_string(const cbor_stream_t *stream, size_t offset,
|
||||
|
||||
size_t cbor_serialize_unicode_string(cbor_stream_t *stream, const char *val);
|
||||
|
||||
/**
|
||||
* @brief Deserialize bytes/unicode from @p stream to @p val (without copy)
|
||||
*
|
||||
* @param[in] stream The stream to deserialize
|
||||
* @param[in] offset The offset within the stream where to start deserializing
|
||||
* @param[out] val Pointer to a char *
|
||||
* @param[out] length Pointer tp a size_t to store the size of the string
|
||||
*
|
||||
* @return Number of bytes written into @p val
|
||||
*/
|
||||
size_t cbor_deserialize_byte_string_no_copy(const cbor_stream_t *stream, size_t offset,
|
||||
unsigned char **val, size_t *length);
|
||||
|
||||
size_t cbor_deserialize_unicode_string_no_copy(const cbor_stream_t *stream, size_t offset,
|
||||
unsigned char **val, size_t *length);
|
||||
|
||||
/**
|
||||
* @brief Deserialize unicode string from @p stream to @p val
|
||||
*
|
||||
|
||||
@ -279,6 +279,39 @@ static void test_byte_string(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_byte_string_no_copy(void)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
{
|
||||
const char *input = "";
|
||||
unsigned char data[] = {0x40};
|
||||
unsigned char *out;
|
||||
size_t size;
|
||||
TEST_ASSERT(cbor_serialize_byte_string(&stream, input));
|
||||
CBOR_CHECK_SERIALIZED(stream, data, sizeof(data));
|
||||
TEST_ASSERT(cbor_deserialize_byte_string_no_copy(&stream, 0, &out, &size));
|
||||
memcpy(buffer, out, size);
|
||||
buffer[size] = '\0';
|
||||
CBOR_CHECK_DESERIALIZED(input, buffer, EQUAL_STRING);
|
||||
}
|
||||
|
||||
cbor_clear(&stream);
|
||||
|
||||
{
|
||||
const char *input = "a";
|
||||
unsigned char data[] = {0x41, 0x61};
|
||||
unsigned char *out;
|
||||
size_t size;
|
||||
TEST_ASSERT(cbor_serialize_byte_string(&stream, input));
|
||||
CBOR_CHECK_SERIALIZED(stream, data, sizeof(data));
|
||||
TEST_ASSERT(cbor_deserialize_byte_string_no_copy(&stream, 0, &out, &size));
|
||||
memcpy(buffer, out, size);
|
||||
buffer[size] = '\0';
|
||||
CBOR_CHECK_DESERIALIZED(input, buffer, EQUAL_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_byte_string_invalid(void)
|
||||
{
|
||||
{
|
||||
@ -318,6 +351,39 @@ static void test_unicode_string(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_unicode_string_no_copy(void)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
{
|
||||
const char *input = "";
|
||||
unsigned char data[] = {0x60};
|
||||
unsigned char *out;
|
||||
size_t size;
|
||||
TEST_ASSERT(cbor_serialize_unicode_string(&stream, input));
|
||||
CBOR_CHECK_SERIALIZED(stream, data, sizeof(data));
|
||||
TEST_ASSERT(cbor_deserialize_unicode_string_no_copy(&stream, 0, &out, &size));
|
||||
memcpy(buffer, out, size);
|
||||
buffer[size] = '\0';
|
||||
CBOR_CHECK_DESERIALIZED(input, buffer, EQUAL_STRING);
|
||||
}
|
||||
|
||||
cbor_clear(&stream);
|
||||
|
||||
{
|
||||
const char *input = "a";
|
||||
unsigned char data[] = {0x61, 0x61};
|
||||
unsigned char *out;
|
||||
size_t size;
|
||||
TEST_ASSERT(cbor_serialize_unicode_string(&stream, input));
|
||||
CBOR_CHECK_SERIALIZED(stream, data, sizeof(data));
|
||||
TEST_ASSERT(cbor_deserialize_unicode_string_no_copy(&stream, 0, &out, &size));
|
||||
memcpy(buffer, out, size);
|
||||
buffer[size] = '\0';
|
||||
CBOR_CHECK_DESERIALIZED(input, buffer, EQUAL_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_unicode_string_invalid(void)
|
||||
{
|
||||
{
|
||||
@ -761,8 +827,10 @@ TestRef tests_cbor_all(void)
|
||||
new_TestFixture(test_int64_t),
|
||||
new_TestFixture(test_int64_t_invalid),
|
||||
new_TestFixture(test_byte_string),
|
||||
new_TestFixture(test_byte_string_no_copy),
|
||||
new_TestFixture(test_byte_string_invalid),
|
||||
new_TestFixture(test_unicode_string),
|
||||
new_TestFixture(test_unicode_string_no_copy),
|
||||
new_TestFixture(test_unicode_string_invalid),
|
||||
new_TestFixture(test_array),
|
||||
new_TestFixture(test_array_indefinite),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user