Mercurial > libjeffpc
changeset 683:b3a4ac14a22d
cbor: add a function to peek at current data item
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Thu, 11 Oct 2018 14:20:08 -0400 |
parents | 117603444601 |
children | 41a3427cde1d |
files | fmt_cbor.c include/jeffpc/cbor.h mapfile-vers tests/.hgignore tests/CMakeLists.txt tests/test_cbor_peek_type.c |
diffstat | 6 files changed, 181 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/fmt_cbor.c Tue Apr 17 20:17:14 2018 -0400 +++ b/fmt_cbor.c Thu Oct 11 14:20:08 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright (c) 2017-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -59,6 +59,10 @@ (type << 5) | additional; \ }) +/* + * pack + */ + static int pack_cbor_type_byte(struct buffer *buffer, enum major_type type, uint8_t additional) { @@ -299,3 +303,59 @@ return -ENOTSUP; } + +/* + * peek + */ + +int cbor_peek_type(struct buffer *buffer, enum val_type *type) +{ + const uint8_t *ptr; + enum major_type major_type; + uint8_t extra; + + if (buffer_remain(buffer) < 1) + return -EFAULT; + + ptr = buffer_data_current(buffer); + + major_type = *ptr >> 5; + extra = *ptr & 0x1f; + + switch (major_type) { + case CMT_UINT: + *type = VT_INT; + break; + case CMT_BYTE: + *type = VT_BLOB; + break; + case CMT_TEXT: + *type = VT_STR; + break; + case CMT_FLOAT: + switch (extra) { + case ADDL_FLOAT_FALSE: + case ADDL_FLOAT_TRUE: + *type = VT_BOOL; + break; + case ADDL_FLOAT_NULL: + *type = VT_NULL; + break; + case ADDL_FLOAT_BREAK: + default: + return -ENOTSUP; + } + break; + case CMT_ARRAY: + *type = VT_ARRAY; + break; + case CMT_MAP: + *type = VT_NVL; + break; + case CMT_NINT: + case CMT_TAG: + return -ENOTSUP; + } + + return 0; +}
--- a/include/jeffpc/cbor.h Tue Apr 17 20:17:14 2018 -0400 +++ b/include/jeffpc/cbor.h Thu Oct 11 14:20:08 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright (c) 2017-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -56,4 +56,6 @@ return cbor_pack_cstr_len(buffer, str, strlen(str)); } +extern int cbor_peek_type(struct buffer *buffer, enum val_type *type); + #endif
--- a/mapfile-vers Tue Apr 17 20:17:14 2018 -0400 +++ b/mapfile-vers Thu Oct 11 14:20:08 2018 -0400 @@ -64,6 +64,7 @@ cbor_pack_str; cbor_pack_uint; cbor_pack_val; + cbor_peek_type; # cstr strcpy_safe;
--- a/tests/.hgignore Tue Apr 17 20:17:14 2018 -0400 +++ b/tests/.hgignore Thu Oct 11 14:20:08 2018 -0400 @@ -6,6 +6,7 @@ test_bswap test_buffer test_cbor_pack +test_cbor_peek_type test_container_of test_endian test_errno
--- a/tests/CMakeLists.txt Tue Apr 17 20:17:14 2018 -0400 +++ b/tests/CMakeLists.txt Thu Oct 11 14:20:08 2018 -0400 @@ -31,6 +31,7 @@ build_test_bin_and_run(atomic-single-thread) build_test_bin_and_run(bswap) build_test_bin_and_run(buffer) +build_test_bin_and_run(cbor_peek_type) build_test_bin_and_run(container_of) build_test_bin_and_run(endian) build_test_bin_and_run(errno)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_cbor_peek_type.c Thu Oct 11 14:20:08 2018 -0400 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * 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. + */ + +#include <jeffpc/cbor.h> + +#include "test.c" + +static const struct test { + int ret; + enum val_type type; +} tests[256] = { +#define V1(idx, ret, type) [idx] = { (ret), (type) } +#define V2(idx, ret, type) V1((idx), (ret), (type)), \ + V1((idx) + 1, (ret), (type)) +#define V4(idx, ret, type) V2((idx), (ret), (type)), \ + V2((idx) + 2, (ret), (type)) +#define V8(idx, ret, type) V4((idx), (ret), (type)), \ + V4((idx) + 4, (ret), (type)) +#define V16(idx, ret, type) V8((idx), (ret), (type)), \ + V8((idx) + 8, (ret), (type)) +#define V32(idx, ret, type) V16((idx), (ret), (type)), \ + V16((idx) + 16, (ret), (type)) + + V32(0x00, 0, VT_INT), /* CMT_UINT */ + V32(0x20, -ENOTSUP, 0), /* CMT_NINT */ + V32(0x40, 0, VT_BLOB), /* CMT_BYTE */ + V32(0x60, 0, VT_STR), /* CMT_TEXT */ + V32(0x80, 0, VT_ARRAY), /* CMT_ARRAY */ + V32(0xa0, 0, VT_NVL), /* CMT_MAP */ + V32(0xc0, -ENOTSUP, 0), /* CMT_TAG */ + + /* CMT_FLOAT is more complicated */ + V16(0xe0, -ENOTSUP, 0), /* CMT_FLOAT */ + V4 (0xf0, -ENOTSUP, 0), /* CMT_FLOAT */ + V2 (0xf4, 0, VT_BOOL), /* CMT_FLOAT => bool */ + V1 (0xf6, 0, VT_NULL), /* CMT_FLOAT => null */ + V1 (0xf7, -ENOTSUP, 0), /* CMT_FLOAT */ + V4 (0xf8, -ENOTSUP, 0), /* CMT_FLOAT */ + V2 (0xfc, -ENOTSUP, 0), /* CMT_FLOAT */ + V1 (0xfe, -ENOTSUP, 0), /* CMT_FLOAT */ + V1 (0xff, -ENOTSUP, 0), /* CMT_FLOAT => break */ +}; + +static void test_zero(void) +{ + enum val_type type; + struct buffer buf; + int ret; + + fprintf(stderr, "empty input: expecting -EFAULT..."); + + buffer_init_static(&buf, NULL, 0, false); + + ret = cbor_peek_type(&buf, &type); + + check_rets(-EFAULT, ret, "cbor_peek_type()"); + + fprintf(stderr, "ok.\n"); +} + +static void test_one(void) +{ + size_t i; + + for (i = 0; i < ARRAY_LEN(tests); i++) { + const struct test *run = &tests[i]; + struct buffer buf; + enum val_type type; + uint8_t in; + int ret; + + fprintf(stderr, "%3zu: %02x expecting ret=%d (%s) type=%s...", + i, i, run->ret, xstrerror(run->ret), + val_typename(run->type)); + + in = i; + + buffer_init_static(&buf, &in, sizeof(in), false); + + ret = cbor_peek_type(&buf, &type); + + check_rets(run->ret, ret, "cbor_peek_type()"); + + if (!ret && (type != run->type)) + fail("got %s", val_typename(type)); + + fprintf(stderr, "ok.\n"); + } +} + +void test(void) +{ + test_zero(); + test_one(); +}