mirror of
https://github.com/openbsd/src.git
synced 2025-01-03 06:45:37 -08:00
Add libcbor; an implementation of the Concise Binary Object
Representation (CBOR) encoding format defined in RFC7049. This is a dependency of libfido2, that we'll use for U2F/FIDO support in OpenSSH. feedback and "Looks good enough to me" deraadt@
This commit is contained in:
parent
cdebaeb725
commit
da0d961c2c
21
lib/libcbor/LICENSE.md
Normal file
21
lib/libcbor/LICENSE.md
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2014-2017 Pavel Kalvoda
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
45
lib/libcbor/Makefile
Normal file
45
lib/libcbor/Makefile
Normal file
@ -0,0 +1,45 @@
|
||||
# $OpenBSD: Makefile,v 1.1 2019/11/14 21:11:34 djm Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/src ${.CURDIR}/src/cbor ${.CURDIR}/src/cbor/internal
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/src -DHAVE_ENDIAN_H
|
||||
|
||||
LIB= cbor
|
||||
SRCS= cbor.c
|
||||
#SRCS+= allocators.c
|
||||
|
||||
WARNINGS=yes
|
||||
CDIAGFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
||||
#CDIAGFLAGS+= -Werror
|
||||
|
||||
# cbor/
|
||||
SRCS+= arrays.c bytestrings.c callbacks.c common.c encoding.c floats_ctrls.c
|
||||
SRCS+= ints.c maps.c serialization.c streaming.c tags.c strings.c
|
||||
|
||||
# cbor/internal
|
||||
SRCS+= builder_callbacks.c encoders.c loaders.c memory_utils.c
|
||||
SRCS+= stack.c unicode.c
|
||||
|
||||
HDRS= cbor.h
|
||||
HDRS+= cbor/arrays.h cbor/bytestrings.h cbor/callbacks.h cbor/common.h
|
||||
HDRS+= cbor/configuration.h cbor/data.h cbor/encoding.h cbor/floats_ctrls.h
|
||||
HDRS+= cbor/ints.h cbor/maps.h cbor/serialization.h cbor/streaming.h
|
||||
HDRS+= cbor/strings.h cbor/tags.h
|
||||
|
||||
NOMAN=
|
||||
|
||||
includes:
|
||||
@for i in $(HDRS); do \
|
||||
j="test -d ${DESTDIR}/usr/include/`dirname $$i` || \
|
||||
${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 755 \
|
||||
${DESTDIR}/usr/include/`dirname $$i`"; \
|
||||
echo $$j; \
|
||||
eval "$$j"; \
|
||||
j="cmp -s src/$$i ${DESTDIR}/usr/include/$$i || \
|
||||
${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} \
|
||||
-m 444 ${.CURDIR}/src/$$i ${DESTDIR}/usr/include/$$i"; \
|
||||
echo $$j; \
|
||||
eval "$$j"; \
|
||||
done
|
||||
|
||||
.include <bsd.lib.mk>
|
50
lib/libcbor/README.md
Normal file
50
lib/libcbor/README.md
Normal file
@ -0,0 +1,50 @@
|
||||
# [libcbor](https://github.com/PJK/libcbor)
|
||||
|
||||
[![Build Status](https://travis-ci.org/PJK/libcbor.svg?branch=master)](https://travis-ci.org/PJK/libcbor)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/8kkmvmefelsxp5u2?svg=true)](https://ci.appveyor.com/project/PJK/libcbor)
|
||||
[![Documentation Status](https://readthedocs.org/projects/libcbor/badge/?version=latest)](https://readthedocs.org/projects/libcbor/?badge=latest)
|
||||
|
||||
**libcbor** is a C library for parsing and generating [CBOR](http://tools.ietf.org/html/rfc7049), the general-purpose schema-less binary data format.
|
||||
|
||||
## Main features
|
||||
- Complete RFC conformance
|
||||
- Robust C99 implementation
|
||||
- Layered architecture offers both control and convenience
|
||||
- Flexible memory management
|
||||
- No shared global state - threading friendly
|
||||
- Proper handling of UTF-8
|
||||
- Full support for streams & incremental processing
|
||||
- Extensive documentation and test suite
|
||||
- No runtime dependencies, small footprint
|
||||
|
||||
## Documentation
|
||||
Get the latest documentation at [libcbor.readthedocs.org](http://libcbor.readthedocs.org/)
|
||||
|
||||
## Contributions
|
||||
|
||||
All bug reports and contributions are welcome. Please see https://github.com/PJK/libcbor for more info.
|
||||
|
||||
Kudos to all the [contributors](https://github.com/PJK/libcbor/graphs/contributors)!
|
||||
|
||||
## License
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Pavel Kalvoda, 2014–2017
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
4
lib/libcbor/README.openbsd
Normal file
4
lib/libcbor/README.openbsd
Normal file
@ -0,0 +1,4 @@
|
||||
This is an import of https://github.com/pjk/libcbor v0.5.0
|
||||
|
||||
Apart from README.md and LICENSE.md, only the src/ directory has been
|
||||
imported.
|
3
lib/libcbor/shlib_version
Normal file
3
lib/libcbor/shlib_version
Normal file
@ -0,0 +1,3 @@
|
||||
major=0
|
||||
minor=5
|
||||
|
19
lib/libcbor/src/allocators.c
Normal file
19
lib/libcbor/src/allocators.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
_cbor_malloc_t _cbor_malloc = malloc;
|
||||
_cbor_realloc_t _cbor_realloc = realloc;
|
||||
_cbor_free_t _cbor_free = free;
|
||||
|
||||
void cbor_set_allocs(_cbor_malloc_t custom_malloc, _cbor_realloc_t custom_realloc, _cbor_free_t custom_free)
|
||||
{
|
||||
_cbor_malloc = custom_malloc;
|
||||
_cbor_realloc = custom_realloc;
|
||||
_cbor_free = custom_free;
|
||||
}
|
391
lib/libcbor/src/cbor.c
Normal file
391
lib/libcbor/src/cbor.c
Normal file
@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "cbor.h"
|
||||
#include "cbor/internal/builder_callbacks.h"
|
||||
#include "cbor/internal/loaders.h"
|
||||
|
||||
cbor_item_t * cbor_load(cbor_data source,
|
||||
size_t source_size,
|
||||
struct cbor_load_result *result)
|
||||
{
|
||||
/* Context stack */
|
||||
static struct cbor_callbacks callbacks = {
|
||||
.uint8 = &cbor_builder_uint8_callback,
|
||||
.uint16 = &cbor_builder_uint16_callback,
|
||||
.uint32 = &cbor_builder_uint32_callback,
|
||||
.uint64 = &cbor_builder_uint64_callback,
|
||||
|
||||
.negint8 = &cbor_builder_negint8_callback,
|
||||
.negint16 = &cbor_builder_negint16_callback,
|
||||
.negint32 = &cbor_builder_negint32_callback,
|
||||
.negint64 = &cbor_builder_negint64_callback,
|
||||
|
||||
.byte_string = &cbor_builder_byte_string_callback,
|
||||
.byte_string_start = &cbor_builder_byte_string_start_callback,
|
||||
|
||||
.string = &cbor_builder_string_callback,
|
||||
.string_start = &cbor_builder_string_start_callback,
|
||||
|
||||
.array_start = &cbor_builder_array_start_callback,
|
||||
.indef_array_start = &cbor_builder_indef_array_start_callback,
|
||||
|
||||
.map_start = &cbor_builder_map_start_callback,
|
||||
.indef_map_start = &cbor_builder_indef_map_start_callback,
|
||||
|
||||
.tag = &cbor_builder_tag_callback,
|
||||
|
||||
.null = &cbor_builder_null_callback,
|
||||
.undefined = &cbor_builder_undefined_callback,
|
||||
.boolean = &cbor_builder_boolean_callback,
|
||||
.float2 = &cbor_builder_float2_callback,
|
||||
.float4 = &cbor_builder_float4_callback,
|
||||
.float8 = &cbor_builder_float8_callback,
|
||||
.indef_break = &cbor_builder_indef_break_callback
|
||||
};
|
||||
|
||||
if (source_size == 0) {
|
||||
result->error.code = CBOR_ERR_NODATA;
|
||||
return NULL;
|
||||
}
|
||||
struct _cbor_stack stack = _cbor_stack_init();
|
||||
|
||||
/* Target for callbacks */
|
||||
struct _cbor_decoder_context context = (struct _cbor_decoder_context) {
|
||||
.stack = &stack,
|
||||
.creation_failed = false,
|
||||
.syntax_error = false
|
||||
};
|
||||
struct cbor_decoder_result decode_result;
|
||||
*result = (struct cbor_load_result) {.read = 0, .error = {.code = CBOR_ERR_NONE}};
|
||||
|
||||
do {
|
||||
if (source_size > result->read) { /* Check for overflows */
|
||||
decode_result = cbor_stream_decode(
|
||||
source + result->read,
|
||||
source_size - result->read,
|
||||
&callbacks,
|
||||
&context);
|
||||
} else {
|
||||
result->error = (struct cbor_error) {
|
||||
.code = CBOR_ERR_NOTENOUGHDATA,
|
||||
.position = result->read
|
||||
};
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (decode_result.status) {
|
||||
case CBOR_DECODER_FINISHED:
|
||||
/* Everything OK */
|
||||
{
|
||||
result->read += decode_result.read;
|
||||
break;
|
||||
}
|
||||
case CBOR_DECODER_NEDATA:
|
||||
/* Data length doesn't match MTB expectation */
|
||||
{
|
||||
result->error.code = CBOR_ERR_NOTENOUGHDATA;
|
||||
goto error;
|
||||
}
|
||||
case CBOR_DECODER_EBUFFER:
|
||||
/* Fallthrough */
|
||||
case CBOR_DECODER_ERROR:
|
||||
/* Reserved/malformated item */
|
||||
{
|
||||
result->error.code = CBOR_ERR_MALFORMATED;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.creation_failed) {
|
||||
/* Most likely unsuccessful allocation - our callback has failed */
|
||||
result->error.code = CBOR_ERR_MEMERROR;
|
||||
goto error;
|
||||
} else if (context.syntax_error) {
|
||||
result->error.code = CBOR_ERR_SYNTAXERROR;
|
||||
goto error;
|
||||
}
|
||||
} while (stack.size > 0);
|
||||
|
||||
/* Move the result before free */
|
||||
cbor_item_t *result_item = context.root;
|
||||
return result_item;
|
||||
|
||||
error:
|
||||
result->error.position = result->read;
|
||||
//debug_print("Failed with decoder error %d at %d\n", result->error.code, result->error.position);
|
||||
//cbor_describe(stack.top->item, stdout);
|
||||
/* Free the stack */
|
||||
while (stack.size > 0) {
|
||||
cbor_decref(&stack.top->item);
|
||||
_cbor_stack_pop(&stack);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static cbor_item_t * _cbor_copy_int(cbor_item_t * item, bool negative)
|
||||
{
|
||||
cbor_item_t * res;
|
||||
switch (cbor_int_get_width(item)) {
|
||||
case CBOR_INT_8: res = cbor_build_uint8(cbor_get_uint8(item)); break;
|
||||
case CBOR_INT_16: res = cbor_build_uint16(cbor_get_uint16(item)); break;
|
||||
case CBOR_INT_32: res = cbor_build_uint32(cbor_get_uint32(item)); break;
|
||||
case CBOR_INT_64: res = cbor_build_uint64(cbor_get_uint64(item)); break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
cbor_mark_negint(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static cbor_item_t * _cbor_copy_float_ctrl(cbor_item_t * item)
|
||||
{
|
||||
switch (cbor_float_get_width(item)) {
|
||||
case CBOR_FLOAT_0:
|
||||
return cbor_build_ctrl(cbor_ctrl_value(item));
|
||||
case CBOR_FLOAT_16:
|
||||
return cbor_build_float2(cbor_float_get_float2(item));
|
||||
case CBOR_FLOAT_32:
|
||||
return cbor_build_float4(cbor_float_get_float4(item));
|
||||
case CBOR_FLOAT_64:
|
||||
return cbor_build_float8(cbor_float_get_float8(item));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cbor_item_t * cbor_copy(cbor_item_t * item)
|
||||
{
|
||||
switch (cbor_typeof(item)) {
|
||||
case CBOR_TYPE_UINT:
|
||||
return _cbor_copy_int(item, false);
|
||||
case CBOR_TYPE_NEGINT:
|
||||
return _cbor_copy_int(item, true);
|
||||
case CBOR_TYPE_BYTESTRING:
|
||||
if (cbor_bytestring_is_definite(item)) {
|
||||
return cbor_build_bytestring(cbor_bytestring_handle(item), cbor_bytestring_length(item));
|
||||
} else {
|
||||
cbor_item_t * res = cbor_new_indefinite_bytestring();
|
||||
for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
|
||||
cbor_bytestring_add_chunk(
|
||||
res,
|
||||
cbor_move(
|
||||
cbor_copy(cbor_bytestring_chunks_handle(item)[i])
|
||||
)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
case CBOR_TYPE_STRING:
|
||||
if (cbor_string_is_definite(item)) {
|
||||
return cbor_build_stringn((const char *) cbor_string_handle(item), cbor_string_length(item));
|
||||
} else {
|
||||
cbor_item_t * res = cbor_new_indefinite_string();
|
||||
for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
|
||||
cbor_string_add_chunk(
|
||||
res,
|
||||
cbor_move(
|
||||
cbor_copy(cbor_string_chunks_handle(item)[i])
|
||||
)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
case CBOR_TYPE_ARRAY: {
|
||||
cbor_item_t * res;
|
||||
if (cbor_array_is_definite(item))
|
||||
res = cbor_new_definite_array(cbor_array_size(item));
|
||||
else
|
||||
res = cbor_new_indefinite_array();
|
||||
|
||||
for (size_t i = 0; i < cbor_array_size(item); i++)
|
||||
cbor_array_push(
|
||||
res,
|
||||
cbor_move(cbor_copy(cbor_move(cbor_array_get(item, i))))
|
||||
);
|
||||
return res;
|
||||
}
|
||||
case CBOR_TYPE_MAP: {
|
||||
cbor_item_t * res;
|
||||
if (cbor_map_is_definite(item))
|
||||
res = cbor_new_definite_map(cbor_map_size(item));
|
||||
else
|
||||
res = cbor_new_indefinite_map();
|
||||
|
||||
struct cbor_pair * it = cbor_map_handle(item);
|
||||
for (size_t i = 0; i < cbor_map_size(item); i++)
|
||||
cbor_map_add(res, (struct cbor_pair) {
|
||||
.key = cbor_move(cbor_copy(it[i].key)),
|
||||
.value = cbor_move(cbor_copy(it[i].value))
|
||||
});
|
||||
return res;
|
||||
}
|
||||
case CBOR_TYPE_TAG:
|
||||
return cbor_build_tag(
|
||||
cbor_tag_value(item),
|
||||
cbor_move(cbor_copy(cbor_tag_item(item)))
|
||||
);
|
||||
case CBOR_TYPE_FLOAT_CTRL:
|
||||
return _cbor_copy_float_ctrl(item);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if CBOR_PRETTY_PRINTER
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <wchar.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
static int _pow(int b, int ex)
|
||||
{
|
||||
if (ex == 0) return 1;
|
||||
int res = b;
|
||||
while (--ex > 0) res *= b;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _cbor_nested_describe(cbor_item_t *item, FILE *out, int indent)
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
switch (cbor_typeof(item)) {
|
||||
case CBOR_TYPE_UINT: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_UINT] ", indent, " ");
|
||||
fprintf(out, "Width: %dB, ", _pow(2, cbor_int_get_width(item)));
|
||||
fprintf(out, "Value: %"PRIu64"\n", cbor_get_int(item));
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_NEGINT: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_NEGINT] ", indent, " ");
|
||||
fprintf(out, "Width: %dB, ", _pow(2, cbor_int_get_width(item)));
|
||||
fprintf(out, "Value: -%"PRIu64" -1\n", cbor_get_int(item));
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_BYTESTRING: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_BYTESTRING] ", indent, " ");
|
||||
if (cbor_bytestring_is_indefinite(item)) {
|
||||
fprintf(out,
|
||||
"Indefinite, with %zu chunks:\n",
|
||||
cbor_bytestring_chunk_count(item));
|
||||
for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
|
||||
_cbor_nested_describe(
|
||||
cbor_bytestring_chunks_handle(item)[i],
|
||||
out,
|
||||
indent + 4);
|
||||
} else {
|
||||
fprintf(out,
|
||||
"Definite, length %zuB\n",
|
||||
cbor_bytestring_length(item));
|
||||
}
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_STRING: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_STRING] ", indent, " ");
|
||||
if (cbor_string_is_indefinite(item)) {
|
||||
fprintf(out,
|
||||
"Indefinite, with %zu chunks:\n",
|
||||
cbor_string_chunk_count(item));
|
||||
for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
|
||||
_cbor_nested_describe(
|
||||
cbor_string_chunks_handle(item)[i],
|
||||
out,
|
||||
indent + 4);
|
||||
} else {
|
||||
fprintf(out,
|
||||
"Definite, length %zuB, %zu codepoints\n",
|
||||
cbor_string_length(item),
|
||||
cbor_string_codepoint_count(item));
|
||||
/* Careful - this doesn't support multibyte characters! */
|
||||
/* Printing those is out of the scope of this demo :) */
|
||||
/* libICU is your friend */
|
||||
fprintf(out, "%*s", indent + 4, " ");
|
||||
/* XXX: no null at the end -> confused vprintf */
|
||||
fwrite(cbor_string_handle(item), (int) cbor_string_length(item), 1, out);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_ARRAY: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_ARRAY] ", indent, " ");
|
||||
if (cbor_array_is_definite(item)) {
|
||||
fprintf(out,
|
||||
"Definite, size: %zu\n",
|
||||
cbor_array_size(item));
|
||||
} else {
|
||||
fprintf(out,
|
||||
"Indefinite, size: %zu\n",
|
||||
cbor_array_size(item));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < cbor_array_size(item); i++)
|
||||
_cbor_nested_describe(
|
||||
cbor_array_handle(item)[i],
|
||||
out,
|
||||
indent + 4);
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_MAP: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_MAP] ", indent, " ");
|
||||
if (cbor_map_is_definite(item)) {
|
||||
fprintf(out,
|
||||
"Definite, size: %zu\n",
|
||||
cbor_map_size(item));
|
||||
} else {
|
||||
fprintf(out,
|
||||
"Indefinite, size: %zu\n",
|
||||
cbor_map_size(item));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < cbor_map_size(item); i++) {
|
||||
_cbor_nested_describe(
|
||||
cbor_map_handle(item)[i].key,
|
||||
out,
|
||||
indent + 4);
|
||||
_cbor_nested_describe(
|
||||
cbor_map_handle(item)[i].value,
|
||||
out,
|
||||
indent + 4);
|
||||
}
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_TAG: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_TAG] ", indent, " ");
|
||||
fprintf(out, "Value: %"PRIu64"\n", cbor_tag_value(item));
|
||||
_cbor_nested_describe(cbor_tag_item(item), out, indent + 4);
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_FLOAT_CTRL: {
|
||||
fprintf(out, "%*s[CBOR_TYPE_FLOAT_CTRL] ", indent, " ");
|
||||
if (cbor_float_ctrl_is_ctrl(item)) {
|
||||
if (cbor_is_bool(item))
|
||||
fprintf(out, "Bool: %s\n", cbor_ctrl_is_bool(item) ? "true" : "false");
|
||||
else if (cbor_is_undef(item))
|
||||
fprintf(out, "Undefined\n");
|
||||
else if (cbor_is_null(item))
|
||||
fprintf(out, "Null\n");
|
||||
else
|
||||
fprintf(out, "Simple value %d\n", cbor_ctrl_value(item));
|
||||
} else {
|
||||
fprintf(out, "Width: %dB, ", _pow(2, cbor_float_get_width(item)));
|
||||
fprintf(out, "value: %lf\n", cbor_float_get_float(item));
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_describe(cbor_item_t *item, FILE *out)
|
||||
{
|
||||
_cbor_nested_describe(item, out, 0);
|
||||
}
|
||||
|
||||
#endif
|
68
lib/libcbor/src/cbor.h
Normal file
68
lib/libcbor/src/cbor.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBCBOR_H_
|
||||
#define LIBCBOR_H_
|
||||
|
||||
#include "cbor/data.h"
|
||||
#include "cbor/common.h"
|
||||
|
||||
#include "cbor/arrays.h"
|
||||
#include "cbor/bytestrings.h"
|
||||
#include "cbor/floats_ctrls.h"
|
||||
#include "cbor/ints.h"
|
||||
#include "cbor/maps.h"
|
||||
#include "cbor/strings.h"
|
||||
#include "cbor/tags.h"
|
||||
|
||||
#include "cbor/encoding.h"
|
||||
#include "cbor/serialization.h"
|
||||
#include "cbor/callbacks.h"
|
||||
#include "cbor/streaming.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* High level decoding
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Loads data item from a buffer
|
||||
*
|
||||
* @param source The buffer
|
||||
* @param source_size
|
||||
* @param result[out] Result indicator. #CBOR_ERR_NONE on success
|
||||
* @return **new** CBOR item or `NULL` on failure. In that case, \p result contains location and description of the error.
|
||||
*/
|
||||
cbor_item_t * cbor_load(cbor_data source,
|
||||
size_t source_size,
|
||||
struct cbor_load_result * result);
|
||||
|
||||
/** Deep copy of an item
|
||||
*
|
||||
* All the reference counts in the new structure are set to one.
|
||||
*
|
||||
* @param item[borrow] item to copy
|
||||
* @return **new** CBOR deep copy
|
||||
*/
|
||||
cbor_item_t * cbor_copy(cbor_item_t * item);
|
||||
|
||||
#if CBOR_PRETTY_PRINTER
|
||||
#include <stdio.h>
|
||||
|
||||
void cbor_describe(cbor_item_t * item, FILE * out);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_H_
|
157
lib/libcbor/src/cbor/arrays.c
Normal file
157
lib/libcbor/src/cbor/arrays.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "arrays.h"
|
||||
#include "internal/memory_utils.h"
|
||||
|
||||
size_t cbor_array_size(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_array(item));
|
||||
return item->metadata.array_metadata.end_ptr;
|
||||
}
|
||||
|
||||
size_t cbor_array_allocated(const cbor_item_t * item)
|
||||
{
|
||||
assert(cbor_isa_array(item));
|
||||
return item->metadata.array_metadata.allocated;
|
||||
}
|
||||
|
||||
|
||||
cbor_item_t * cbor_array_get(const cbor_item_t * item, size_t index)
|
||||
{
|
||||
return cbor_incref(((cbor_item_t **) item->data)[index]);
|
||||
}
|
||||
|
||||
bool cbor_array_set(cbor_item_t * item, size_t index, cbor_item_t * value)
|
||||
{
|
||||
if (index == item->metadata.array_metadata.end_ptr) {
|
||||
return cbor_array_push(item, value);
|
||||
} else if (index < item->metadata.array_metadata.end_ptr) {
|
||||
return cbor_array_replace(item, index, value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbor_array_replace(cbor_item_t * item, size_t index, cbor_item_t * value)
|
||||
{
|
||||
if (index >= item->metadata.array_metadata.end_ptr)
|
||||
return false;
|
||||
/* We cannot use cbor_array_get as that would increase the refcount */
|
||||
cbor_intermediate_decref(((cbor_item_t **) item->data)[index]);
|
||||
((cbor_item_t **) item->data)[index] = cbor_incref(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
// Check for overflows first
|
||||
if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t new_allocation = metadata->allocated == 0 ? 1 : CBOR_BUFFER_GROWTH * metadata->allocated;
|
||||
|
||||
unsigned char * new_data = _cbor_realloc_multiple(array->data, sizeof(cbor_item_t *), new_allocation);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
bool cbor_array_is_definite(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_array(item));
|
||||
return item->metadata.array_metadata.type == _CBOR_METADATA_DEFINITE;
|
||||
}
|
||||
|
||||
bool cbor_array_is_indefinite(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_array(item));
|
||||
return item->metadata.array_metadata.type == _CBOR_METADATA_INDEFINITE;
|
||||
}
|
||||
|
||||
cbor_item_t **cbor_array_handle(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_array(item));
|
||||
return (cbor_item_t **) item->data;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_definite_array(size_t size)
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
if (item == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cbor_item_t ** data = _cbor_alloc_multiple(sizeof(cbor_item_t *), size);
|
||||
if (data == NULL) {
|
||||
_CBOR_FREE(item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
data[i] = NULL;
|
||||
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_ARRAY,
|
||||
.metadata = {
|
||||
.array_metadata = {
|
||||
.type = _CBOR_METADATA_DEFINITE,
|
||||
.allocated = size,
|
||||
.end_ptr = 0
|
||||
}
|
||||
},
|
||||
.data = (unsigned char *)data
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_indefinite_array()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
if (item == NULL)
|
||||
return NULL;
|
||||
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_ARRAY,
|
||||
.metadata = {
|
||||
.array_metadata = {
|
||||
.type = _CBOR_METADATA_INDEFINITE,
|
||||
.allocated = 0,
|
||||
.end_ptr = 0
|
||||
}
|
||||
},
|
||||
.data = NULL /* Can be safely realloc-ed */
|
||||
};
|
||||
return item;
|
||||
}
|
112
lib/libcbor/src/cbor/arrays.h
Normal file
112
lib/libcbor/src/cbor/arrays.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_ARRAYS_H
|
||||
#define LIBCBOR_ARRAYS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Get the number of members
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @return The number of members
|
||||
*/
|
||||
size_t cbor_array_size(const cbor_item_t * item);
|
||||
|
||||
/** Get the size of the allocated storage
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @return The size of the allocated storage (number of items)
|
||||
*/
|
||||
size_t cbor_array_allocated(const cbor_item_t * item);
|
||||
|
||||
/** Get item by index
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @param index The index
|
||||
* @return **incref** The item, or `NULL` in case of boundary violation
|
||||
*/
|
||||
cbor_item_t * cbor_array_get(const cbor_item_t * item, size_t index);
|
||||
|
||||
/** Set item by index
|
||||
*
|
||||
* Creating arrays with holes is not possible
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @param value[incref] The item to assign
|
||||
* @param index The index, first item is 0.
|
||||
* @return true on success, false on allocation failure.
|
||||
*/
|
||||
bool cbor_array_set(cbor_item_t * item, size_t index, cbor_item_t * value);
|
||||
|
||||
/** Replace item at an index
|
||||
*
|
||||
* The item being replace will be #cbor_decref 'ed.
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @param value[incref] The item to assign
|
||||
* @param index The index, first item is 0.
|
||||
* @return true on success, false on allocation failure.
|
||||
*/
|
||||
bool cbor_array_replace(cbor_item_t * item, size_t index, cbor_item_t * value);
|
||||
|
||||
/** Is the array definite?
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @return Is the array definite?
|
||||
*/
|
||||
bool cbor_array_is_definite(const cbor_item_t * item);
|
||||
|
||||
/** Is the array indefinite?
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @return Is the array indefinite?
|
||||
*/
|
||||
bool cbor_array_is_indefinite(const cbor_item_t * item);
|
||||
|
||||
/** Get the array contents
|
||||
*
|
||||
* The items may be reordered and modified as long as references remain consistent.
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @return #cbor_array_size items
|
||||
*/
|
||||
cbor_item_t ** cbor_array_handle(const cbor_item_t * item);
|
||||
|
||||
/** Create new definite array
|
||||
*
|
||||
* @param size Number of slots to preallocate
|
||||
* @return **new** array or `NULL` upon malloc failure
|
||||
*/
|
||||
cbor_item_t * cbor_new_definite_array(size_t size);
|
||||
|
||||
/** Create new indefinite array
|
||||
*
|
||||
* @return **new** array or `NULL` upon malloc failure
|
||||
*/
|
||||
cbor_item_t * cbor_new_indefinite_array();
|
||||
|
||||
/** Append to the end
|
||||
*
|
||||
* For indefinite items, storage may be realloacted. For definite items, only the
|
||||
* preallocated capacity is available.
|
||||
*
|
||||
* @param array[borrow] An array
|
||||
* @param pushee[incref] The item to push
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool cbor_array_push(cbor_item_t * array, cbor_item_t * pushee);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_ARRAYS_H
|
118
lib/libcbor/src/cbor/bytestrings.c
Normal file
118
lib/libcbor/src/cbor/bytestrings.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "bytestrings.h"
|
||||
#include "internal/memory_utils.h"
|
||||
|
||||
size_t cbor_bytestring_length(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
return item->metadata.bytestring_metadata.length;
|
||||
}
|
||||
|
||||
unsigned char *cbor_bytestring_handle(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
return item->data;
|
||||
}
|
||||
|
||||
bool cbor_bytestring_is_definite(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE;
|
||||
}
|
||||
|
||||
bool cbor_bytestring_is_indefinite(const cbor_item_t *item)
|
||||
{
|
||||
return !cbor_bytestring_is_definite(item);
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_definite_bytestring()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_BYTESTRING,
|
||||
.metadata = {.bytestring_metadata = {_CBOR_METADATA_DEFINITE, 0}}
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_indefinite_bytestring()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_BYTESTRING,
|
||||
.metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_INDEFINITE, .length = 0}},
|
||||
.data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data))
|
||||
};
|
||||
*((struct cbor_indefinite_string_data *) item->data) = (struct cbor_indefinite_string_data) {
|
||||
.chunk_count = 0,
|
||||
.chunk_capacity = 0,
|
||||
.chunks = NULL,
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length)
|
||||
{
|
||||
cbor_item_t *res = cbor_new_definite_bytestring();
|
||||
void * content = _CBOR_MALLOC(length);
|
||||
memcpy(content, handle, length);
|
||||
cbor_bytestring_set_handle(res, content, length);
|
||||
return res;
|
||||
}
|
||||
|
||||
void cbor_bytestring_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
assert(cbor_bytestring_is_definite(item));
|
||||
item->data = data;
|
||||
item->metadata.bytestring_metadata.length = length;
|
||||
}
|
||||
|
||||
cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
assert(cbor_bytestring_is_indefinite(item));
|
||||
return ((struct cbor_indefinite_string_data *) item->data)->chunks;
|
||||
}
|
||||
|
||||
size_t cbor_bytestring_chunk_count(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
assert(cbor_bytestring_is_indefinite(item));
|
||||
return ((struct cbor_indefinite_string_data *) item->data)->chunk_count;
|
||||
|
||||
}
|
||||
|
||||
bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
assert(cbor_bytestring_is_indefinite(item));
|
||||
struct cbor_indefinite_string_data *data = (struct cbor_indefinite_string_data *) item->data;
|
||||
if (data->chunk_count == data->chunk_capacity) {
|
||||
/* We need more space */
|
||||
if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->chunk_capacity = data->chunk_capacity == 0 ? 1 : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
|
||||
|
||||
cbor_item_t **new_chunks_data = _cbor_realloc_multiple(data->chunks, sizeof(cbor_item_t *), data->chunk_capacity);
|
||||
|
||||
if (new_chunks_data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->chunks = new_chunks_data;
|
||||
}
|
||||
data->chunks[data->chunk_count++] = cbor_incref(chunk);
|
||||
return true;
|
||||
}
|
123
lib/libcbor/src/cbor/bytestrings.h
Normal file
123
lib/libcbor/src/cbor/bytestrings.h
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_BYTESTRINGS_H
|
||||
#define LIBCBOR_BYTESTRINGS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Byte string manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Returns the length of the binary data
|
||||
*
|
||||
* For definite byte strings only
|
||||
*
|
||||
* @param item[borrow] a definite bytestring
|
||||
* @return length of the binary data. Zero if no chunk has been attached yet
|
||||
*/
|
||||
size_t cbor_bytestring_length(const cbor_item_t *item);
|
||||
|
||||
/** Is the byte string definite?
|
||||
*
|
||||
* @param item[borrow] a byte string
|
||||
* @return Is the byte string definite?
|
||||
*/
|
||||
bool cbor_bytestring_is_definite(const cbor_item_t *item);
|
||||
|
||||
/** Is the byte string indefinite?
|
||||
*
|
||||
* @param item[borrow] a byte string
|
||||
* @return Is the byte string indefinite?
|
||||
*/
|
||||
bool cbor_bytestring_is_indefinite(const cbor_item_t *item);
|
||||
|
||||
/** Get the handle to the binary data
|
||||
*
|
||||
* Definite items only. Modifying the data is allowed. In that case, the caller takes
|
||||
* responsibility for the effect on items this item might be a part of
|
||||
*
|
||||
* @param item[borrow] A definite byte string
|
||||
* @return The address of the binary data. `NULL` if no data have been assigned yet.
|
||||
*/
|
||||
cbor_mutable_data cbor_bytestring_handle(const cbor_item_t *item);
|
||||
|
||||
/** Set the handle to the binary data
|
||||
*
|
||||
* @param item[borrow] A definite byte string
|
||||
* @param data The memory block. The caller gives up the ownership of the block. libcbor will deallocate it when appropriate using its free function
|
||||
* @param length Length of the data block
|
||||
*/
|
||||
void cbor_bytestring_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length);
|
||||
|
||||
/** Get the handle to the array of chunks
|
||||
*
|
||||
* Manipulations with the memory block (e.g. sorting it) are allowed, but the validity and the number of chunks must be retained.
|
||||
*
|
||||
* @param item[borrow] A indefinite byte string
|
||||
* @return array of #cbor_bytestring_chunk_count definite bytestrings
|
||||
*/
|
||||
cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item);
|
||||
|
||||
/** Get the number of chunks this string consist of
|
||||
*
|
||||
* @param item[borrow] A indefinite bytestring
|
||||
* @return The chunk count. 0 for freshly created items.
|
||||
*/
|
||||
size_t cbor_bytestring_chunk_count(const cbor_item_t *item);
|
||||
|
||||
/** Appends a chunk to the bytestring
|
||||
*
|
||||
* Indefinite byte strings only.
|
||||
*
|
||||
* May realloc the chunk storage.
|
||||
*
|
||||
* @param item[borrow] An indefinite byte string
|
||||
* @param item[incref] A definite byte string
|
||||
* @return true on success, false on realloc failure. In that case, the refcount of `chunk` is not increased and the `item` is left intact.
|
||||
*/
|
||||
bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk);
|
||||
|
||||
/** Creates a new definite byte string
|
||||
*
|
||||
* The handle is initialized to `NULL` and length to 0
|
||||
*
|
||||
* @return **new** definite bytestring. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_new_definite_bytestring();
|
||||
|
||||
/** Creates a new indefinite byte string
|
||||
*
|
||||
* The chunks array is initialized to `NULL` and chunkcount to 0
|
||||
*
|
||||
* @return **new** indefinite bytestring. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_new_indefinite_bytestring();
|
||||
|
||||
/** Creates a new byte string and initializes it
|
||||
*
|
||||
* The `handle` will be copied to a newly allocated block
|
||||
*
|
||||
* @param handle Block of binary data
|
||||
* @param length Length of `data`
|
||||
* @return A **new** byte string with content `handle`. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //LIBCBOR_BYTESTRINGS_H
|
104
lib/libcbor/src/cbor/callbacks.c
Normal file
104
lib/libcbor/src/cbor/callbacks.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "callbacks.h"
|
||||
|
||||
#define CBOR_DUMMY_CALLBACK { }
|
||||
|
||||
void cbor_null_uint8_callback(void *_ctx, uint8_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_uint16_callback(void *_ctx, uint16_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_uint32_callback(void *_ctx, uint32_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_uint64_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_negint8_callback(void *_ctx, uint8_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_negint16_callback(void *_ctx, uint16_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_negint32_callback(void *_ctx, uint32_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_negint64_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_string_callback(void *_ctx, cbor_data _val, size_t _val2) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_byte_string_callback(void *_ctx, cbor_data _val, size_t _val2) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_byte_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_array_start_callback(void *_ctx, size_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_indef_array_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_map_start_callback(void *_ctx, size_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_indef_map_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_tag_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_float2_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_float4_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_float8_callback(void *_ctx, double _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_null_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_undefined_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_boolean_callback(void *_ctx, bool _val) CBOR_DUMMY_CALLBACK
|
||||
|
||||
void cbor_null_indef_break_callback(void *_ctx) CBOR_DUMMY_CALLBACK
|
||||
|
||||
const struct cbor_callbacks cbor_empty_callbacks = {
|
||||
/* Type 0 - Unsigned integers */
|
||||
.uint8 = cbor_null_uint8_callback,
|
||||
.uint16 = cbor_null_uint16_callback,
|
||||
.uint32 = cbor_null_uint32_callback,
|
||||
.uint64 = cbor_null_uint64_callback,
|
||||
|
||||
/* Type 1 - Negative integers */
|
||||
.negint8 = cbor_null_negint8_callback,
|
||||
.negint16 = cbor_null_negint16_callback,
|
||||
.negint32 = cbor_null_negint32_callback,
|
||||
.negint64 = cbor_null_negint64_callback,
|
||||
|
||||
/* Type 2 - Byte strings */
|
||||
.byte_string_start = cbor_null_byte_string_start_callback,
|
||||
.byte_string = cbor_null_byte_string_callback,
|
||||
|
||||
/* Type 3 - Strings */
|
||||
.string_start = cbor_null_string_start_callback,
|
||||
.string = cbor_null_string_callback,
|
||||
|
||||
/* Type 4 - Arrays */
|
||||
.indef_array_start = cbor_null_indef_array_start_callback,
|
||||
.array_start = cbor_null_array_start_callback,
|
||||
|
||||
/* Type 5 - Maps */
|
||||
.indef_map_start = cbor_null_indef_map_start_callback,
|
||||
.map_start = cbor_null_map_start_callback,
|
||||
|
||||
/* Type 6 - Tags */
|
||||
.tag = cbor_null_tag_callback,
|
||||
|
||||
/* Type 7 - Floats & misc */
|
||||
/* Type names cannot be member names */
|
||||
.float2 = cbor_null_float2_callback,
|
||||
/* 2B float is not supported in standard C */
|
||||
.float4 = cbor_null_float4_callback,
|
||||
.float8 = cbor_null_float8_callback,
|
||||
.undefined = cbor_null_undefined_callback,
|
||||
.null = cbor_null_null_callback,
|
||||
.boolean = cbor_null_boolean_callback,
|
||||
|
||||
/* Shared indefinites */
|
||||
.indef_break = cbor_null_indef_break_callback,
|
||||
};
|
187
lib/libcbor/src/cbor/callbacks.h
Normal file
187
lib/libcbor/src/cbor/callbacks.h
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_CALLBACKS_H
|
||||
#define LIBCBOR_CALLBACKS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_int8_callback)(void *, uint8_t);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_int16_callback)(void *, uint16_t);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_int32_callback)(void *, uint32_t);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_int64_callback)(void *, uint64_t);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_simple_callback)(void *);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_string_callback)(void *, cbor_data, size_t);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_collection_callback)(void *, size_t);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_float_callback)(void *, float);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_double_callback)(void *, double);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void(*cbor_bool_callback)(void *, bool);
|
||||
|
||||
/** Callback bundle -- passed to the decoder */
|
||||
struct cbor_callbacks {
|
||||
/** Unsigned int */
|
||||
cbor_int8_callback uint8;
|
||||
/** Unsigned int */
|
||||
cbor_int16_callback uint16;
|
||||
/** Unsigned int */
|
||||
cbor_int32_callback uint32;
|
||||
/** Unsigned int */
|
||||
cbor_int64_callback uint64;
|
||||
|
||||
/** Negative int */
|
||||
cbor_int64_callback negint64;
|
||||
/** Negative int */
|
||||
cbor_int32_callback negint32;
|
||||
/** Negative int */
|
||||
cbor_int16_callback negint16;
|
||||
/** Negative int */
|
||||
cbor_int8_callback negint8;
|
||||
|
||||
/** Definite byte string */
|
||||
cbor_simple_callback byte_string_start;
|
||||
/** Indefinite byte string start */
|
||||
cbor_string_callback byte_string;
|
||||
|
||||
/** Definite string */
|
||||
cbor_string_callback string;
|
||||
/** Indefinite string start */
|
||||
cbor_simple_callback string_start;
|
||||
|
||||
/** Definite array */
|
||||
cbor_simple_callback indef_array_start;
|
||||
/** Indefinite array */
|
||||
cbor_collection_callback array_start;
|
||||
|
||||
/** Definite map */
|
||||
cbor_simple_callback indef_map_start;
|
||||
/** Indefinite map */
|
||||
cbor_collection_callback map_start;
|
||||
|
||||
/** Tags */
|
||||
cbor_int64_callback tag;
|
||||
|
||||
/** Half float */
|
||||
cbor_float_callback float2;
|
||||
/** Single float */
|
||||
cbor_float_callback float4;
|
||||
/** Double float */
|
||||
cbor_double_callback float8;
|
||||
/** Undef */
|
||||
cbor_simple_callback undefined;
|
||||
/** Null */
|
||||
cbor_simple_callback null;
|
||||
/** Bool */
|
||||
cbor_bool_callback boolean;
|
||||
|
||||
/** Indefinite item break */
|
||||
cbor_simple_callback indef_break;
|
||||
};
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_uint8_callback(void *, uint8_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_uint16_callback(void *, uint16_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_uint32_callback(void *, uint32_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_uint64_callback(void *, uint64_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_negint8_callback(void *, uint8_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_negint16_callback(void *, uint16_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_negint32_callback(void *, uint32_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_negint64_callback(void *, uint64_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_string_callback(void *, cbor_data, size_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_string_start_callback(void *);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_byte_string_callback(void *, cbor_data, size_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_byte_string_start_callback(void *);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_array_start_callback(void *, size_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_indef_array_start_callback(void *);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_map_start_callback(void *, size_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_indef_map_start_callback(void *);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_tag_callback(void *, uint64_t);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_float2_callback(void *, float);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_float4_callback(void *, float);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_float8_callback(void *, double);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_null_callback(void *);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_undefined_callback(void *);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_boolean_callback(void *, bool);
|
||||
|
||||
/** Dummy callback implementation - does nothing */
|
||||
void cbor_null_indef_break_callback(void *);
|
||||
|
||||
/** Dummy callback bundle - does nothing */
|
||||
extern const struct cbor_callbacks cbor_empty_callbacks;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //LIBCBOR_CALLBACKS_H
|
188
lib/libcbor/src/cbor/common.c
Normal file
188
lib/libcbor/src/cbor/common.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "cbor/common.h"
|
||||
#include "arrays.h"
|
||||
#include "bytestrings.h"
|
||||
#include "data.h"
|
||||
#include "floats_ctrls.h"
|
||||
#include "ints.h"
|
||||
#include "maps.h"
|
||||
#include "strings.h"
|
||||
#include "tags.h"
|
||||
|
||||
bool cbor_isa_uint(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_UINT;
|
||||
}
|
||||
|
||||
bool cbor_isa_negint(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_NEGINT;
|
||||
}
|
||||
|
||||
bool cbor_isa_bytestring(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_BYTESTRING;
|
||||
}
|
||||
|
||||
bool cbor_isa_string(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_STRING;
|
||||
}
|
||||
|
||||
bool cbor_isa_array(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_ARRAY;
|
||||
}
|
||||
|
||||
bool cbor_isa_map(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_MAP;
|
||||
}
|
||||
|
||||
bool cbor_isa_tag(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_TAG;
|
||||
}
|
||||
|
||||
bool cbor_isa_float_ctrl(const cbor_item_t *item)
|
||||
{
|
||||
return item->type == CBOR_TYPE_FLOAT_CTRL;
|
||||
}
|
||||
|
||||
|
||||
cbor_type cbor_typeof(const cbor_item_t *item)
|
||||
{
|
||||
return item->type;
|
||||
}
|
||||
|
||||
|
||||
bool cbor_is_int(const cbor_item_t *item)
|
||||
{
|
||||
return cbor_isa_uint(item) || cbor_isa_negint(item);
|
||||
}
|
||||
|
||||
|
||||
bool cbor_is_bool(const cbor_item_t *item)
|
||||
{
|
||||
return cbor_isa_float_ctrl(item) &&
|
||||
(cbor_ctrl_value(item) == CBOR_CTRL_FALSE || cbor_ctrl_value(item) == CBOR_CTRL_TRUE);
|
||||
}
|
||||
|
||||
bool cbor_is_null(const cbor_item_t *item)
|
||||
{
|
||||
return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL;
|
||||
}
|
||||
|
||||
bool cbor_is_undef(const cbor_item_t *item)
|
||||
{
|
||||
return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF;
|
||||
}
|
||||
|
||||
bool cbor_is_float(const cbor_item_t *item)
|
||||
{
|
||||
return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item);
|
||||
}
|
||||
|
||||
|
||||
cbor_item_t * cbor_incref(cbor_item_t *item)
|
||||
{
|
||||
item->refcount++;
|
||||
return item;
|
||||
}
|
||||
|
||||
void cbor_decref(cbor_item_t **item_ref)
|
||||
{
|
||||
cbor_item_t * item = *item_ref;
|
||||
if (--item->refcount == 0) {
|
||||
switch (item->type) {
|
||||
case CBOR_TYPE_UINT:
|
||||
/* Fallthrough */
|
||||
case CBOR_TYPE_NEGINT:
|
||||
/* Combined allocation, freeing the item suffices */
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_BYTESTRING: {
|
||||
if (cbor_bytestring_is_definite(item)) {
|
||||
_CBOR_FREE(item->data);
|
||||
} else {
|
||||
/* We need to decref all chunks */
|
||||
cbor_item_t **handle = cbor_bytestring_chunks_handle(item);
|
||||
for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
|
||||
cbor_decref(&handle[i]);
|
||||
_CBOR_FREE(((struct cbor_indefinite_string_data *) item->data)->chunks);
|
||||
_CBOR_FREE(item->data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_STRING: {
|
||||
if (cbor_string_is_definite(item)) {
|
||||
_CBOR_FREE(item->data);
|
||||
} else {
|
||||
/* We need to decref all chunks */
|
||||
cbor_item_t **handle = cbor_string_chunks_handle(item);
|
||||
for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
|
||||
cbor_decref(&handle[i]);
|
||||
_CBOR_FREE(((struct cbor_indefinite_string_data *) item->data)->chunks);
|
||||
_CBOR_FREE(item->data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_ARRAY: {
|
||||
/* Get all items and decref them */
|
||||
cbor_item_t **handle = cbor_array_handle(item);
|
||||
size_t size = cbor_array_size(item);
|
||||
for (size_t i = 0; i < size; i++)
|
||||
if (handle[i] != NULL)
|
||||
cbor_decref(&handle[i]);
|
||||
_CBOR_FREE(item->data);
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_MAP: {
|
||||
struct cbor_pair *handle = cbor_map_handle(item);
|
||||
for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; i++, handle++) {
|
||||
cbor_decref(&handle->key);
|
||||
if (handle->value != NULL)
|
||||
cbor_decref(&handle->value);
|
||||
}
|
||||
_CBOR_FREE(item->data);
|
||||
break;
|
||||
};
|
||||
case CBOR_TYPE_TAG: {
|
||||
if (item->metadata.tag_metadata.tagged_item != NULL)
|
||||
cbor_decref(&item->metadata.tag_metadata.tagged_item);
|
||||
_CBOR_FREE(item->data);
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_FLOAT_CTRL: {
|
||||
/* Floats have combined allocation */
|
||||
break;
|
||||
}
|
||||
}
|
||||
_CBOR_FREE(item);
|
||||
//TODO
|
||||
*item_ref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_intermediate_decref(cbor_item_t * item)
|
||||
{
|
||||
cbor_decref(&item);
|
||||
}
|
||||
|
||||
size_t cbor_refcount(const cbor_item_t * item)
|
||||
{
|
||||
return item->refcount;
|
||||
}
|
||||
|
||||
cbor_item_t * cbor_move(cbor_item_t * item)
|
||||
{
|
||||
item->refcount--;
|
||||
return item;
|
||||
}
|
261
lib/libcbor/src/cbor/common.h
Normal file
261
lib/libcbor/src/cbor/common.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_COMMON_H
|
||||
#define LIBCBOR_COMMON_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "data.h"
|
||||
#include "cbor/configuration.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
/** C++ is not a subset of C99 -- 'restrict' qualifier is not a part of the language.
|
||||
* This is a workaround to keep it in C headers -- compilers allow linking non-restrict
|
||||
* signatures with restrict implementations.
|
||||
*
|
||||
* If you know a nicer way, please do let me know.
|
||||
*/
|
||||
#define CBOR_RESTRICT_POINTER
|
||||
|
||||
#else
|
||||
|
||||
// MSVC + C++ workaround
|
||||
#define CBOR_RESTRICT_POINTER CBOR_RESTRICT_SPECIFIER
|
||||
|
||||
#endif
|
||||
|
||||
static const uint8_t cbor_major_version = CBOR_MAJOR_VERSION;
|
||||
static const uint8_t cbor_minor_version = CBOR_MINOR_VERSION;
|
||||
static const uint8_t cbor_patch_version = CBOR_PATCH_VERSION;
|
||||
|
||||
#define CBOR_VERSION TO_STR(CBOR_MAJOR_VERSION) "." TO_STR(CBOR_MINOR_VERSION) "." TO_STR(CBOR_PATCH_VERSION)
|
||||
#define CBOR_HEX_VERSION ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)
|
||||
|
||||
|
||||
/* http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing */
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#define debug_print(fmt, ...) do { \
|
||||
if (DEBUG) \
|
||||
fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define debug_print(fmt, ...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define TO_STR_(x) #x
|
||||
#define TO_STR(x) TO_STR_(x) /* enables proper double expansion */
|
||||
|
||||
#if CBOR_CUSTOM_ALLOC
|
||||
|
||||
typedef void * (* _cbor_malloc_t)(size_t);
|
||||
typedef void * (* _cbor_realloc_t)(void *, size_t);
|
||||
typedef void (* _cbor_free_t)(void *);
|
||||
|
||||
extern _cbor_malloc_t _cbor_malloc;
|
||||
extern _cbor_realloc_t _cbor_realloc;
|
||||
extern _cbor_free_t _cbor_free;
|
||||
|
||||
/** Sets the memory management routines to use.
|
||||
*
|
||||
* Only available when CBOR_CUSTOM_ALLOC is truthy
|
||||
*
|
||||
* \rst
|
||||
* .. warning:: This function modifies the global state and should therefore be used accordingly. Changing the memory handlers while allocated items exist will result in a ``free``/``malloc`` mismatch. This function is not thread safe with respect to both itself and all the other *libcbor* functions that work with the heap.
|
||||
* .. note:: `realloc` implementation must correctly support `NULL` reallocation
|
||||
* \endrst
|
||||
*
|
||||
* @param custom_malloc malloc implementation
|
||||
* @param custom_realloc realloc implementation
|
||||
* @param custom_free free implementation
|
||||
*/
|
||||
void cbor_set_allocs(_cbor_malloc_t custom_malloc, _cbor_realloc_t custom_realloc, _cbor_free_t custom_free);
|
||||
|
||||
#define _CBOR_MALLOC _cbor_malloc
|
||||
#define _CBOR_REALLOC _cbor_realloc
|
||||
#define _CBOR_FREE _cbor_free
|
||||
|
||||
#else
|
||||
|
||||
#define _CBOR_MALLOC malloc
|
||||
#define _CBOR_REALLOC realloc
|
||||
#define _CBOR_FREE free
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Type manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Get the type of the item
|
||||
*
|
||||
* @param item[borrow]
|
||||
* @return The type
|
||||
*/
|
||||
cbor_type cbor_typeof(const cbor_item_t * item); /* Will be inlined iff link-time opt is enabled */
|
||||
|
||||
/* Standard item types as described by the RFC */
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item an #CBOR_TYPE_UINT?
|
||||
*/
|
||||
bool cbor_isa_uint(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a #CBOR_TYPE_NEGINT?
|
||||
*/
|
||||
bool cbor_isa_negint(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a #CBOR_TYPE_BYTESTRING?
|
||||
*/
|
||||
bool cbor_isa_bytestring(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a #CBOR_TYPE_STRING?
|
||||
*/
|
||||
bool cbor_isa_string(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item an #CBOR_TYPE_ARRAY?
|
||||
*/
|
||||
bool cbor_isa_array(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a #CBOR_TYPE_MAP?
|
||||
*/
|
||||
bool cbor_isa_map(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a #CBOR_TYPE_TAG?
|
||||
*/
|
||||
bool cbor_isa_tag(const cbor_item_t * item);
|
||||
|
||||
/** Does the item have the appropriate major type?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a #CBOR_TYPE_FLOAT_CTRL?
|
||||
*/
|
||||
bool cbor_isa_float_ctrl(const cbor_item_t * item);
|
||||
|
||||
/* Practical types with respect to their semantics (but not tag values) */
|
||||
|
||||
/** Is the item an integer, either positive or negative?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item an integer, either positive or negative?
|
||||
*/
|
||||
bool cbor_is_int(const cbor_item_t * item);
|
||||
|
||||
/** Is the item an a floating point number?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a floating point number?
|
||||
*/
|
||||
bool cbor_is_float(const cbor_item_t * item);
|
||||
|
||||
/** Is the item an a boolean?
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item a boolean?
|
||||
*/
|
||||
bool cbor_is_bool(const cbor_item_t * item);
|
||||
|
||||
/** Does this item represent `null`
|
||||
* \rst
|
||||
* .. warning:: This is in no way related to the value of the pointer. Passing a null pointer will most likely result in a crash.
|
||||
* \endrst
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item (CBOR logical) null?
|
||||
*/
|
||||
bool cbor_is_null(const cbor_item_t * item);
|
||||
|
||||
|
||||
/** Does this item represent `undefined`
|
||||
* \rst
|
||||
* .. warning:: Care must be taken to distinguish nulls and undefined values in C.
|
||||
* \endrst
|
||||
* @param item[borrow] the item
|
||||
* @return Is the item (CBOR logical) undefined?
|
||||
*/
|
||||
bool cbor_is_undef(const cbor_item_t * item);
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Memory management
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Increases the reference count by one
|
||||
*
|
||||
* No dependent items are affected.
|
||||
*
|
||||
* @param item[incref] item the item
|
||||
* @return the input reference
|
||||
*/
|
||||
cbor_item_t * cbor_incref(cbor_item_t * item);
|
||||
|
||||
/** Decreases the reference count by one, deallocating the item if needed
|
||||
*
|
||||
* In case the item is deallocated, the reference count of any dependent items
|
||||
* is adjusted accordingly in a recursive manner.
|
||||
*
|
||||
* @param item[take] the item. Set to `NULL` if deallocated
|
||||
*/
|
||||
void cbor_decref(cbor_item_t ** item);
|
||||
|
||||
/** Decreases the reference count by one, deallocating the item if needed
|
||||
*
|
||||
* Convenience wrapper for #cbor_decref when its set-to-null behavior is not needed
|
||||
*
|
||||
* @param item[take] the item
|
||||
*/
|
||||
void cbor_intermediate_decref(cbor_item_t * item);
|
||||
|
||||
/** Get the reference count
|
||||
*
|
||||
* \rst
|
||||
* .. warning:: This does *not* account for transitive references.
|
||||
* \endrst
|
||||
*
|
||||
* @param item[borrow] the item
|
||||
* @return the reference count
|
||||
*/
|
||||
size_t cbor_refcount(const cbor_item_t * item);
|
||||
|
||||
/** Provides CPP-like move construct
|
||||
*
|
||||
* Decreases the reference count by one, but does not deallocate the item even if its refcount
|
||||
* reaches zero. This is useful for passing intermediate values to functions that increase
|
||||
* reference count. Should only be used with functions that `incref` their arguments.
|
||||
*
|
||||
* \rst
|
||||
* .. warning:: If the item is moved without correctly increasing the reference count afterwards, the memory will be leaked.
|
||||
* \endrst
|
||||
*
|
||||
* @param item[take] the item
|
||||
* @return the item with reference count decreased by one
|
||||
*/
|
||||
cbor_item_t * cbor_move(cbor_item_t * item);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_COMMON_H
|
15
lib/libcbor/src/cbor/configuration.h
Normal file
15
lib/libcbor/src/cbor/configuration.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef LIBCBOR_CONFIGURATION_H
|
||||
#define LIBCBOR_CONFIGURATION_H
|
||||
|
||||
#define CBOR_MAJOR_VERSION 0
|
||||
#define CBOR_MINOR_VERSION 5
|
||||
#define CBOR_PATCH_VERSION 0
|
||||
|
||||
#define CBOR_CUSTOM_ALLOC 0
|
||||
#define CBOR_BUFFER_GROWTH 2
|
||||
#define CBOR_PRETTY_PRINTER 1
|
||||
|
||||
#define CBOR_RESTRICT_SPECIFIER restrict
|
||||
#define CBOR_INLINE_SPECIFIER
|
||||
|
||||
#endif //LIBCBOR_CONFIGURATION_H
|
15
lib/libcbor/src/cbor/configuration.h.in
Normal file
15
lib/libcbor/src/cbor/configuration.h.in
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef LIBCBOR_CONFIGURATION_H
|
||||
#define LIBCBOR_CONFIGURATION_H
|
||||
|
||||
#define CBOR_MAJOR_VERSION ${CBOR_VERSION_MAJOR}
|
||||
#define CBOR_MINOR_VERSION ${CBOR_VERSION_MINOR}
|
||||
#define CBOR_PATCH_VERSION ${CBOR_VERSION_PATCH}
|
||||
|
||||
#cmakedefine01 CBOR_CUSTOM_ALLOC
|
||||
#define CBOR_BUFFER_GROWTH ${CBOR_BUFFER_GROWTH}
|
||||
#cmakedefine01 CBOR_PRETTY_PRINTER
|
||||
|
||||
#define CBOR_RESTRICT_SPECIFIER ${CBOR_RESTRICT_SPECIFIER}
|
||||
#define CBOR_INLINE_SPECIFIER ${CBOR_INLINE_SPECIFIER}
|
||||
|
||||
#endif //LIBCBOR_CONFIGURATION_H
|
212
lib/libcbor/src/cbor/data.h
Normal file
212
lib/libcbor/src/cbor/data.h
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_DATA_H
|
||||
#define LIBCBOR_DATA_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef const unsigned char * cbor_data;
|
||||
typedef unsigned char * cbor_mutable_data;
|
||||
|
||||
/** Specifies the Major type of ::cbor_item_t */
|
||||
typedef enum cbor_type {
|
||||
CBOR_TYPE_UINT /** 0 - positive integers */
|
||||
,CBOR_TYPE_NEGINT /** 1 - negative integers*/
|
||||
,CBOR_TYPE_BYTESTRING /** 2 - byte strings */
|
||||
,CBOR_TYPE_STRING /** 3 - strings */
|
||||
,CBOR_TYPE_ARRAY /** 4 - arrays */
|
||||
,CBOR_TYPE_MAP /** 5 - maps */
|
||||
,CBOR_TYPE_TAG /** 6 - tags */
|
||||
,CBOR_TYPE_FLOAT_CTRL /** 7 - decimals and special values (true, false, nil, ...) */
|
||||
} cbor_type;
|
||||
|
||||
/** Possible decoding errors */
|
||||
typedef enum {
|
||||
CBOR_ERR_NONE
|
||||
,CBOR_ERR_NOTENOUGHDATA
|
||||
,CBOR_ERR_NODATA
|
||||
,CBOR_ERR_MALFORMATED
|
||||
,CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for your allocator? */
|
||||
,CBOR_ERR_SYNTAXERROR /** Stack parsing algorithm failed */
|
||||
} cbor_error_code;
|
||||
|
||||
/** Possible widths of #CBOR_TYPE_UINT items */
|
||||
typedef enum {
|
||||
CBOR_INT_8
|
||||
,CBOR_INT_16
|
||||
,CBOR_INT_32
|
||||
,CBOR_INT_64
|
||||
} cbor_int_width;
|
||||
|
||||
/** Possible widths of #CBOR_TYPE_FLOAT_CTRL items */
|
||||
typedef enum {
|
||||
CBOR_FLOAT_0 /** Internal use - ctrl and special values */
|
||||
,CBOR_FLOAT_16 /** Half float */
|
||||
,CBOR_FLOAT_32 /** Single float */
|
||||
,CBOR_FLOAT_64 /** Double */
|
||||
} cbor_float_width;
|
||||
|
||||
/** Metadata for dynamically sized types */
|
||||
typedef enum {
|
||||
_CBOR_METADATA_DEFINITE
|
||||
,_CBOR_METADATA_INDEFINITE
|
||||
} _cbor_dst_metadata;
|
||||
|
||||
/** Semantic mapping for CTRL simple values */
|
||||
typedef enum {
|
||||
CBOR_CTRL_NONE = 0,
|
||||
CBOR_CTRL_FALSE = 20,
|
||||
CBOR_CTRL_TRUE = 21,
|
||||
CBOR_CTRL_NULL = 22,
|
||||
CBOR_CTRL_UNDEF = 23
|
||||
} _cbor_ctrl;
|
||||
|
||||
/** Integers specific metadata */
|
||||
struct _cbor_int_metadata {
|
||||
cbor_int_width width;
|
||||
};
|
||||
|
||||
/** Bytestrings specific metadata */
|
||||
struct _cbor_bytestring_metadata {
|
||||
size_t length;
|
||||
_cbor_dst_metadata type;
|
||||
};
|
||||
|
||||
/** Strings specific metadata */
|
||||
struct _cbor_string_metadata {
|
||||
size_t length;
|
||||
size_t codepoint_count; /* Sum of chunks' codepoint_counts for indefinite strings */
|
||||
_cbor_dst_metadata type;
|
||||
};
|
||||
|
||||
/** Arrays specific metadata */
|
||||
struct _cbor_array_metadata {
|
||||
size_t allocated;
|
||||
size_t end_ptr;
|
||||
_cbor_dst_metadata type;
|
||||
};
|
||||
|
||||
/** Maps specific metadata */
|
||||
struct _cbor_map_metadata {
|
||||
size_t allocated;
|
||||
size_t end_ptr;
|
||||
_cbor_dst_metadata type;
|
||||
};
|
||||
|
||||
/** Arrays specific metadata
|
||||
*
|
||||
* The pointer is included - cbor_item_metadata is
|
||||
* 2 * sizeof(size_t) + sizeof(_cbor_string_type_metadata),
|
||||
* lets use the space
|
||||
*/
|
||||
struct _cbor_tag_metadata {
|
||||
struct cbor_item_t * tagged_item;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
/** Floats specific metadata - includes CTRL values */
|
||||
struct _cbor_float_ctrl_metadata {
|
||||
cbor_float_width width;
|
||||
uint8_t ctrl;
|
||||
};
|
||||
|
||||
/** Raw memory casts helper */
|
||||
union _cbor_float_helper {
|
||||
float as_float;
|
||||
uint32_t as_uint;
|
||||
};
|
||||
|
||||
/** Raw memory casts helper */
|
||||
union _cbor_double_helper {
|
||||
double as_double;
|
||||
uint64_t as_uint;
|
||||
};
|
||||
|
||||
/** Union of metadata across all possible types - discriminated in #cbor_item_t */
|
||||
union cbor_item_metadata {
|
||||
struct _cbor_int_metadata int_metadata;
|
||||
struct _cbor_bytestring_metadata bytestring_metadata;
|
||||
struct _cbor_string_metadata string_metadata;
|
||||
struct _cbor_array_metadata array_metadata;
|
||||
struct _cbor_map_metadata map_metadata;
|
||||
struct _cbor_tag_metadata tag_metadata;
|
||||
struct _cbor_float_ctrl_metadata float_ctrl_metadata;
|
||||
};
|
||||
|
||||
/** The item handle */
|
||||
typedef struct cbor_item_t {
|
||||
/** Discriminated by type */
|
||||
union cbor_item_metadata metadata;
|
||||
/** Reference count - initialize to 0 */
|
||||
size_t refcount;
|
||||
/** Major type discriminator */
|
||||
cbor_type type;
|
||||
/** Raw data block - interpretation depends on metadata */
|
||||
unsigned char * data;
|
||||
} cbor_item_t;
|
||||
|
||||
/** Defines cbor_item_t#data structure for indefinite strings and bytestrings
|
||||
*
|
||||
* Used to cast the raw representation for a sane manipulation
|
||||
*/
|
||||
struct cbor_indefinite_string_data {
|
||||
size_t chunk_count;
|
||||
size_t chunk_capacity;
|
||||
cbor_item_t * * chunks;
|
||||
};
|
||||
|
||||
/** High-level decoding error */
|
||||
struct cbor_error {
|
||||
/** Aproximate position */
|
||||
size_t position;
|
||||
/** Description */
|
||||
cbor_error_code code;
|
||||
};
|
||||
|
||||
/** Simple pair of items for use in maps */
|
||||
struct cbor_pair {
|
||||
cbor_item_t * key, * value;
|
||||
};
|
||||
|
||||
/** High-level decoding result */
|
||||
struct cbor_load_result {
|
||||
/** Error indicator */
|
||||
struct cbor_error error;
|
||||
/** Number of bytes read*/
|
||||
size_t read;
|
||||
};
|
||||
|
||||
|
||||
/** Streaming decoder result - status */
|
||||
enum cbor_decoder_status {
|
||||
CBOR_DECODER_FINISHED /** OK, finished */
|
||||
,CBOR_DECODER_NEDATA /** Not enough data - mismatch with MTB */
|
||||
,CBOR_DECODER_EBUFFER /** Buffer manipulation problem */
|
||||
,CBOR_DECODER_ERROR /** Malformed or reserved MTB/value */
|
||||
};
|
||||
|
||||
/** Streaming decoder result */
|
||||
struct cbor_decoder_result {
|
||||
/** Bytes read */
|
||||
size_t read;
|
||||
/** The result */
|
||||
enum cbor_decoder_status status;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_DATA_H
|
186
lib/libcbor/src/cbor/encoding.c
Normal file
186
lib/libcbor/src/cbor/encoding.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "encoding.h"
|
||||
#include "internal/encoders.h"
|
||||
|
||||
size_t cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint8(value, buffer, buffer_size, 0x00);
|
||||
}
|
||||
|
||||
size_t cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint16(value, buffer, buffer_size, 0x00);
|
||||
}
|
||||
|
||||
size_t cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint32(value, buffer, buffer_size, 0x00);
|
||||
}
|
||||
|
||||
size_t cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint64(value, buffer, buffer_size, 0x00);
|
||||
}
|
||||
|
||||
size_t cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint(value, buffer, buffer_size, 0x00);
|
||||
}
|
||||
|
||||
|
||||
size_t cbor_encode_negint8(uint8_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint8(value, buffer, buffer_size, 0x20);
|
||||
}
|
||||
|
||||
size_t cbor_encode_negint16(uint16_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint16(value, buffer, buffer_size, 0x20);
|
||||
}
|
||||
|
||||
size_t cbor_encode_negint32(uint32_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint32(value, buffer, buffer_size, 0x20);
|
||||
}
|
||||
|
||||
size_t cbor_encode_negint64(uint64_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint64(value, buffer, buffer_size, 0x20);
|
||||
}
|
||||
|
||||
size_t cbor_encode_negint(uint64_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint(value, buffer, buffer_size, 0x20);
|
||||
}
|
||||
|
||||
size_t cbor_encode_bytestring_start(size_t length, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x40);
|
||||
}
|
||||
|
||||
size_t _cbor_encode_byte(uint8_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
if (buffer_size >= 1) {
|
||||
buffer[0] = value;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t cbor_encode_indef_bytestring_start(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0x5F, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_string_start(size_t length, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x60);
|
||||
}
|
||||
|
||||
size_t cbor_encode_indef_string_start(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0x7F, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_array_start(size_t length, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x80);
|
||||
}
|
||||
|
||||
size_t cbor_encode_indef_array_start(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0x9F, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_map_start(size_t length, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0xA0);
|
||||
}
|
||||
|
||||
size_t cbor_encode_indef_map_start(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0xBF, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_tag(uint64_t value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint(value, buffer, buffer_size, 0xC0);
|
||||
}
|
||||
|
||||
size_t cbor_encode_bool(bool value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return value ? _cbor_encode_byte(0xF5, buffer, buffer_size) : _cbor_encode_byte(0xF4, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_null(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0xF6, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_undef(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0xF7, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_half(float value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
/* Assuming value is normalized */
|
||||
uint32_t val = ((union _cbor_float_helper) {.as_float = value}).as_uint;
|
||||
uint16_t res;
|
||||
uint8_t exp = (uint8_t) ((val & 0x7F800000) >> 23); /* 0b0111_1111_1000_0000_0000_0000_0000_0000 */
|
||||
uint32_t mant = val & 0x7FFFFF; /* 0b0000_0000_0111_1111_1111_1111_1111_1111 */
|
||||
if (exp == 0xFF) { /* Infinity or NaNs */
|
||||
if (value != value) {
|
||||
res = (uint16_t) 0x00e700; /* Not IEEE semantics - required by CBOR [s. 3.9] */
|
||||
} else {
|
||||
res = (uint16_t) ((val & 0x80000000) >> 16 | 0x7C00 | (mant ? 1 : 0) << 15);
|
||||
}
|
||||
} else if (exp == 0x00) { /* Zeroes or subnorms */
|
||||
res = (uint16_t) ((val & 0x80000000) >> 16 | mant >> 13);
|
||||
} else { /* Normal numbers */
|
||||
int8_t logical_exp = (int8_t) (exp - 127);
|
||||
assert(logical_exp == exp - 127);
|
||||
|
||||
// Now we know that 2^exp <= 0 logically
|
||||
if (logical_exp < -24) {
|
||||
/* No unambiguous representation exists, this float is not a half float and is too small to
|
||||
be represented using a half, round off to zero. Consistent with the reference implementation. */
|
||||
res = 0;
|
||||
} else if (logical_exp < -14) {
|
||||
/* Offset the remaining decimal places by shifting the significand, the value is lost.
|
||||
This is an implementation decision that works around the absence of standard half-float
|
||||
in the language. */
|
||||
res = (uint16_t) (val & 0x80000000) >> 16 | (uint16_t) (1 << (24 + logical_exp));
|
||||
} else {
|
||||
res = (uint16_t) ((val & 0x80000000) >> 16 | ((((uint8_t) logical_exp) + 15) << 10) | (uint16_t) (mant >> 13));
|
||||
}
|
||||
}
|
||||
return _cbor_encode_uint16(res, buffer, buffer_size, 0xE0);
|
||||
}
|
||||
|
||||
size_t cbor_encode_single(float value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
|
||||
return _cbor_encode_uint32(((union _cbor_float_helper) {.as_float = value}).as_uint, buffer, buffer_size, 0xE0);
|
||||
}
|
||||
|
||||
size_t cbor_encode_double(double value, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint64(((union _cbor_double_helper) {.as_double = value}).as_uint, buffer, buffer_size, 0xE0);
|
||||
}
|
||||
|
||||
size_t cbor_encode_break(unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_byte(0xFF, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t cbor_encode_ctrl(uint8_t value, unsigned char * buffer, size_t buffer_size)
|
||||
{
|
||||
return _cbor_encode_uint8(value, buffer, buffer_size, 0xE0);
|
||||
}
|
107
lib/libcbor/src/cbor/encoding.h
Normal file
107
lib/libcbor/src/cbor/encoding.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_ENCODING_H
|
||||
#define LIBCBOR_ENCODING_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Primitives encoding
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
size_t cbor_encode_uint8(uint8_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_uint16(uint16_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_uint32(uint32_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_uint64(uint64_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_uint(uint64_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_negint8(uint8_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_negint16(uint16_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_negint32(uint32_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_negint64(uint64_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_negint(uint64_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_bytestring_start(size_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_indef_bytestring_start(unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_string_start(size_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_indef_string_start(unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_array_start(size_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_indef_array_start(unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_map_start(size_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_indef_map_start(unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_tag(uint64_t, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_bool(bool, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_null(unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_undef(unsigned char *, size_t);
|
||||
|
||||
/** Encodes a half-precision float
|
||||
*
|
||||
* Since there is no native representation or semantics for half floats
|
||||
* in the language, we use single-precision floats, as every value that
|
||||
* can be expressed as a half-float can also be expressed as a float.
|
||||
*
|
||||
* This however means that not all floats passed to this function can be
|
||||
* unambiguously encoded. The behavior is as follows:
|
||||
* - Infinity, NaN are preserved
|
||||
* - Zero is preserved
|
||||
* - Denormalized numbers keep their sign bit and 10 most significant bit of the significand
|
||||
* - All other numbers
|
||||
* - If the logical value of the exponent is < -24, the output is zero
|
||||
* - If the logical value of the exponent is between -23 and -14, the output
|
||||
* is cut off to represent the 'magnitude' of the input, by which we
|
||||
* mean (-1)^{signbit} x 1.0e{exponent}. The value in the significand is lost.
|
||||
* - In all other cases, the sign bit, the exponent, and 10 most significant bits
|
||||
* of the significand are kept
|
||||
*
|
||||
* @param value
|
||||
* @param buffer Target buffer
|
||||
* @param buffer_size Available space in the buffer
|
||||
* @return number of bytes written
|
||||
*/
|
||||
size_t cbor_encode_half(float, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_single(float, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_double(double, unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_break(unsigned char *, size_t);
|
||||
|
||||
size_t cbor_encode_ctrl(uint8_t, unsigned char *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //LIBCBOR_ENCODING_H
|
191
lib/libcbor/src/cbor/floats_ctrls.c
Normal file
191
lib/libcbor/src/cbor/floats_ctrls.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "floats_ctrls.h"
|
||||
#include "assert.h"
|
||||
#include <math.h>
|
||||
|
||||
cbor_float_width cbor_float_get_width(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_float_ctrl(item));
|
||||
return item->metadata.float_ctrl_metadata.width;
|
||||
}
|
||||
|
||||
uint8_t cbor_ctrl_value(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_float_ctrl(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_0);
|
||||
return item->metadata.float_ctrl_metadata.ctrl;
|
||||
}
|
||||
|
||||
bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_float_ctrl(item));
|
||||
return cbor_float_get_width(item) == CBOR_FLOAT_0;
|
||||
}
|
||||
|
||||
float cbor_float_get_float2(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_16);
|
||||
return *(float *) item->data;
|
||||
}
|
||||
|
||||
float cbor_float_get_float4(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_32);
|
||||
return *(float *) item->data;
|
||||
}
|
||||
|
||||
double cbor_float_get_float8(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_64);
|
||||
return *(double *) item->data;
|
||||
}
|
||||
|
||||
double cbor_float_get_float(const cbor_item_t * item)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
switch(cbor_float_get_width(item)) {
|
||||
case CBOR_FLOAT_0: return NAN;
|
||||
case CBOR_FLOAT_16: return cbor_float_get_float2(item);
|
||||
case CBOR_FLOAT_32: return cbor_float_get_float4(item);
|
||||
case CBOR_FLOAT_64: return cbor_float_get_float8(item);
|
||||
}
|
||||
return NAN; /* Compiler complaints */
|
||||
}
|
||||
|
||||
void cbor_set_float2(cbor_item_t *item, float value)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_16);
|
||||
*((float *) item->data) = value;
|
||||
}
|
||||
|
||||
void cbor_set_float4(cbor_item_t *item, float value)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_32);
|
||||
*((float *) item->data) = value;
|
||||
}
|
||||
|
||||
void cbor_set_float8(cbor_item_t *item, double value)
|
||||
{
|
||||
assert(cbor_is_float(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_64);
|
||||
*((double *) item->data) = value;
|
||||
}
|
||||
|
||||
void cbor_set_ctrl(cbor_item_t *item, uint8_t value)
|
||||
{
|
||||
assert(cbor_isa_float_ctrl(item));
|
||||
assert(cbor_float_get_width(item) == CBOR_FLOAT_0);
|
||||
item->metadata.float_ctrl_metadata.ctrl = value;
|
||||
}
|
||||
|
||||
bool cbor_ctrl_is_bool(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_bool(item));
|
||||
return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_ctrl()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
*item = (cbor_item_t) {
|
||||
.type = CBOR_TYPE_FLOAT_CTRL,
|
||||
.data = NULL,
|
||||
.refcount = 1,
|
||||
.metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0, .ctrl = CBOR_CTRL_NONE}}
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_float2()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
|
||||
*item = (cbor_item_t) {
|
||||
.type = CBOR_TYPE_FLOAT_CTRL,
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}}
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_float4()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
|
||||
*item = (cbor_item_t) {
|
||||
.type = CBOR_TYPE_FLOAT_CTRL,
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}}
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_float8()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8);
|
||||
*item = (cbor_item_t) {
|
||||
.type = CBOR_TYPE_FLOAT_CTRL,
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}}
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_null()
|
||||
{
|
||||
cbor_item_t *item = cbor_new_ctrl();
|
||||
cbor_set_ctrl(item, CBOR_CTRL_NULL);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_undef()
|
||||
{
|
||||
cbor_item_t *item = cbor_new_ctrl();
|
||||
cbor_set_ctrl(item, CBOR_CTRL_UNDEF);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_bool(bool value)
|
||||
{
|
||||
return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_float2(float value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_float2();
|
||||
cbor_set_float2(item, value);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_float4(float value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_float4();
|
||||
cbor_set_float4(item, value);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_float8(double value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_float8();
|
||||
cbor_set_float8(item, value);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_ctrl(uint8_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_ctrl();
|
||||
cbor_set_ctrl(item, value);
|
||||
return item;
|
||||
}
|
203
lib/libcbor/src/cbor/floats_ctrls.h
Normal file
203
lib/libcbor/src/cbor/floats_ctrls.h
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_FLOATS_CTRLS_H
|
||||
#define LIBCBOR_FLOATS_CTRLS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Float manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Is this a ctrl value?
|
||||
*
|
||||
* @param item[borrow] A float or ctrl item
|
||||
* @return Is this a ctrl value?
|
||||
*/
|
||||
bool cbor_float_ctrl_is_ctrl(const cbor_item_t * item);
|
||||
|
||||
/** Get the float width
|
||||
*
|
||||
* @param item[borrow] A float or ctrl item
|
||||
* @return The width.
|
||||
*/
|
||||
cbor_float_width cbor_float_get_width(const cbor_item_t * item);
|
||||
|
||||
/** Get a half precision float
|
||||
*
|
||||
* The item must have the corresponding width
|
||||
*
|
||||
* @param[borrow] A half precision float
|
||||
* @return half precision value
|
||||
*/
|
||||
float cbor_float_get_float2(const cbor_item_t * item);
|
||||
|
||||
/** Get a single precision float
|
||||
*
|
||||
* The item must have the corresponding width
|
||||
*
|
||||
* @param[borrow] A signle precision float
|
||||
* @return single precision value
|
||||
*/
|
||||
float cbor_float_get_float4(const cbor_item_t * item);
|
||||
|
||||
/** Get a double precision float
|
||||
*
|
||||
* The item must have the corresponding width
|
||||
*
|
||||
* @param[borrow] A double precision float
|
||||
* @return double precision value
|
||||
*/
|
||||
double cbor_float_get_float8(const cbor_item_t * item);
|
||||
|
||||
/** Get the float value represented as double
|
||||
*
|
||||
* Can be used regardless of the width.
|
||||
*
|
||||
* @param[borrow] Any float
|
||||
* @return double precision value
|
||||
*/
|
||||
double cbor_float_get_float(const cbor_item_t * item);
|
||||
|
||||
/** Constructs a new ctrl item
|
||||
*
|
||||
* The width cannot be changed once the item is created
|
||||
*
|
||||
* @return **new** 1B ctrl
|
||||
*/
|
||||
cbor_item_t * cbor_new_ctrl();
|
||||
|
||||
/** Constructs a new float item
|
||||
*
|
||||
* The width cannot be changed once the item is created
|
||||
*
|
||||
* @return **new** 2B float
|
||||
*/
|
||||
cbor_item_t * cbor_new_float2();
|
||||
|
||||
/** Constructs a new float item
|
||||
*
|
||||
* The width cannot be changed once the item is created
|
||||
*
|
||||
* @return **new** 4B float
|
||||
*/
|
||||
cbor_item_t * cbor_new_float4();
|
||||
|
||||
/** Constructs a new float item
|
||||
*
|
||||
* The width cannot be changed once the item is created
|
||||
*
|
||||
* @return **new** 8B float
|
||||
*/
|
||||
cbor_item_t * cbor_new_float8();
|
||||
|
||||
/** Constructs new null ctrl item
|
||||
*
|
||||
* @return **new** null ctrl item
|
||||
*/
|
||||
cbor_item_t * cbor_new_null();
|
||||
|
||||
/** Constructs new under ctrl item
|
||||
*
|
||||
* @return **new** under ctrl item
|
||||
*/
|
||||
cbor_item_t * cbor_new_undef();
|
||||
|
||||
/** Constructs new boolean ctrl item
|
||||
*
|
||||
* @param value The value to use
|
||||
* @return **new** boolen ctrl item
|
||||
*/
|
||||
cbor_item_t * cbor_build_bool(bool value);
|
||||
|
||||
/** Assign a control value
|
||||
*
|
||||
* \rst
|
||||
* .. warning:: It is possible to produce an invalid CBOR value by assigning a invalid value using this mechanism. Please consult the standard before use.
|
||||
* \endrst
|
||||
*
|
||||
* @param item[borrow] A ctrl item
|
||||
* @param value The simple value to assign. Please consult the standard for allowed values
|
||||
*/
|
||||
void cbor_set_ctrl(cbor_item_t * item, uint8_t value);
|
||||
|
||||
/** Assigns a float value
|
||||
*
|
||||
* @param item[borrow] A half precision float
|
||||
* @param value The value to assign
|
||||
*/
|
||||
void cbor_set_float2(cbor_item_t * item, float value);
|
||||
|
||||
/** Assigns a float value
|
||||
*
|
||||
* @param item[borrow] A single precision float
|
||||
* @param value The value to assign
|
||||
*/
|
||||
void cbor_set_float4(cbor_item_t * item, float value);
|
||||
|
||||
/** Assigns a float value
|
||||
*
|
||||
* @param item[borrow] A double precision float
|
||||
* @param value The value to assign
|
||||
*/
|
||||
void cbor_set_float8(cbor_item_t * item, double value);
|
||||
|
||||
/** Reads the control value
|
||||
*
|
||||
* @param item[borrow] A ctrl item
|
||||
* @return the simple value
|
||||
*/
|
||||
uint8_t cbor_ctrl_value(const cbor_item_t * item);
|
||||
|
||||
/** Is this ctrl item a boolean?
|
||||
*
|
||||
* @param item[borrow] A ctrl item
|
||||
* @return Is this ctrl item a boolean?
|
||||
*/
|
||||
bool cbor_ctrl_is_bool(const cbor_item_t * item);
|
||||
|
||||
/** Constructs a new float
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** float
|
||||
*/
|
||||
cbor_item_t *cbor_build_float2(float value);
|
||||
|
||||
/** Constructs a new float
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** float
|
||||
*/
|
||||
cbor_item_t *cbor_build_float4(float value);
|
||||
|
||||
/** Constructs a new float
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** float
|
||||
*/
|
||||
cbor_item_t *cbor_build_float8(double value);
|
||||
|
||||
/** Constructs a ctrl item
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** ctrl item
|
||||
*/
|
||||
cbor_item_t *cbor_build_ctrl(uint8_t value);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_FLOATS_CTRLS_H
|
359
lib/libcbor/src/cbor/internal/builder_callbacks.c
Normal file
359
lib/libcbor/src/cbor/internal/builder_callbacks.c
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "builder_callbacks.h"
|
||||
#include "unicode.h"
|
||||
#include <string.h>
|
||||
#include "../arrays.h"
|
||||
#include "../bytestrings.h"
|
||||
#include "../floats_ctrls.h"
|
||||
#include "../ints.h"
|
||||
#include "../maps.h"
|
||||
#include "../strings.h"
|
||||
#include "../tags.h"
|
||||
|
||||
void _cbor_builder_append(cbor_item_t *item, struct _cbor_decoder_context *ctx)
|
||||
{
|
||||
if (ctx->stack->size == 0) {
|
||||
/* Top level item */
|
||||
ctx->root = item;
|
||||
} else {
|
||||
/* Part of a bigger structure */
|
||||
switch (ctx->stack->top->item->type) {
|
||||
case CBOR_TYPE_ARRAY: {
|
||||
if (cbor_array_is_definite(ctx->stack->top->item)) {
|
||||
assert(ctx->stack->top->subitems > 0);
|
||||
cbor_array_push(ctx->stack->top->item, item);
|
||||
ctx->stack->top->subitems--;
|
||||
if (ctx->stack->top->subitems == 0) {
|
||||
cbor_item_t *item = ctx->stack->top->item;
|
||||
_cbor_stack_pop(ctx->stack);
|
||||
_cbor_builder_append(item, ctx);
|
||||
}
|
||||
cbor_decref(&item);
|
||||
} else {
|
||||
/* Indefinite array, don't bother with subitems */
|
||||
cbor_array_push(ctx->stack->top->item, item);
|
||||
cbor_decref(&item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_MAP: {
|
||||
/* We use 0 and 1 subitems to distinguish between keys and values in indefinite items */
|
||||
if (ctx->stack->top->subitems % 2) {
|
||||
/* Odd record, this is a value */
|
||||
_cbor_map_add_value(ctx->stack->top->item, cbor_move(item));
|
||||
} else {
|
||||
/* Even record, this is a key */
|
||||
_cbor_map_add_key(ctx->stack->top->item, cbor_move(item));
|
||||
}
|
||||
if (cbor_map_is_definite(ctx->stack->top->item)) {
|
||||
ctx->stack->top->subitems--;
|
||||
if (ctx->stack->top->subitems == 0) {
|
||||
cbor_item_t *item = ctx->stack->top->item;
|
||||
_cbor_stack_pop(ctx->stack);
|
||||
_cbor_builder_append(item, ctx);
|
||||
}
|
||||
} else {
|
||||
ctx->stack->top->subitems ^= 1; /* Flip the indicator for indefinite items */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CBOR_TYPE_TAG: {
|
||||
assert(ctx->stack->top->subitems == 1);
|
||||
cbor_tag_set_item(ctx->stack->top->item, item);
|
||||
cbor_decref(&item); /* Give up on our reference */
|
||||
cbor_item_t *item = ctx->stack->top->item;
|
||||
_cbor_stack_pop(ctx->stack);
|
||||
_cbor_builder_append(item, ctx);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
cbor_decref(&item);
|
||||
ctx->syntax_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define CHECK_RES do { if (res == NULL) { ctx->creation_failed = true; return; } } while (0)
|
||||
|
||||
void cbor_builder_uint8_callback(void *context, uint8_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int8();
|
||||
CHECK_RES;
|
||||
cbor_mark_uint(res);
|
||||
cbor_set_uint8(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_uint16_callback(void *context, uint16_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int16();
|
||||
CHECK_RES;
|
||||
cbor_mark_uint(res);
|
||||
cbor_set_uint16(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_uint32_callback(void *context, uint32_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int32();
|
||||
CHECK_RES;
|
||||
cbor_mark_uint(res);
|
||||
cbor_set_uint32(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_uint64_callback(void *context, uint64_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int64();
|
||||
CHECK_RES;
|
||||
cbor_mark_uint(res);
|
||||
cbor_set_uint64(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_negint8_callback(void *context, uint8_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int8();
|
||||
CHECK_RES;
|
||||
cbor_mark_negint(res);
|
||||
cbor_set_uint8(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_negint16_callback(void *context, uint16_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int16();
|
||||
cbor_mark_negint(res);
|
||||
cbor_set_uint16(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_negint32_callback(void *context, uint32_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int32();
|
||||
CHECK_RES;
|
||||
cbor_mark_negint(res);
|
||||
cbor_set_uint32(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_negint64_callback(void *context, uint64_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_int64();
|
||||
CHECK_RES;
|
||||
cbor_mark_negint(res);
|
||||
cbor_set_uint64(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_byte_string_callback(void *context, cbor_data data, size_t length)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
unsigned char *new_handle = _CBOR_MALLOC(length);
|
||||
if (new_handle == NULL) {
|
||||
ctx->creation_failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(new_handle, data, length);
|
||||
cbor_item_t *res = cbor_new_definite_bytestring();
|
||||
|
||||
if (res == NULL) {
|
||||
_CBOR_FREE(new_handle);
|
||||
ctx->creation_failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
cbor_bytestring_set_handle(res, new_handle, length);
|
||||
|
||||
if (ctx->stack->size > 0 && cbor_isa_bytestring(ctx->stack->top->item)) {
|
||||
if (cbor_bytestring_is_indefinite(ctx->stack->top->item)) {
|
||||
cbor_bytestring_add_chunk(ctx->stack->top->item, cbor_move(res));
|
||||
} else {
|
||||
cbor_decref(&res);
|
||||
ctx->syntax_error = true;
|
||||
}
|
||||
} else {
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_builder_byte_string_start_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_indefinite_bytestring();
|
||||
CHECK_RES;
|
||||
_cbor_stack_push(ctx->stack, res, 0);
|
||||
}
|
||||
|
||||
|
||||
void cbor_builder_string_callback(void *context, cbor_data data, size_t length)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
struct _cbor_unicode_status unicode_status;
|
||||
|
||||
size_t codepoint_count = _cbor_unicode_codepoint_count(data, length, &unicode_status);
|
||||
|
||||
if (unicode_status.status == _CBOR_UNICODE_BADCP) {
|
||||
ctx->syntax_error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char *new_handle = _CBOR_MALLOC(length);
|
||||
|
||||
if (new_handle == NULL) {
|
||||
ctx->creation_failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(new_handle, data, length);
|
||||
cbor_item_t *res = cbor_new_definite_string();
|
||||
cbor_string_set_handle(res, new_handle, length);
|
||||
res->metadata.string_metadata.codepoint_count = codepoint_count;
|
||||
|
||||
/* Careful here: order matters */
|
||||
if (ctx->stack->size > 0 && cbor_isa_string(ctx->stack->top->item)) {
|
||||
if (cbor_string_is_indefinite(ctx->stack->top->item)) {
|
||||
cbor_string_add_chunk(ctx->stack->top->item, cbor_move(res));
|
||||
} else {
|
||||
cbor_decref(&res);
|
||||
ctx->syntax_error = true;
|
||||
}
|
||||
} else {
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_builder_string_start_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_indefinite_string();
|
||||
CHECK_RES;
|
||||
_cbor_stack_push(ctx->stack, res, 0);
|
||||
}
|
||||
|
||||
void cbor_builder_array_start_callback(void *context, size_t size)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_definite_array(size);
|
||||
CHECK_RES;
|
||||
if (size > 0) {
|
||||
_cbor_stack_push(ctx->stack, res, size);
|
||||
} else {
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_builder_indef_array_start_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_indefinite_array();
|
||||
CHECK_RES;
|
||||
_cbor_stack_push(ctx->stack, res, 0);
|
||||
}
|
||||
|
||||
void cbor_builder_indef_map_start_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_indefinite_map();
|
||||
CHECK_RES;
|
||||
_cbor_stack_push(ctx->stack, res, 0);
|
||||
}
|
||||
|
||||
void cbor_builder_map_start_callback(void *context, size_t size)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_definite_map(size);
|
||||
CHECK_RES;
|
||||
if (size > 0) {
|
||||
_cbor_stack_push(ctx->stack, res, size * 2);
|
||||
} else {
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_builder_indef_break_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
if (ctx->stack->size == 0) {
|
||||
// TODO complain
|
||||
} else {
|
||||
cbor_item_t *item = ctx->stack->top->item;
|
||||
_cbor_stack_pop(ctx->stack);
|
||||
_cbor_builder_append(item, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_builder_float2_callback(void *context, float value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_float2();
|
||||
cbor_set_float2(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_float4_callback(void *context, float value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_float4();
|
||||
CHECK_RES;
|
||||
cbor_set_float4(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_float8_callback(void *context, double value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_float8();
|
||||
CHECK_RES;
|
||||
cbor_set_float8(res, value);
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_null_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_null();
|
||||
CHECK_RES;
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_undefined_callback(void *context)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_undef();
|
||||
CHECK_RES;
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_boolean_callback(void *context, bool value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_build_bool(value);
|
||||
CHECK_RES;
|
||||
_cbor_builder_append(res, ctx);
|
||||
}
|
||||
|
||||
void cbor_builder_tag_callback(void *context, uint64_t value)
|
||||
{
|
||||
struct _cbor_decoder_context *ctx = context;
|
||||
cbor_item_t *res = cbor_new_tag(value);
|
||||
CHECK_RES;
|
||||
_cbor_stack_push(ctx->stack, res, 1);
|
||||
}
|
81
lib/libcbor/src/cbor/internal/builder_callbacks.h
Normal file
81
lib/libcbor/src/cbor/internal/builder_callbacks.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_BUILDER_CALLBACKS_H
|
||||
#define LIBCBOR_BUILDER_CALLBACKS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
#include "../callbacks.h"
|
||||
#include "stack.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** High-level decoding context */
|
||||
struct _cbor_decoder_context {
|
||||
/** Callback creating the last item has failed */
|
||||
bool creation_failed;
|
||||
/** Stack expectation mismatch */
|
||||
bool syntax_error;
|
||||
cbor_item_t *root;
|
||||
struct _cbor_stack *stack;
|
||||
};
|
||||
|
||||
void cbor_builder_uint8_callback(void *, uint8_t);
|
||||
|
||||
void cbor_builder_uint16_callback(void *, uint16_t);
|
||||
|
||||
void cbor_builder_uint32_callback(void *, uint32_t);
|
||||
|
||||
void cbor_builder_uint64_callback(void *, uint64_t);
|
||||
|
||||
void cbor_builder_negint8_callback(void *, uint8_t);
|
||||
|
||||
void cbor_builder_negint16_callback(void *, uint16_t);
|
||||
|
||||
void cbor_builder_negint32_callback(void *, uint32_t);
|
||||
|
||||
void cbor_builder_negint64_callback(void *, uint64_t);
|
||||
|
||||
void cbor_builder_string_callback(void *, cbor_data, size_t);
|
||||
|
||||
void cbor_builder_string_start_callback(void *);
|
||||
|
||||
void cbor_builder_byte_string_callback(void *, cbor_data, size_t);
|
||||
|
||||
void cbor_builder_byte_string_start_callback(void *);
|
||||
|
||||
void cbor_builder_array_start_callback(void *, size_t);
|
||||
|
||||
void cbor_builder_indef_array_start_callback(void *);
|
||||
|
||||
void cbor_builder_map_start_callback(void *, size_t);
|
||||
|
||||
void cbor_builder_indef_map_start_callback(void *);
|
||||
|
||||
void cbor_builder_tag_callback(void *, uint64_t);
|
||||
|
||||
void cbor_builder_float2_callback(void *, float);
|
||||
|
||||
void cbor_builder_float4_callback(void *, float);
|
||||
|
||||
void cbor_builder_float8_callback(void *, double);
|
||||
|
||||
void cbor_builder_null_callback(void *);
|
||||
|
||||
void cbor_builder_undefined_callback(void *);
|
||||
|
||||
void cbor_builder_boolean_callback(void *, bool);
|
||||
|
||||
void cbor_builder_indef_break_callback(void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_BUILDER_CALLBACKS_H
|
112
lib/libcbor/src/cbor/internal/encoders.c
Normal file
112
lib/libcbor/src/cbor/internal/encoders.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "encoders.h"
|
||||
|
||||
#if HAVE_ENDIAN_H
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
|
||||
{
|
||||
if (value <= 23) {
|
||||
if (buffer_size >= 1) {
|
||||
buffer[0] = value + offset;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (buffer_size >= 2) {
|
||||
buffer[0] = 0x18 + offset;
|
||||
buffer[1] = value;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
|
||||
{
|
||||
if (buffer_size >= 3) {
|
||||
buffer[0] = 0x19 + offset;
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
*(uint16_t *) &buffer[1] = htobe16(value);
|
||||
#else
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
*(uint16_t *) &buffer[1] = value;
|
||||
#else
|
||||
buffer[1] = value >> 8;
|
||||
buffer[2] = value;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 3;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
|
||||
{
|
||||
if (buffer_size >= 5) {
|
||||
buffer[0] = 0x1A + offset;
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
*(uint32_t *) &buffer[1] = htobe32(value);
|
||||
#else
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
*(uint32_t *) &buffer[1] = value;
|
||||
#else
|
||||
buffer[1] = value >> 24;
|
||||
buffer[2] = value >> 16;
|
||||
buffer[3] = value >> 8;
|
||||
buffer[4] = value;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 5;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
|
||||
{
|
||||
if (buffer_size >= 9) {
|
||||
buffer[0] = 0x1B + offset;
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
*(uint64_t *) &buffer[1] = htobe64(value);
|
||||
#else
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
*(uint64_t *) &buffer[1] = value;
|
||||
#else
|
||||
buffer[1] = value >> 56;
|
||||
buffer[2] = value >> 48;
|
||||
buffer[3] = value >> 40;
|
||||
buffer[4] = value >> 32;
|
||||
buffer[5] = value >> 24;
|
||||
buffer[6] = value >> 16;
|
||||
buffer[7] = value >> 8;
|
||||
buffer[8] = value;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 9;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
|
||||
{
|
||||
if (value <= UINT16_MAX) if (value <= UINT8_MAX)
|
||||
return _cbor_encode_uint8((uint8_t) value, buffer, buffer_size, offset);
|
||||
else
|
||||
return _cbor_encode_uint16((uint16_t) value, buffer, buffer_size, offset);
|
||||
else if (value <= UINT32_MAX)
|
||||
return _cbor_encode_uint32((uint32_t) value, buffer, buffer_size, offset);
|
||||
else
|
||||
return _cbor_encode_uint64((uint64_t) value, buffer, buffer_size, offset);
|
||||
}
|
32
lib/libcbor/src/cbor/internal/encoders.h
Normal file
32
lib/libcbor/src/cbor/internal/encoders.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_ENCODERS_H
|
||||
#define LIBCBOR_ENCODERS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset);
|
||||
|
||||
size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset);
|
||||
|
||||
size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset);
|
||||
|
||||
size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset);
|
||||
|
||||
size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_ENCODERS_H
|
99
lib/libcbor/src/cbor/internal/loaders.c
Normal file
99
lib/libcbor/src/cbor/internal/loaders.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "loaders.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
uint8_t _cbor_load_uint8(cbor_data source)
|
||||
{
|
||||
return (uint8_t) *source;
|
||||
}
|
||||
|
||||
uint16_t _cbor_load_uint16(const unsigned char *source)
|
||||
{
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
return be16toh(*(uint16_t *) source);
|
||||
#else
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
return *(uint16_t *) source;
|
||||
#else
|
||||
return ((uint16_t) *(source + 0) << 8) +
|
||||
(uint8_t) *(source + 1);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t _cbor_load_uint32(const unsigned char *source)
|
||||
{
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
return be32toh(*(uint32_t *) source);
|
||||
#else
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
return *(uint32_t *) source;
|
||||
#else
|
||||
return ((uint32_t) *(source + 0) << 0x18) +
|
||||
((uint32_t) *(source + 1) << 0x10) +
|
||||
((uint16_t) *(source + 2) << 0x08) +
|
||||
(uint8_t) *(source + 3);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t _cbor_load_uint64(const unsigned char *source)
|
||||
{
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
return be64toh(*(uint64_t *) source);
|
||||
#else
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
return *(uint64_t *) source;
|
||||
#else
|
||||
return ((uint64_t) *(source + 0) << 0x38) +
|
||||
((uint64_t) *(source + 1) << 0x30) +
|
||||
((uint64_t) *(source + 2) << 0x28) +
|
||||
((uint64_t) *(source + 3) << 0x20) +
|
||||
((uint32_t) *(source + 4) << 0x18) +
|
||||
((uint32_t) *(source + 5) << 0x10) +
|
||||
((uint16_t) *(source + 6) << 0x08) +
|
||||
(uint8_t) *(source + 7);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* As per http://tools.ietf.org/html/rfc7049#appendix-D */
|
||||
float _cbor_decode_half(unsigned char *halfp)
|
||||
{
|
||||
int half = (halfp[0] << 8) + halfp[1];
|
||||
int exp = (half >> 10) & 0x1f;
|
||||
int mant = half & 0x3ff;
|
||||
double val;
|
||||
if (exp == 0) val = ldexp(mant, -24);
|
||||
else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
|
||||
else val = mant == 0 ? INFINITY : NAN;
|
||||
return (float) (half & 0x8000 ? -val : val);
|
||||
}
|
||||
|
||||
double _cbor_load_half(cbor_data source)
|
||||
{
|
||||
/* Discard const */
|
||||
return _cbor_decode_half((unsigned char *) source);
|
||||
}
|
||||
|
||||
float _cbor_load_float(cbor_data source)
|
||||
{
|
||||
union _cbor_float_helper helper = {.as_uint = _cbor_load_uint32(source)};
|
||||
return helper.as_float;
|
||||
}
|
||||
|
||||
double _cbor_load_double(cbor_data source)
|
||||
{
|
||||
union _cbor_double_helper helper = {.as_uint = _cbor_load_uint64(source)};
|
||||
return helper.as_double;
|
||||
}
|
36
lib/libcbor/src/cbor/internal/loaders.h
Normal file
36
lib/libcbor/src/cbor/internal/loaders.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_LOADERS_H
|
||||
#define LIBCBOR_LOADERS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Read the given uint from the given location, no questions asked */
|
||||
uint8_t _cbor_load_uint8(const unsigned char *source);
|
||||
|
||||
uint16_t _cbor_load_uint16(const unsigned char *source);
|
||||
|
||||
uint32_t _cbor_load_uint32(const unsigned char *source);
|
||||
|
||||
uint64_t _cbor_load_uint64(const unsigned char *source);
|
||||
|
||||
double _cbor_load_half(cbor_data source);
|
||||
|
||||
float _cbor_load_float(cbor_data source);
|
||||
|
||||
double _cbor_load_double(cbor_data source);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_LOADERS_H
|
46
lib/libcbor/src/cbor/internal/memory_utils.c
Normal file
46
lib/libcbor/src/cbor/internal/memory_utils.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "memory_utils.h"
|
||||
#include "cbor/common.h"
|
||||
|
||||
// TODO: Consider builtins (https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html)
|
||||
|
||||
/** Highest on bit position */
|
||||
size_t _cbor_highest_bit(size_t number)
|
||||
{
|
||||
size_t bit = 0;
|
||||
while (number != 0) {
|
||||
bit++;
|
||||
number >>= 1;
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
bool _cbor_safe_to_multiply(size_t a, size_t b)
|
||||
{
|
||||
return _cbor_highest_bit(a) + _cbor_highest_bit(b) <= sizeof(size_t) * 8;
|
||||
}
|
||||
|
||||
void * _cbor_alloc_multiple(size_t item_size, size_t item_count)
|
||||
{
|
||||
if (_cbor_safe_to_multiply(item_size, item_count)) {
|
||||
return _CBOR_MALLOC(item_size * item_count);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void * _cbor_realloc_multiple(void * pointer, size_t item_size, size_t item_count)
|
||||
{
|
||||
if (_cbor_safe_to_multiply(item_size, item_count)) {
|
||||
return _CBOR_REALLOC(pointer, item_size * item_count);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
37
lib/libcbor/src/cbor/internal/memory_utils.h
Normal file
37
lib/libcbor/src/cbor/internal/memory_utils.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_MEMORY_UTILS_H
|
||||
#define LIBCBOR_MEMORY_UTILS_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/** Can a and b be multiplied without overflowing size_t? */
|
||||
bool _cbor_safe_to_multiply(size_t a, size_t b);
|
||||
|
||||
/** Overflow-proof contiguous array allocation
|
||||
*
|
||||
* @param item_size
|
||||
* @param item_count
|
||||
* @return Region of item_size * item_count bytes, or NULL if the total size overflows size_t or the underlying allocator failed
|
||||
*/
|
||||
void * _cbor_alloc_multiple(size_t item_size, size_t item_count);
|
||||
|
||||
|
||||
/** Overflow-proof contiguous array reallocation
|
||||
*
|
||||
* This implements the OpenBSD `reallocarray` functionality.
|
||||
*
|
||||
* @param pointer
|
||||
* @param item_size
|
||||
* @param item_count
|
||||
* @return Realloc'd of item_size * item_count bytes, or NULL if the total size overflows size_t or the underlying allocator failed
|
||||
*/
|
||||
void * _cbor_realloc_multiple(void * pointer, size_t item_size, size_t item_count);
|
||||
|
||||
#endif //LIBCBOR_MEMORY_UTILS_H
|
33
lib/libcbor/src/cbor/internal/stack.c
Normal file
33
lib/libcbor/src/cbor/internal/stack.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "stack.h"
|
||||
|
||||
struct _cbor_stack _cbor_stack_init()
|
||||
{
|
||||
return (struct _cbor_stack) {.top = NULL, .size = 0};
|
||||
}
|
||||
|
||||
void _cbor_stack_pop(struct _cbor_stack *stack)
|
||||
{
|
||||
struct _cbor_stack_record *top = stack->top;
|
||||
stack->top = stack->top->lower;
|
||||
_CBOR_FREE(top);
|
||||
stack->size--;
|
||||
}
|
||||
|
||||
struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *stack, cbor_item_t *item, size_t subitems)
|
||||
{
|
||||
struct _cbor_stack_record *new_top = _CBOR_MALLOC(sizeof(struct _cbor_stack_record));
|
||||
if (new_top == NULL)
|
||||
return NULL;
|
||||
|
||||
*new_top = (struct _cbor_stack_record) {stack->top, item, subitems};
|
||||
stack->top = new_top;
|
||||
stack->size++;
|
||||
return new_top;
|
||||
}
|
40
lib/libcbor/src/cbor/internal/stack.h
Normal file
40
lib/libcbor/src/cbor/internal/stack.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_STACK_H
|
||||
#define LIBCBOR_STACK_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Simple stack record for the parser */
|
||||
struct _cbor_stack_record {
|
||||
struct _cbor_stack_record *lower;
|
||||
cbor_item_t *item;
|
||||
size_t subitems;
|
||||
};
|
||||
|
||||
/** Stack handle - contents and size */
|
||||
struct _cbor_stack {
|
||||
struct _cbor_stack_record *top;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct _cbor_stack _cbor_stack_init();
|
||||
|
||||
void _cbor_stack_pop(struct _cbor_stack *);
|
||||
|
||||
struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *, cbor_item_t *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_STACK_H
|
69
lib/libcbor/src/cbor/internal/unicode.c
Normal file
69
lib/libcbor/src/cbor/internal/unicode.c
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "unicode.h"
|
||||
|
||||
#define UTF8_ACCEPT 0
|
||||
#define UTF8_REJECT 1
|
||||
|
||||
static const uint8_t utf8d[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00..1f */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 20..3f */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40..5f */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60..7f */
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, /* 80..9f */
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* a0..bf */
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* c0..df */
|
||||
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, /* e0..ef */
|
||||
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, /* f0..ff */
|
||||
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, /* s0..s0 */
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, /* s1..s2 */
|
||||
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, /* s3..s4 */
|
||||
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, /* s5..s6 */
|
||||
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* s7..s8 */
|
||||
};
|
||||
|
||||
/* Copyright of this function: (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> */
|
||||
/* See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. */
|
||||
uint32_t _cbor_unicode_decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
|
||||
uint32_t type = utf8d[byte];
|
||||
|
||||
*codep = (*state != UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
*state = utf8d[256 + *state * 16 + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, struct _cbor_unicode_status * status)
|
||||
{
|
||||
*status = (struct _cbor_unicode_status) { .location = 0, .status = _CBOR_UNICODE_OK };
|
||||
uint32_t codepoint, state = UTF8_ACCEPT, res;
|
||||
size_t pos = 0, count = 0;
|
||||
|
||||
for (; pos < source_length; pos++)
|
||||
{
|
||||
res = _cbor_unicode_decode(&state, &codepoint, source[pos]);
|
||||
|
||||
if (res == UTF8_ACCEPT) {
|
||||
count++;
|
||||
} else if (res == UTF8_REJECT) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unfinished multibyte codepoint */
|
||||
if (state != UTF8_ACCEPT)
|
||||
goto error;
|
||||
|
||||
return count;
|
||||
|
||||
error:
|
||||
*status = (struct _cbor_unicode_status) { .location = pos, .status = _CBOR_UNICODE_BADCP };
|
||||
return -1;
|
||||
}
|
34
lib/libcbor/src/cbor/internal/unicode.h
Normal file
34
lib/libcbor/src/cbor/internal/unicode.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_UNICODE_H
|
||||
#define LIBCBOR_UNICODE_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum _cbor_unicode_status_error {
|
||||
_CBOR_UNICODE_OK,
|
||||
_CBOR_UNICODE_BADCP
|
||||
};
|
||||
|
||||
/** Signals unicode validation error and possibly its location */
|
||||
struct _cbor_unicode_status {
|
||||
enum _cbor_unicode_status_error status;
|
||||
size_t location;
|
||||
};
|
||||
|
||||
size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, struct _cbor_unicode_status * status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_UNICODE_H
|
207
lib/libcbor/src/cbor/ints.c
Normal file
207
lib/libcbor/src/cbor/ints.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "ints.h"
|
||||
|
||||
cbor_int_width cbor_int_get_width(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
return item->metadata.int_metadata.width;
|
||||
}
|
||||
|
||||
uint8_t cbor_get_uint8(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_8);
|
||||
return *item->data;
|
||||
}
|
||||
|
||||
uint16_t cbor_get_uint16(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_16);
|
||||
return *(uint16_t *) item->data;
|
||||
}
|
||||
|
||||
uint32_t cbor_get_uint32(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_32);
|
||||
return *(uint32_t *) item->data;
|
||||
}
|
||||
|
||||
uint64_t cbor_get_uint64(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_64);
|
||||
return *(uint64_t *) item->data;
|
||||
}
|
||||
|
||||
uint64_t cbor_get_int(const cbor_item_t * item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
switch(cbor_int_get_width(item)) {
|
||||
case CBOR_INT_8: return cbor_get_uint8(item);
|
||||
case CBOR_INT_16: return cbor_get_uint16(item);
|
||||
case CBOR_INT_32: return cbor_get_uint32(item);
|
||||
case CBOR_INT_64: return cbor_get_uint64(item);
|
||||
}
|
||||
return 0xDEADBEEF; /* Compiler complaints */
|
||||
}
|
||||
|
||||
void cbor_set_uint8(cbor_item_t *item, uint8_t value)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_8);
|
||||
*item->data = value;
|
||||
}
|
||||
|
||||
void cbor_set_uint16(cbor_item_t *item, uint16_t value)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_16);
|
||||
*(uint16_t *) item->data = value;
|
||||
}
|
||||
|
||||
|
||||
void cbor_set_uint32(cbor_item_t *item, uint32_t value)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_32);
|
||||
*(uint32_t *) item->data = value;
|
||||
}
|
||||
|
||||
void cbor_set_uint64(cbor_item_t *item, uint64_t value)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
assert(cbor_int_get_width(item) == CBOR_INT_64);
|
||||
*(uint64_t *) item->data = value;
|
||||
}
|
||||
|
||||
void cbor_mark_uint(cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
item->type = CBOR_TYPE_UINT;
|
||||
}
|
||||
|
||||
void cbor_mark_negint(cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_is_int(item));
|
||||
item->type = CBOR_TYPE_NEGINT;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_int8()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 1);
|
||||
*item = (cbor_item_t) {
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.int_metadata = {.width = CBOR_INT_8}},
|
||||
.type = CBOR_TYPE_UINT
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_int16()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 2);
|
||||
*item = (cbor_item_t) {
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.int_metadata = {.width = CBOR_INT_16}},
|
||||
.type = CBOR_TYPE_UINT
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_int32()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
|
||||
*item = (cbor_item_t) {
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.int_metadata = {.width = CBOR_INT_32}},
|
||||
.type = CBOR_TYPE_UINT
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_int64()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8);
|
||||
*item = (cbor_item_t) {
|
||||
.data = (unsigned char *) item + sizeof(cbor_item_t),
|
||||
.refcount = 1,
|
||||
.metadata = {.int_metadata = {.width = CBOR_INT_64}},
|
||||
.type = CBOR_TYPE_UINT
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_uint8(uint8_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int8();
|
||||
cbor_set_uint8(item, value);
|
||||
cbor_mark_uint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_uint16(uint16_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int16();
|
||||
cbor_set_uint16(item, value);
|
||||
cbor_mark_uint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_uint32(uint32_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int32();
|
||||
cbor_set_uint32(item, value);
|
||||
cbor_mark_uint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_uint64(uint64_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int64();
|
||||
cbor_set_uint64(item, value);
|
||||
cbor_mark_uint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_negint8(uint8_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int8();
|
||||
cbor_set_uint8(item, value);
|
||||
cbor_mark_negint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_negint16(uint16_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int16();
|
||||
cbor_set_uint16(item, value);
|
||||
cbor_mark_negint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_negint32(uint32_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int32();
|
||||
cbor_set_uint32(item, value);
|
||||
cbor_mark_negint(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_negint64(uint64_t value)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_int64();
|
||||
cbor_set_uint64(item, value);
|
||||
cbor_mark_negint(item);
|
||||
return item;
|
||||
}
|
203
lib/libcbor/src/cbor/ints.h
Normal file
203
lib/libcbor/src/cbor/ints.h
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_INTS_H
|
||||
#define LIBCBOR_INTS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Integer (uints and negints) manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Extracts the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer
|
||||
* @return the value
|
||||
*/
|
||||
uint8_t cbor_get_uint8(const cbor_item_t *item);
|
||||
|
||||
/** Extracts the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer
|
||||
* @return the value
|
||||
*/
|
||||
uint16_t cbor_get_uint16(const cbor_item_t *item);
|
||||
|
||||
/** Extracts the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer
|
||||
* @return the value
|
||||
*/
|
||||
uint32_t cbor_get_uint32(const cbor_item_t *item);
|
||||
|
||||
/** Extracts the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer
|
||||
* @return the value
|
||||
*/
|
||||
uint64_t cbor_get_uint64(const cbor_item_t *item);
|
||||
|
||||
/** Extracts the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer
|
||||
* @return the value, extended to `uint64_t`
|
||||
*/
|
||||
uint64_t cbor_get_int(const cbor_item_t *item);
|
||||
|
||||
/** Assigns the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
* @param value the value to assign. For negative integer, the logical value is `-value - 1`
|
||||
*/
|
||||
void cbor_set_uint8(cbor_item_t *item, uint8_t value);
|
||||
|
||||
/** Assigns the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
* @param value the value to assign. For negative integer, the logical value is `-value - 1`
|
||||
*/
|
||||
void cbor_set_uint16(cbor_item_t *item, uint16_t value);
|
||||
|
||||
/** Assigns the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
* @param value the value to assign. For negative integer, the logical value is `-value - 1`
|
||||
*/
|
||||
void cbor_set_uint32(cbor_item_t *item, uint32_t value);
|
||||
|
||||
/** Assigns the integer value
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
* @param value the value to assign. For negative integer, the logical value is `-value - 1`
|
||||
*/
|
||||
void cbor_set_uint64(cbor_item_t *item, uint64_t value);
|
||||
|
||||
/** Queries the integer width
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
* @return the width
|
||||
*/
|
||||
cbor_int_width cbor_int_get_width(const cbor_item_t *item);
|
||||
|
||||
/** Marks the integer item as a positive integer
|
||||
*
|
||||
* The data value is not changed
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
*/
|
||||
void cbor_mark_uint(cbor_item_t *item);
|
||||
|
||||
/** Marks the integer item as a negative integer
|
||||
*
|
||||
* The data value is not changed
|
||||
*
|
||||
* @param item[borrow] positive or negative integer item
|
||||
*/
|
||||
void cbor_mark_negint(cbor_item_t *item);
|
||||
|
||||
/** Allocates new integer with 1B width
|
||||
*
|
||||
* The width cannot be changed once allocated
|
||||
*
|
||||
* @return **new** positive integer. The value is not initialized.
|
||||
*/
|
||||
cbor_item_t *cbor_new_int8();
|
||||
|
||||
/** Allocates new integer with 2B width
|
||||
*
|
||||
* The width cannot be changed once allocated
|
||||
*
|
||||
* @return **new** positive integer. The value is not initialized.
|
||||
*/
|
||||
cbor_item_t *cbor_new_int16();
|
||||
|
||||
/** Allocates new integer with 4B width
|
||||
*
|
||||
* The width cannot be changed once allocated
|
||||
*
|
||||
* @return **new** positive integer. The value is not initialized.
|
||||
*/
|
||||
cbor_item_t *cbor_new_int32();
|
||||
|
||||
/** Allocates new integer with 8B width
|
||||
*
|
||||
* The width cannot be changed once allocated
|
||||
*
|
||||
* @return **new** positive integer. The value is not initialized.
|
||||
*/
|
||||
cbor_item_t *cbor_new_int64();
|
||||
|
||||
/** Constructs a new positive integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** positive integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_uint8(uint8_t value);
|
||||
|
||||
/** Constructs a new positive integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** positive integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_uint16(uint16_t value);
|
||||
|
||||
/** Constructs a new positive integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** positive integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_uint32(uint32_t value);
|
||||
|
||||
/** Constructs a new positive integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** positive integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_uint64(uint64_t value);
|
||||
|
||||
/** Constructs a new negative integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** negative integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_negint8(uint8_t value);
|
||||
|
||||
/** Constructs a new negative integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** negative integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_negint16(uint16_t value);
|
||||
|
||||
/** Constructs a new negative integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** negative integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_negint32(uint32_t value);
|
||||
|
||||
/** Constructs a new negative integer
|
||||
*
|
||||
* @param value the value to use
|
||||
* @return **new** negative integer
|
||||
*/
|
||||
cbor_item_t *cbor_build_negint64(uint64_t value);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_INTS_H
|
141
lib/libcbor/src/cbor/maps.c
Normal file
141
lib/libcbor/src/cbor/maps.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "maps.h"
|
||||
#include "internal/memory_utils.h"
|
||||
|
||||
size_t cbor_map_size(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
return item->metadata.map_metadata.end_ptr;
|
||||
}
|
||||
|
||||
size_t cbor_map_allocated(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
return item->metadata.map_metadata.allocated;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_definite_map(size_t size)
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
if (item == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_MAP,
|
||||
.metadata = {.map_metadata = {
|
||||
.allocated = size,
|
||||
.type = _CBOR_METADATA_DEFINITE,
|
||||
.end_ptr = 0
|
||||
}},
|
||||
.data = _cbor_alloc_multiple(sizeof(struct cbor_pair), size)
|
||||
};
|
||||
if (item->data == NULL) {
|
||||
_CBOR_FREE(item);
|
||||
return NULL;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_indefinite_map()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
if (item == NULL)
|
||||
return NULL;
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_MAP,
|
||||
.metadata = {.map_metadata = {
|
||||
.allocated = 0,
|
||||
.type = _CBOR_METADATA_INDEFINITE,
|
||||
.end_ptr = 0
|
||||
}},
|
||||
.data = NULL
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
struct _cbor_map_metadata *metadata = (struct _cbor_map_metadata *) &item->metadata;
|
||||
if (cbor_map_is_definite(item)) {
|
||||
struct cbor_pair *data = cbor_map_handle(item);
|
||||
if (metadata->end_ptr >= metadata->allocated) {
|
||||
/* Don't realloc definite preallocated map */
|
||||
return false;
|
||||
}
|
||||
|
||||
data[metadata->end_ptr].key = key;
|
||||
data[metadata->end_ptr++].value = NULL;
|
||||
} else {
|
||||
if (metadata->end_ptr >= metadata->allocated) {
|
||||
/* Exponential realloc */
|
||||
// Check for overflows first
|
||||
if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t new_allocation = metadata->allocated == 0 ? 1 : CBOR_BUFFER_GROWTH * metadata->allocated;
|
||||
|
||||
unsigned char * new_data = _cbor_realloc_multiple(item->data, sizeof(struct cbor_pair), new_allocation);
|
||||
|
||||
if (new_data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
item->data = new_data;
|
||||
metadata->allocated = new_allocation;
|
||||
}
|
||||
struct cbor_pair *data = cbor_map_handle(item);
|
||||
data[metadata->end_ptr].key = key;
|
||||
data[metadata->end_ptr++].value = NULL;
|
||||
}
|
||||
cbor_incref(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
cbor_incref(value);
|
||||
cbor_map_handle(item)[
|
||||
/* Move one back since we are assuming _add_key (which increased the ptr)
|
||||
* was the previous operation on this object */
|
||||
item->metadata.map_metadata.end_ptr - 1
|
||||
].value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
if (!_cbor_map_add_key(item, pair.key))
|
||||
return false;
|
||||
return _cbor_map_add_value(item, pair.value);
|
||||
}
|
||||
|
||||
bool cbor_map_is_definite(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
return item->metadata.map_metadata.type == _CBOR_METADATA_DEFINITE;
|
||||
}
|
||||
|
||||
bool cbor_map_is_indefinite(const cbor_item_t *item)
|
||||
{
|
||||
return !cbor_map_is_definite(item);
|
||||
}
|
||||
|
||||
struct cbor_pair *cbor_map_handle(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
return (struct cbor_pair *) item->data;
|
||||
}
|
107
lib/libcbor/src/cbor/maps.h
Normal file
107
lib/libcbor/src/cbor/maps.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_MAPS_H
|
||||
#define LIBCBOR_MAPS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Map manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Get the number of pairs
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @return The number of pairs
|
||||
*/
|
||||
size_t cbor_map_size(const cbor_item_t *item);
|
||||
|
||||
/** Get the size of the allocated storage
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @return Allocated storage size (as the number of #cbor_pair items)
|
||||
*/
|
||||
size_t cbor_map_allocated(const cbor_item_t *item);
|
||||
|
||||
/** Create a new definite map
|
||||
*
|
||||
* @param size The number of slots to preallocate
|
||||
* @return **new** definite map. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_new_definite_map(size_t size);
|
||||
|
||||
/** Create a new indefinite map
|
||||
*
|
||||
* @param size The number of slots to preallocate
|
||||
* @return **new** definite map. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_new_indefinite_map();
|
||||
|
||||
/** Add a pair to the map
|
||||
*
|
||||
* For definite maps, items can only be added to the preallocated space. For indefinite
|
||||
* maps, the storage will be expanded as needed
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @param pair[incref] The key-value pair to add (incref is member-wise)
|
||||
* @return `true` on success, `false` if either reallocation failed or the preallcoated storage is full
|
||||
*/
|
||||
bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair);
|
||||
|
||||
/** Add a key to the map
|
||||
*
|
||||
* Sets the value to `NULL`. Internal API.
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @param key[incref] The key
|
||||
* @return `true` on success, `false` if either reallocation failed or the preallcoated storage is full
|
||||
*/
|
||||
bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key);
|
||||
|
||||
/** Add a value to the map
|
||||
*
|
||||
* Assumes that #_cbor_map_add_key has been called. Internal API.
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @param key[incref] The value
|
||||
* @return `true` on success, `false` if either reallocation failed or the preallcoated storage is full
|
||||
*/
|
||||
bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value);
|
||||
|
||||
/** Is this map definite?
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @return Is this map definite?
|
||||
*/
|
||||
bool cbor_map_is_definite(const cbor_item_t *item);
|
||||
|
||||
/** Is this map indefinite?
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @return Is this map indefinite?
|
||||
*/
|
||||
bool cbor_map_is_indefinite(const cbor_item_t *item);
|
||||
|
||||
/** Get the pairs storage
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @return Array of #cbor_map_size pairs. Manipulation is possible as long as references remain valid.
|
||||
*/
|
||||
struct cbor_pair *cbor_map_handle(const cbor_item_t *item);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_MAPS_H
|
287
lib/libcbor/src/cbor/serialization.c
Normal file
287
lib/libcbor/src/cbor/serialization.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "serialization.h"
|
||||
#include "encoding.h"
|
||||
#include "cbor/arrays.h"
|
||||
#include "cbor/bytestrings.h"
|
||||
#include "cbor/floats_ctrls.h"
|
||||
#include "cbor/ints.h"
|
||||
#include "cbor/maps.h"
|
||||
#include "cbor/strings.h"
|
||||
#include "cbor/tags.h"
|
||||
#include "internal/memory_utils.h"
|
||||
#include <string.h>
|
||||
|
||||
size_t cbor_serialize(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
switch (cbor_typeof(item)) {
|
||||
case CBOR_TYPE_UINT:
|
||||
return cbor_serialize_uint(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_NEGINT:
|
||||
return cbor_serialize_negint(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_BYTESTRING:
|
||||
return cbor_serialize_bytestring(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_STRING:
|
||||
return cbor_serialize_string(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_ARRAY:
|
||||
return cbor_serialize_array(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_MAP:
|
||||
return cbor_serialize_map(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_TAG:
|
||||
return cbor_serialize_tag(item, buffer, buffer_size);
|
||||
case CBOR_TYPE_FLOAT_CTRL:
|
||||
return cbor_serialize_float_ctrl(item, buffer, buffer_size);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
size_t cbor_serialize_uint(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_uint(item));
|
||||
switch (cbor_int_get_width(item)) {
|
||||
case CBOR_INT_8:
|
||||
return cbor_encode_uint8(cbor_get_uint8(item), buffer, buffer_size);
|
||||
case CBOR_INT_16:
|
||||
return cbor_encode_uint16(cbor_get_uint16(item), buffer, buffer_size);
|
||||
case CBOR_INT_32:
|
||||
return cbor_encode_uint32(cbor_get_uint32(item), buffer, buffer_size);
|
||||
case CBOR_INT_64:
|
||||
return cbor_encode_uint64(cbor_get_uint64(item), buffer, buffer_size);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cbor_serialize_negint(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_negint(item));
|
||||
switch (cbor_int_get_width(item)) {
|
||||
case CBOR_INT_8:
|
||||
return cbor_encode_negint8(cbor_get_uint8(item), buffer, buffer_size);
|
||||
case CBOR_INT_16:
|
||||
return cbor_encode_negint16(cbor_get_uint16(item), buffer, buffer_size);
|
||||
case CBOR_INT_32:
|
||||
return cbor_encode_negint32(cbor_get_uint32(item), buffer, buffer_size);
|
||||
case CBOR_INT_64:
|
||||
return cbor_encode_negint64(cbor_get_uint64(item), buffer, buffer_size);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cbor_serialize_bytestring(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_bytestring(item));
|
||||
if (cbor_bytestring_is_definite(item)) {
|
||||
size_t length = cbor_bytestring_length(item);
|
||||
size_t written = cbor_encode_bytestring_start(length, buffer, buffer_size);
|
||||
if (written && (buffer_size - written >= length)) {
|
||||
memcpy(buffer + written, cbor_bytestring_handle(item), length);
|
||||
return written + length;
|
||||
} else
|
||||
return 0;
|
||||
} else {
|
||||
assert(cbor_bytestring_is_indefinite(item));
|
||||
size_t chunk_count = cbor_bytestring_chunk_count(item);
|
||||
size_t written = cbor_encode_indef_bytestring_start(buffer, buffer_size);
|
||||
|
||||
if (written == 0)
|
||||
return 0;
|
||||
|
||||
cbor_item_t **chunks = cbor_bytestring_chunks_handle(item);
|
||||
for (size_t i = 0; i < chunk_count; i++) {
|
||||
size_t chunk_written = cbor_serialize_bytestring(chunks[i], buffer + written, buffer_size - written);
|
||||
if (chunk_written == 0)
|
||||
return 0;
|
||||
else
|
||||
written += chunk_written;
|
||||
}
|
||||
if (cbor_encode_break(buffer + written, buffer_size - written) > 0)
|
||||
return written + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cbor_serialize_string(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
if (cbor_string_is_definite(item)) {
|
||||
size_t length = cbor_string_length(item);
|
||||
size_t written = cbor_encode_string_start(length, buffer, buffer_size);
|
||||
if (written && (buffer_size - written >= length)) {
|
||||
memcpy(buffer + written, cbor_string_handle(item), length);
|
||||
return written + length;
|
||||
} else
|
||||
return 0;
|
||||
} else {
|
||||
assert(cbor_string_is_indefinite(item));
|
||||
size_t chunk_count = cbor_string_chunk_count(item);
|
||||
size_t written = cbor_encode_indef_string_start(buffer, buffer_size);
|
||||
|
||||
if (written == 0)
|
||||
return 0;
|
||||
|
||||
cbor_item_t **chunks = cbor_string_chunks_handle(item);
|
||||
for (size_t i = 0; i < chunk_count; i++) {
|
||||
size_t chunk_written = cbor_serialize_string(chunks[i], buffer + written, buffer_size - written);
|
||||
if (chunk_written == 0)
|
||||
return 0;
|
||||
else
|
||||
written += chunk_written;
|
||||
}
|
||||
if (cbor_encode_break(buffer + written, buffer_size - written) > 0)
|
||||
return written + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cbor_serialize_array(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_array(item));
|
||||
size_t size = cbor_array_size(item),
|
||||
written = 0;
|
||||
cbor_item_t **handle = cbor_array_handle(item);
|
||||
if (cbor_array_is_definite(item)) {
|
||||
written = cbor_encode_array_start(size, buffer, buffer_size);
|
||||
} else {
|
||||
assert(cbor_array_is_indefinite(item));
|
||||
written = cbor_encode_indef_array_start(buffer, buffer_size);
|
||||
}
|
||||
if (written == 0)
|
||||
return 0;
|
||||
|
||||
size_t item_written;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
item_written = cbor_serialize(*(handle++), buffer + written, buffer_size - written);
|
||||
if (item_written == 0)
|
||||
return 0;
|
||||
else
|
||||
written += item_written;
|
||||
}
|
||||
|
||||
if (cbor_array_is_definite(item)) {
|
||||
return written;
|
||||
} else {
|
||||
assert(cbor_array_is_indefinite(item));
|
||||
item_written = cbor_encode_break(buffer + written, buffer_size - written);
|
||||
if (item_written == 0)
|
||||
return 0;
|
||||
else
|
||||
return written + 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cbor_serialize_map(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_map(item));
|
||||
size_t size = cbor_map_size(item),
|
||||
written = 0;
|
||||
struct cbor_pair * handle = cbor_map_handle(item);
|
||||
|
||||
if (cbor_map_is_definite(item)) {
|
||||
written = cbor_encode_map_start(size, buffer, buffer_size);
|
||||
} else {
|
||||
assert(cbor_map_is_indefinite(item));
|
||||
written = cbor_encode_indef_map_start(buffer, buffer_size);
|
||||
}
|
||||
if (written == 0)
|
||||
return 0;
|
||||
|
||||
size_t item_written;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
item_written = cbor_serialize(handle->key, buffer + written, buffer_size - written);
|
||||
if (item_written == 0)
|
||||
return 0;
|
||||
else
|
||||
written += item_written;
|
||||
item_written = cbor_serialize((handle++)->value, buffer + written, buffer_size - written);
|
||||
if (item_written == 0)
|
||||
return 0;
|
||||
else
|
||||
written += item_written;
|
||||
}
|
||||
|
||||
if (cbor_map_is_definite(item)) {
|
||||
return written;
|
||||
} else {
|
||||
assert(cbor_map_is_indefinite(item));
|
||||
item_written = cbor_encode_break(buffer + written, buffer_size - written);
|
||||
if (item_written == 0)
|
||||
return 0;
|
||||
else
|
||||
return written + 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cbor_serialize_tag(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_tag(item));
|
||||
size_t written = cbor_encode_tag(cbor_tag_value(item), buffer, buffer_size);
|
||||
if (written == 0)
|
||||
return 0;
|
||||
|
||||
size_t item_written = cbor_serialize(cbor_tag_item(item), buffer + written, buffer_size - written);
|
||||
if (item_written == 0)
|
||||
return 0;
|
||||
else
|
||||
return written + item_written;
|
||||
}
|
||||
|
||||
size_t cbor_serialize_float_ctrl(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size)
|
||||
{
|
||||
assert(cbor_isa_float_ctrl(item));
|
||||
switch (cbor_float_get_width(item)) {
|
||||
case CBOR_FLOAT_0:
|
||||
/* CTRL - special treatment */
|
||||
return cbor_encode_ctrl(cbor_ctrl_value(item), buffer, buffer_size);
|
||||
case CBOR_FLOAT_16:
|
||||
return cbor_encode_half(cbor_float_get_float2(item), buffer, buffer_size);
|
||||
case CBOR_FLOAT_32:
|
||||
return cbor_encode_single(cbor_float_get_float4(item), buffer, buffer_size);
|
||||
case CBOR_FLOAT_64:
|
||||
return cbor_encode_double(cbor_float_get_float8(item), buffer, buffer_size);
|
||||
}
|
||||
|
||||
/* Should never happen - make the compiler happy */
|
||||
return 0;
|
||||
}
|
123
lib/libcbor/src/cbor/serialization.h
Normal file
123
lib/libcbor/src/cbor/serialization.h
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_SERIALIZATION_H
|
||||
#define LIBCBOR_SERIALIZATION_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* High level encoding
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Serialize the given item
|
||||
*
|
||||
* @param item[borrow] A data item
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize(const cbor_item_t * item, cbor_mutable_data buffer, size_t buffer_size);
|
||||
|
||||
/** Serialize the given item, allocating buffers as needed
|
||||
*
|
||||
* \rst
|
||||
* .. warning:: It is your responsibility to free the buffer using an appropriate ``free`` implementation.
|
||||
* \endrst
|
||||
*
|
||||
* @param item[borrow] A data item
|
||||
* @param buffer[out] Buffer containing the result
|
||||
* @param buffer_size[out] Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure, in which case \p buffer is ``NULL``.
|
||||
*/
|
||||
size_t cbor_serialize_alloc(const cbor_item_t * item, cbor_mutable_data * buffer, size_t * buffer_size);
|
||||
|
||||
/** Serialize an uint
|
||||
*
|
||||
* @param item[borrow] A uint
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_uint(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize a negint
|
||||
*
|
||||
* @param item[borrow] A neging
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_negint(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize a bytestring
|
||||
*
|
||||
* @param item[borrow] A bytestring
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_bytestring(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize a string
|
||||
*
|
||||
* @param item[borrow] A string
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_string(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize an array
|
||||
*
|
||||
* @param item[borrow] An array
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_array(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize a map
|
||||
*
|
||||
* @param item[borrow] A map
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_map(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize a tag
|
||||
*
|
||||
* @param item[borrow] A tag
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_tag(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
/** Serialize a
|
||||
*
|
||||
* @param item[borrow] A float or ctrl
|
||||
* @param buffer Buffer to serialize to
|
||||
* @param buffer_size Size of the \p buffer
|
||||
* @return Length of the result. 0 on failure.
|
||||
*/
|
||||
size_t cbor_serialize_float_ctrl(const cbor_item_t *, cbor_mutable_data, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //LIBCBOR_SERIALIZATION_H
|
684
lib/libcbor/src/cbor/streaming.c
Normal file
684
lib/libcbor/src/cbor/streaming.c
Normal file
@ -0,0 +1,684 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "streaming.h"
|
||||
#include "internal/loaders.h"
|
||||
|
||||
bool static _cbor_claim_bytes(size_t required,
|
||||
size_t provided, struct cbor_decoder_result *result)
|
||||
{
|
||||
if (required > (provided - result->read)) {
|
||||
/* We need to keep all the metadata if parsing is to be resumed */
|
||||
result->read = 0;
|
||||
result->status = CBOR_DECODER_NEDATA;
|
||||
return false;
|
||||
} else {
|
||||
result->read += required;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct cbor_decoder_result cbor_stream_decode(cbor_data source, size_t source_size,
|
||||
const struct cbor_callbacks *callbacks,
|
||||
void *context)
|
||||
{
|
||||
/* If we have no data, we cannot read even the MTB */
|
||||
if (source_size < 1) {
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_EBUFFER};
|
||||
}
|
||||
|
||||
/* If we have a byte, assume it's the MTB */
|
||||
struct cbor_decoder_result result = {1, CBOR_DECODER_FINISHED};
|
||||
|
||||
switch (*source) {
|
||||
case 0x00: /* Fallthrough */
|
||||
case 0x01: /* Fallthrough */
|
||||
case 0x02: /* Fallthrough */
|
||||
case 0x03: /* Fallthrough */
|
||||
case 0x04: /* Fallthrough */
|
||||
case 0x05: /* Fallthrough */
|
||||
case 0x06: /* Fallthrough */
|
||||
case 0x07: /* Fallthrough */
|
||||
case 0x08: /* Fallthrough */
|
||||
case 0x09: /* Fallthrough */
|
||||
case 0x0A: /* Fallthrough */
|
||||
case 0x0B: /* Fallthrough */
|
||||
case 0x0C: /* Fallthrough */
|
||||
case 0x0D: /* Fallthrough */
|
||||
case 0x0E: /* Fallthrough */
|
||||
case 0x0F: /* Fallthrough */
|
||||
case 0x10: /* Fallthrough */
|
||||
case 0x11: /* Fallthrough */
|
||||
case 0x12: /* Fallthrough */
|
||||
case 0x13: /* Fallthrough */
|
||||
case 0x14: /* Fallthrough */
|
||||
case 0x15: /* Fallthrough */
|
||||
case 0x16: /* Fallthrough */
|
||||
case 0x17:
|
||||
/* Embedded one byte unsigned integer */
|
||||
{
|
||||
callbacks->uint8(context, _cbor_load_uint8(source));
|
||||
return result;
|
||||
}
|
||||
case 0x18:
|
||||
/* One byte unsigned integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
callbacks->uint8(context, _cbor_load_uint8(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x19:
|
||||
/* Two bytes unsigned integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
callbacks->uint16(context, _cbor_load_uint16(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x1A:
|
||||
/* Four bytes unsigned integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
callbacks->uint32(context, _cbor_load_uint32(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x1B:
|
||||
/* Eight bytes unsigned integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
callbacks->uint64(context, _cbor_load_uint64(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x1C: /* Fallthrough */
|
||||
case 0x1D: /* Fallthrough */
|
||||
case 0x1E: /* Fallthrough */
|
||||
case 0x1F:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0x20: /* Fallthrough */
|
||||
case 0x21: /* Fallthrough */
|
||||
case 0x22: /* Fallthrough */
|
||||
case 0x23: /* Fallthrough */
|
||||
case 0x24: /* Fallthrough */
|
||||
case 0x25: /* Fallthrough */
|
||||
case 0x26: /* Fallthrough */
|
||||
case 0x27: /* Fallthrough */
|
||||
case 0x28: /* Fallthrough */
|
||||
case 0x29: /* Fallthrough */
|
||||
case 0x2A: /* Fallthrough */
|
||||
case 0x2B: /* Fallthrough */
|
||||
case 0x2C: /* Fallthrough */
|
||||
case 0x2D: /* Fallthrough */
|
||||
case 0x2E: /* Fallthrough */
|
||||
case 0x2F: /* Fallthrough */
|
||||
case 0x30: /* Fallthrough */
|
||||
case 0x31: /* Fallthrough */
|
||||
case 0x32: /* Fallthrough */
|
||||
case 0x33: /* Fallthrough */
|
||||
case 0x34: /* Fallthrough */
|
||||
case 0x35: /* Fallthrough */
|
||||
case 0x36: /* Fallthrough */
|
||||
case 0x37:
|
||||
/* Embedded one byte negative integer */
|
||||
{
|
||||
callbacks->negint8(context, _cbor_load_uint8(source) - 0x20); /* 0x20 offset */
|
||||
return result;
|
||||
}
|
||||
case 0x38:
|
||||
/* One byte negative integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
callbacks->negint8(context, _cbor_load_uint8(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x39:
|
||||
/* Two bytes negative integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
callbacks->negint16(context, _cbor_load_uint16(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x3A:
|
||||
/* Four bytes negative integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
callbacks->negint32(context, _cbor_load_uint32(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x3B:
|
||||
/* Eight bytes negative integer */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
callbacks->negint64(context, _cbor_load_uint64(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x3C: /* Fallthrough */
|
||||
case 0x3D: /* Fallthrough */
|
||||
case 0x3E: /* Fallthrough */
|
||||
case 0x3F:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0x40: /* Fallthrough */
|
||||
case 0x41: /* Fallthrough */
|
||||
case 0x42: /* Fallthrough */
|
||||
case 0x43: /* Fallthrough */
|
||||
case 0x44: /* Fallthrough */
|
||||
case 0x45: /* Fallthrough */
|
||||
case 0x46: /* Fallthrough */
|
||||
case 0x47: /* Fallthrough */
|
||||
case 0x48: /* Fallthrough */
|
||||
case 0x49: /* Fallthrough */
|
||||
case 0x4A: /* Fallthrough */
|
||||
case 0x4B: /* Fallthrough */
|
||||
case 0x4C: /* Fallthrough */
|
||||
case 0x4D: /* Fallthrough */
|
||||
case 0x4E: /* Fallthrough */
|
||||
case 0x4F: /* Fallthrough */
|
||||
case 0x50: /* Fallthrough */
|
||||
case 0x51: /* Fallthrough */
|
||||
case 0x52: /* Fallthrough */
|
||||
case 0x53: /* Fallthrough */
|
||||
case 0x54: /* Fallthrough */
|
||||
case 0x55: /* Fallthrough */
|
||||
case 0x56: /* Fallthrough */
|
||||
case 0x57:
|
||||
/* Embedded length byte string */
|
||||
{
|
||||
size_t length = (size_t) _cbor_load_uint8(source) - 0x40; /* 0x40 offset */
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->byte_string(context, source + 1, length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x58:
|
||||
/* One byte length byte string */
|
||||
// TODO template this?
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint8(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->byte_string(context, source + 1 + 1, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x59:
|
||||
/* Two bytes length byte string */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint16(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->byte_string(context, source + 1 + 2, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x5A:
|
||||
/* Four bytes length byte string */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint32(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->byte_string(context, source + 1 + 4, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x5B:
|
||||
/* Eight bytes length byte string */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint64(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->byte_string(context, source + 1 + 8, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x5C: /* Fallthrough */
|
||||
case 0x5D: /* Fallthrough */
|
||||
case 0x5E:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0x5F:
|
||||
/* Indefinite byte string */
|
||||
{
|
||||
callbacks->byte_string_start(context);
|
||||
return result;
|
||||
}
|
||||
case 0x60: /* Fallthrough */
|
||||
case 0x61: /* Fallthrough */
|
||||
case 0x62: /* Fallthrough */
|
||||
case 0x63: /* Fallthrough */
|
||||
case 0x64: /* Fallthrough */
|
||||
case 0x65: /* Fallthrough */
|
||||
case 0x66: /* Fallthrough */
|
||||
case 0x67: /* Fallthrough */
|
||||
case 0x68: /* Fallthrough */
|
||||
case 0x69: /* Fallthrough */
|
||||
case 0x6A: /* Fallthrough */
|
||||
case 0x6B: /* Fallthrough */
|
||||
case 0x6C: /* Fallthrough */
|
||||
case 0x6D: /* Fallthrough */
|
||||
case 0x6E: /* Fallthrough */
|
||||
case 0x6F: /* Fallthrough */
|
||||
case 0x70: /* Fallthrough */
|
||||
case 0x71: /* Fallthrough */
|
||||
case 0x72: /* Fallthrough */
|
||||
case 0x73: /* Fallthrough */
|
||||
case 0x74: /* Fallthrough */
|
||||
case 0x75: /* Fallthrough */
|
||||
case 0x76: /* Fallthrough */
|
||||
case 0x77:
|
||||
/* Embedded one byte length string */
|
||||
{
|
||||
size_t length = (size_t) _cbor_load_uint8(source) - 0x60; /* 0x60 offset */
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->string(context, source + 1, length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x78:
|
||||
/* One byte length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint8(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->string(context, source + 1 + 1, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x79:
|
||||
/* Two bytes length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint16(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->string(context, source + 1 + 2, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x7A:
|
||||
/* Four bytes length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint32(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->string(context, source + 1 + 4, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x7B:
|
||||
/* Eight bytes length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
size_t length = (size_t) _cbor_load_uint64(source + 1);
|
||||
if (_cbor_claim_bytes(length, source_size, &result)) {
|
||||
callbacks->string(context, source + 1 + 8, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x7C: /* Fallthrough */
|
||||
case 0x7D: /* Fallthrough */
|
||||
case 0x7E:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0x7F:
|
||||
/* Indefinite length string */
|
||||
{
|
||||
callbacks->string_start(context);
|
||||
return result;
|
||||
}
|
||||
case 0x80: /* Fallthrough */
|
||||
case 0x81: /* Fallthrough */
|
||||
case 0x82: /* Fallthrough */
|
||||
case 0x83: /* Fallthrough */
|
||||
case 0x84: /* Fallthrough */
|
||||
case 0x85: /* Fallthrough */
|
||||
case 0x86: /* Fallthrough */
|
||||
case 0x87: /* Fallthrough */
|
||||
case 0x88: /* Fallthrough */
|
||||
case 0x89: /* Fallthrough */
|
||||
case 0x8A: /* Fallthrough */
|
||||
case 0x8B: /* Fallthrough */
|
||||
case 0x8C: /* Fallthrough */
|
||||
case 0x8D: /* Fallthrough */
|
||||
case 0x8E: /* Fallthrough */
|
||||
case 0x8F: /* Fallthrough */
|
||||
case 0x90: /* Fallthrough */
|
||||
case 0x91: /* Fallthrough */
|
||||
case 0x92: /* Fallthrough */
|
||||
case 0x93: /* Fallthrough */
|
||||
case 0x94: /* Fallthrough */
|
||||
case 0x95: /* Fallthrough */
|
||||
case 0x96: /* Fallthrough */
|
||||
case 0x97:
|
||||
/* Embedded one byte length array */
|
||||
{
|
||||
callbacks->array_start(context, (size_t) _cbor_load_uint8(source) - 0x80); /* 0x40 offset */
|
||||
return result;
|
||||
}
|
||||
case 0x98:
|
||||
/* One byte length array */
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
callbacks->array_start(context, (size_t) _cbor_load_uint8(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x99:
|
||||
/* Two bytes length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
callbacks->array_start(context, (size_t) _cbor_load_uint16(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x9A:
|
||||
/* Four bytes length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
callbacks->array_start(context, (size_t) _cbor_load_uint32(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x9B:
|
||||
/* Eight bytes length string */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
callbacks->array_start(context, (size_t) _cbor_load_uint64(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0x9C: /* Fallthrough */
|
||||
case 0x9D: /* Fallthrough */
|
||||
case 0x9E:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0x9F:
|
||||
/* Indefinite length array */
|
||||
{
|
||||
callbacks->indef_array_start(context);
|
||||
return result;
|
||||
}
|
||||
case 0xA0: /* Fallthrough */
|
||||
case 0xA1: /* Fallthrough */
|
||||
case 0xA2: /* Fallthrough */
|
||||
case 0xA3: /* Fallthrough */
|
||||
case 0xA4: /* Fallthrough */
|
||||
case 0xA5: /* Fallthrough */
|
||||
case 0xA6: /* Fallthrough */
|
||||
case 0xA7: /* Fallthrough */
|
||||
case 0xA8: /* Fallthrough */
|
||||
case 0xA9: /* Fallthrough */
|
||||
case 0xAA: /* Fallthrough */
|
||||
case 0xAB: /* Fallthrough */
|
||||
case 0xAC: /* Fallthrough */
|
||||
case 0xAD: /* Fallthrough */
|
||||
case 0xAE: /* Fallthrough */
|
||||
case 0xAF: /* Fallthrough */
|
||||
case 0xB0: /* Fallthrough */
|
||||
case 0xB1: /* Fallthrough */
|
||||
case 0xB2: /* Fallthrough */
|
||||
case 0xB3: /* Fallthrough */
|
||||
case 0xB4: /* Fallthrough */
|
||||
case 0xB5: /* Fallthrough */
|
||||
case 0xB6: /* Fallthrough */
|
||||
case 0xB7:
|
||||
/* Embedded one byte length map */
|
||||
{
|
||||
callbacks->map_start(context, (size_t) _cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */
|
||||
return result;
|
||||
}
|
||||
case 0xB8:
|
||||
/* One byte length map */
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
callbacks->map_start(context, (size_t) _cbor_load_uint8(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xB9:
|
||||
/* Two bytes length map */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
callbacks->map_start(context, (size_t) _cbor_load_uint16(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xBA:
|
||||
/* Four bytes length map */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
callbacks->map_start(context, (size_t) _cbor_load_uint32(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xBB:
|
||||
/* Eight bytes length map */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
callbacks->map_start(context, (size_t) _cbor_load_uint64(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xBC: /* Fallthrough */
|
||||
case 0xBD: /* Fallthrough */
|
||||
case 0xBE:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0xBF:
|
||||
/* Indefinite length map */
|
||||
{
|
||||
callbacks->indef_map_start(context);
|
||||
return result;
|
||||
}
|
||||
case 0xC0:
|
||||
/* Text date/time - RFC 3339 tag, fallthrough */
|
||||
case 0xC1:
|
||||
/* Epoch date tag, fallthrough */
|
||||
case 0xC2:
|
||||
/* Positive bignum tag, fallthrough */
|
||||
case 0xC3:
|
||||
/* Negative bignum tag, fallthrough */
|
||||
case 0xC4:
|
||||
/* Fraction, fallthrough */
|
||||
case 0xC5:
|
||||
/* Big float */
|
||||
{
|
||||
callbacks->tag(context, _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */
|
||||
return result;
|
||||
}
|
||||
case 0xC6: /* Fallthrough */
|
||||
case 0xC7: /* Fallthrough */
|
||||
case 0xC8: /* Fallthrough */
|
||||
case 0xC9: /* Fallthrough */
|
||||
case 0xCA: /* Fallthrough */
|
||||
case 0xCB: /* Fallthrough */
|
||||
case 0xCC: /* Fallthrough */
|
||||
case 0xCD: /* Fallthrough */
|
||||
case 0xCE: /* Fallthrough */
|
||||
case 0xCF: /* Fallthrough */
|
||||
case 0xD0: /* Fallthrough */
|
||||
case 0xD1: /* Fallthrough */
|
||||
case 0xD2: /* Fallthrough */
|
||||
case 0xD3: /* Fallthrough */
|
||||
case 0xD4: /* Unassigned tag value */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0xD5: /* Expected b64url conversion tag - fallthrough */
|
||||
case 0xD6: /* Expected b64 conversion tag - fallthrough */
|
||||
case 0xD7: /* Expected b16 conversion tag */
|
||||
{
|
||||
callbacks->tag(context, _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */
|
||||
return result;
|
||||
}
|
||||
case 0xD8: /* 1B tag */
|
||||
{
|
||||
if (_cbor_claim_bytes(1, source_size, &result)) {
|
||||
callbacks->tag(context, _cbor_load_uint8(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xD9: /* 2B tag */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
callbacks->tag(context, _cbor_load_uint16(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xDA: /* 4B tag */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
callbacks->tag(context, _cbor_load_uint32(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xDB: /* 8B tag */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
callbacks->tag(context, _cbor_load_uint64(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xDC: /* Fallthrough */
|
||||
case 0xDD: /* Fallthrough */
|
||||
case 0xDE: /* Fallthrough */
|
||||
case 0xDF: /* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0xE0: /* Fallthrough */
|
||||
case 0xE1: /* Fallthrough */
|
||||
case 0xE2: /* Fallthrough */
|
||||
case 0xE3: /* Fallthrough */
|
||||
case 0xE4: /* Fallthrough */
|
||||
case 0xE5: /* Fallthrough */
|
||||
case 0xE6: /* Fallthrough */
|
||||
case 0xE7: /* Fallthrough */
|
||||
case 0xE8: /* Fallthrough */
|
||||
case 0xE9: /* Fallthrough */
|
||||
case 0xEA: /* Fallthrough */
|
||||
case 0xEB: /* Fallthrough */
|
||||
case 0xEC: /* Fallthrough */
|
||||
case 0xED: /* Fallthrough */
|
||||
case 0xEE: /* Fallthrough */
|
||||
case 0xEF: /* Fallthrough */
|
||||
case 0xF0: /* Fallthrough */
|
||||
case 0xF1: /* Fallthrough */
|
||||
case 0xF2: /* Fallthrough */
|
||||
case 0xF3: /* Simple value - unassigned */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0xF4:
|
||||
/* False */
|
||||
{
|
||||
callbacks->boolean(context, false);
|
||||
return result;
|
||||
}
|
||||
case 0xF5:
|
||||
/* True */
|
||||
{
|
||||
callbacks->boolean(context, true);
|
||||
return result;
|
||||
}
|
||||
case 0xF6:
|
||||
/* Null */
|
||||
{
|
||||
callbacks->null(context);
|
||||
return result;
|
||||
}
|
||||
case 0xF7:
|
||||
/* Undefined */
|
||||
{
|
||||
callbacks->undefined(context);
|
||||
return result;
|
||||
}
|
||||
case 0xF8:
|
||||
/* 1B simple value, unassigned */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0xF9:
|
||||
/* 2B float */
|
||||
{
|
||||
if (_cbor_claim_bytes(2, source_size, &result)) {
|
||||
callbacks->float2(context, _cbor_load_half(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xFA:
|
||||
/* 4B float */
|
||||
{
|
||||
if (_cbor_claim_bytes(4, source_size, &result)) {
|
||||
callbacks->float4(context, _cbor_load_float(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xFB:
|
||||
/* 8B float */
|
||||
{
|
||||
if (_cbor_claim_bytes(8, source_size, &result)) {
|
||||
callbacks->float8(context, _cbor_load_double(source + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case 0xFC: /* Fallthrough */
|
||||
case 0xFD: /* Fallthrough */
|
||||
case 0xFE:
|
||||
/* Reserved */
|
||||
{
|
||||
return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR};
|
||||
}
|
||||
case 0xFF:
|
||||
/* Break */
|
||||
{
|
||||
callbacks->indef_break(context);
|
||||
return result;
|
||||
}
|
||||
default: /* Never happens - this shuts up the compiler */
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
38
lib/libcbor/src/cbor/streaming.h
Normal file
38
lib/libcbor/src/cbor/streaming.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_STREAMING_H
|
||||
#define LIBCBOR_STREAMING_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
#include "callbacks.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Stateless decoder
|
||||
*
|
||||
* Will try parsing the \p buffer and will invoke the appropriate callback on success.
|
||||
* Decodes one item at a time. No memory allocations occur.
|
||||
*
|
||||
* @param buffer Input buffer
|
||||
* @param buffer_size Length of the buffer
|
||||
* @param callbacks The callback bundle
|
||||
* @param context An arbitrary pointer to allow for maintaining context.
|
||||
*/
|
||||
struct cbor_decoder_result cbor_stream_decode(cbor_data buffer,
|
||||
size_t buffer_size,
|
||||
const struct cbor_callbacks * callbacks,
|
||||
void * context);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_STREAMING_H
|
133
lib/libcbor/src/cbor/strings.c
Normal file
133
lib/libcbor/src/cbor/strings.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "strings.h"
|
||||
#include "internal/memory_utils.h"
|
||||
|
||||
cbor_item_t *cbor_new_definite_string()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_STRING,
|
||||
.metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}}
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_new_indefinite_string()
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_STRING,
|
||||
.metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE, .length = 0}},
|
||||
.data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data))
|
||||
};
|
||||
*((struct cbor_indefinite_string_data *) item->data) = (struct cbor_indefinite_string_data) {
|
||||
.chunk_count = 0,
|
||||
.chunk_capacity = 0,
|
||||
.chunks = NULL,
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_string(const char *val)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_definite_string();
|
||||
size_t len = strlen(val);
|
||||
unsigned char * handle = _CBOR_MALLOC(len);
|
||||
memcpy(handle, val, len);
|
||||
cbor_string_set_handle(item, handle, len);
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_build_stringn(const char *val, size_t length)
|
||||
{
|
||||
cbor_item_t *item = cbor_new_definite_string();
|
||||
unsigned char * handle = _CBOR_MALLOC(length);
|
||||
memcpy(handle, val, length);
|
||||
cbor_string_set_handle(item, handle, length);
|
||||
return item;
|
||||
}
|
||||
|
||||
void cbor_string_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
assert(cbor_string_is_definite(item));
|
||||
item->data = data;
|
||||
item->metadata.string_metadata.length = length;
|
||||
}
|
||||
|
||||
cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
assert(cbor_string_is_indefinite(item));
|
||||
return ((struct cbor_indefinite_string_data *) item->data)->chunks;
|
||||
}
|
||||
|
||||
size_t cbor_string_chunk_count(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
assert(cbor_string_is_indefinite(item));
|
||||
return ((struct cbor_indefinite_string_data *) item->data)->chunk_count;
|
||||
|
||||
}
|
||||
|
||||
bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
assert(cbor_string_is_indefinite(item));
|
||||
struct cbor_indefinite_string_data *data = (struct cbor_indefinite_string_data *) item->data;
|
||||
if (data->chunk_count == data->chunk_capacity) {
|
||||
/* We need more space */
|
||||
if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->chunk_capacity = data->chunk_capacity == 0 ? 1 : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
|
||||
cbor_item_t **new_chunks_data = _cbor_realloc_multiple(data->chunks, sizeof(cbor_item_t *), data->chunk_capacity);
|
||||
|
||||
if (new_chunks_data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->chunks = new_chunks_data;
|
||||
}
|
||||
data->chunks[data->chunk_count++] = cbor_incref(chunk);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t cbor_string_length(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
return item->metadata.string_metadata.length;
|
||||
}
|
||||
|
||||
unsigned char *cbor_string_handle(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
return item->data;
|
||||
}
|
||||
|
||||
size_t cbor_string_codepoint_count(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
return item->metadata.string_metadata.codepoint_count;
|
||||
}
|
||||
|
||||
bool cbor_string_is_definite(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_string(item));
|
||||
return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE;
|
||||
}
|
||||
|
||||
bool cbor_string_is_indefinite(const cbor_item_t *item)
|
||||
{
|
||||
return !cbor_string_is_definite(item);
|
||||
}
|
144
lib/libcbor/src/cbor/strings.h
Normal file
144
lib/libcbor/src/cbor/strings.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_STRINGS_H
|
||||
#define LIBCBOR_STRINGS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* String manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Returns the length of the underlying string
|
||||
*
|
||||
* For definite strings only
|
||||
*
|
||||
* @param item[borrow] a definite string
|
||||
* @return length of the string. Zero if no chunk has been attached yet
|
||||
*/
|
||||
size_t cbor_string_length(const cbor_item_t *item);
|
||||
|
||||
/** The number of codepoints in this string
|
||||
*
|
||||
* Might differ from length if there are multibyte ones
|
||||
*
|
||||
* @param item[borrow] A string
|
||||
* @return The number of codepoints in this string
|
||||
*/
|
||||
size_t cbor_string_codepoint_count(const cbor_item_t *item);
|
||||
|
||||
/** Is the string definite?
|
||||
*
|
||||
* @param item[borrow] a string
|
||||
* @return Is the string definite?
|
||||
*/
|
||||
bool cbor_string_is_definite(const cbor_item_t *item);
|
||||
|
||||
/** Is the string indefinite?
|
||||
*
|
||||
* @param item[borrow] a string
|
||||
* @return Is the string indefinite?
|
||||
*/
|
||||
bool cbor_string_is_indefinite(const cbor_item_t *item);
|
||||
|
||||
/** Get the handle to the underlying string
|
||||
*
|
||||
* Definite items only. Modifying the data is allowed. In that case, the caller takes
|
||||
* responsibility for the effect on items this item might be a part of
|
||||
*
|
||||
* @param item[borrow] A definite string
|
||||
* @return The address of the underlying string. `NULL` if no data have been assigned yet.
|
||||
*/
|
||||
cbor_mutable_data cbor_string_handle(const cbor_item_t *item);
|
||||
|
||||
/** Set the handle to the underlying string
|
||||
*
|
||||
*
|
||||
* \rst
|
||||
* .. warning:: Using a pointer to a stack allocated constant is a common mistake. Lifetime of the string will expire when it goes out of scope and the CBOR item will be left inconsistent.
|
||||
* \endrst
|
||||
*
|
||||
* @param item[borrow] A definite string
|
||||
* @param data The memory block. The caller gives up the ownership of the block. libcbor will deallocate it when appropriate using its free function
|
||||
* @param length Length of the data block
|
||||
*/
|
||||
void cbor_string_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length);
|
||||
|
||||
/** Get the handle to the array of chunks
|
||||
*
|
||||
* Manipulations with the memory block (e.g. sorting it) are allowed, but the validity and the number of chunks must be retained.
|
||||
*
|
||||
* @param item[borrow] A indefinite string
|
||||
* @return array of #cbor_string_chunk_count definite strings
|
||||
*/
|
||||
cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item);
|
||||
|
||||
/** Get the number of chunks this string consist of
|
||||
*
|
||||
* @param item[borrow] A indefinite string
|
||||
* @return The chunk count. 0 for freshly created items.
|
||||
*/
|
||||
size_t cbor_string_chunk_count(const cbor_item_t *item);
|
||||
|
||||
/** Appends a chunk to the string
|
||||
*
|
||||
* Indefinite strings only.
|
||||
*
|
||||
* May realloc the chunk storage.
|
||||
*
|
||||
* @param item[borrow] An indefinite string
|
||||
* @param item[incref] A definite string
|
||||
* @return true on success. false on realloc failure. In that case, the refcount of `chunk` is not increased and the `item` is left intact.
|
||||
*/
|
||||
bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk);
|
||||
|
||||
/** Creates a new definite string
|
||||
*
|
||||
* The handle is initialized to `NULL` and length to 0
|
||||
*
|
||||
* @return **new** definite string. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_new_definite_string();
|
||||
|
||||
/** Creates a new indefinite string
|
||||
*
|
||||
* The chunks array is initialized to `NULL` and chunkcount to 0
|
||||
*
|
||||
* @return **new** indefinite string. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_new_indefinite_string();
|
||||
|
||||
/** Creates a new string and initializes it
|
||||
*
|
||||
* The `val` will be copied to a newly allocated block
|
||||
*
|
||||
* @param val A null-terminated UTF-8 string
|
||||
* @return A **new** string with content `handle`. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_build_string(const char *val);
|
||||
|
||||
/** Creates a new string and initializes it
|
||||
*
|
||||
* The `handle` will be copied to a newly allocated block
|
||||
*
|
||||
* @param val A UTF-8 string, at least \p length long (excluding the null byte)
|
||||
* @return A **new** string with content `handle`. `NULL` on malloc failure.
|
||||
*/
|
||||
cbor_item_t *cbor_build_stringn(const char *val, size_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_STRINGS_H
|
45
lib/libcbor/src/cbor/tags.c
Normal file
45
lib/libcbor/src/cbor/tags.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "tags.h"
|
||||
|
||||
cbor_item_t *cbor_new_tag(uint64_t value)
|
||||
{
|
||||
cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
|
||||
*item = (cbor_item_t) {
|
||||
.refcount = 1,
|
||||
.type = CBOR_TYPE_TAG,
|
||||
.metadata = {.tag_metadata = {.value = value, .tagged_item = NULL}},
|
||||
.data = NULL /* Never used */
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
cbor_item_t *cbor_tag_item(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_tag(item));
|
||||
return item->metadata.tag_metadata.tagged_item;
|
||||
}
|
||||
|
||||
uint64_t cbor_tag_value(const cbor_item_t *item)
|
||||
{
|
||||
assert(cbor_isa_tag(item));
|
||||
return item->metadata.tag_metadata.value;
|
||||
}
|
||||
|
||||
void cbor_tag_set_item(cbor_item_t *item, cbor_item_t *tagged_item)
|
||||
{
|
||||
assert(cbor_isa_tag(item));
|
||||
cbor_incref(tagged_item);
|
||||
item->metadata.tag_metadata.tagged_item = tagged_item;
|
||||
}
|
||||
|
||||
cbor_item_t * cbor_build_tag(uint64_t value, cbor_item_t * item) {
|
||||
cbor_item_t *res = cbor_new_tag(value);
|
||||
cbor_tag_set_item(res, item);
|
||||
return res;
|
||||
}
|
63
lib/libcbor/src/cbor/tags.h
Normal file
63
lib/libcbor/src/cbor/tags.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
|
||||
*
|
||||
* libcbor is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBCBOR_TAGS_H
|
||||
#define LIBCBOR_TAGS_H
|
||||
|
||||
#include "cbor/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Tag manipulation
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/** Create a new tag
|
||||
*
|
||||
* @param value The tag value. Please consult the tag repository
|
||||
* @return **new** tag. Item reference is `NULL`.
|
||||
*/
|
||||
cbor_item_t *cbor_new_tag(uint64_t value);
|
||||
|
||||
/** Get the tagged item
|
||||
*
|
||||
* @param item[borrow] A tag
|
||||
* @return **incref** the tagged item
|
||||
*/
|
||||
cbor_item_t *cbor_tag_item(const cbor_item_t *item);
|
||||
|
||||
/** Get tag value
|
||||
*
|
||||
* @param item[borrow] A tag
|
||||
* @return The tag value. Please consult the tag repository
|
||||
*/
|
||||
uint64_t cbor_tag_value(const cbor_item_t *item);
|
||||
|
||||
/** Set the tagged item
|
||||
*
|
||||
* @param item[borrow] A tag
|
||||
* @param tagged_item[incref] The item to tag
|
||||
*/
|
||||
void cbor_tag_set_item(cbor_item_t *item, cbor_item_t *tagged_item);
|
||||
|
||||
/** Build a new tag
|
||||
*
|
||||
* @param item[incref] The tagee
|
||||
* @param value Tag value
|
||||
* @return **new** tag item
|
||||
*/
|
||||
cbor_item_t * cbor_build_tag(uint64_t value, cbor_item_t * item);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LIBCBOR_TAGS_H
|
Loading…
Reference in New Issue
Block a user