Mercurial > libjeffpc
changeset 721:60e8e945b4a3
cbor: add cbor_peek_break helper
This function makes it slightly easier to check that the next data item is a
break. It deserves its own function otherwise each caller would have to
map cbor_peek_type's 0 return to an errno.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 19 Mar 2019 15:54:17 -0400 |
parents | 9c00aef1efc4 |
children | 69021db0eee3 |
files | include/jeffpc/cbor.h tests/test_cbor_peek.c |
diffstat | 2 files changed, 73 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/include/jeffpc/cbor.h Tue Mar 19 16:09:14 2019 -0400 +++ b/include/jeffpc/cbor.h Tue Mar 19 15:54:17 2019 -0400 @@ -71,6 +71,34 @@ extern int cbor_peek_type(struct buffer *buffer, enum val_type *type); /* + * Peek at whether or not the next data item is a CBOR "break". Returns: + * + * 0: + * if next value is a CBOR "break" + * -EILSEQ: + * if next value can be represented by a VT_* + * -ENOTSUP: + * if next value cannot be represented by a VT_* + * -EFAULT: + * if the buffer is not large enough to contain another value + */ +static inline int cbor_peek_break(struct buffer *buffer) +{ + enum val_type type; + int ret; + + ret = cbor_peek_type(buffer, &type); + switch (ret) { + case 0: + return -EILSEQ; + case -EINTR: + return 0; + default: + return ret; + } +} + +/* * On failure, the buffer state is unchanged. On success, the buffer is * updated to point to the first byte of the next data item. */
--- a/tests/test_cbor_peek.c Tue Mar 19 16:09:14 2019 -0400 +++ b/tests/test_cbor_peek.c Tue Mar 19 15:54:17 2019 -0400 @@ -25,39 +25,40 @@ #include "test.c" static const struct test { - int ret; + int ret_type; + int ret_break; 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)) +#define V1(idx, tret, bret, type) [idx] = { (tret), (bret), (type) } +#define V2(idx, tret, bret, type) V1((idx), (tret), (bret), (type)), \ + V1((idx) + 1, (tret), (bret), (type)) +#define V4(idx, tret, bret, type) V2((idx), (tret), (bret), (type)), \ + V2((idx) + 2, (tret), (bret), (type)) +#define V8(idx, tret, bret, type) V4((idx), (tret), (bret), (type)), \ + V4((idx) + 4, (tret), (bret), (type)) +#define V16(idx, tret, bret, type) V8((idx), (tret), (bret), (type)), \ + V8((idx) + 8, (tret), (bret), (type)) +#define V32(idx, tret, bret, type) V16((idx), (tret), (bret), (type)), \ + V16((idx) + 16, (tret), (bret), (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 */ + V32(0x00, 0, -EILSEQ, VT_INT), /* CMT_UINT */ + V32(0x20, -ENOTSUP, -ENOTSUP, 0), /* CMT_NINT */ + V32(0x40, 0, -EILSEQ, VT_BLOB), /* CMT_BYTE */ + V32(0x60, 0, -EILSEQ, VT_STR), /* CMT_TEXT */ + V32(0x80, 0, -EILSEQ, VT_ARRAY),/* CMT_ARRAY */ + V32(0xa0, 0, -EILSEQ, VT_NVL), /* CMT_MAP */ + V32(0xc0, -ENOTSUP, -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, -EINTR, 0), /* CMT_FLOAT => break */ + V16(0xe0, -ENOTSUP, -ENOTSUP, 0), /* CMT_FLOAT */ + V4 (0xf0, -ENOTSUP, -ENOTSUP, 0), /* CMT_FLOAT */ + V2 (0xf4, 0, -EILSEQ, VT_BOOL), /* CMT_FLOAT => bool */ + V1 (0xf6, 0, -EILSEQ, VT_NULL), /* CMT_FLOAT => null */ + V1 (0xf7, -ENOTSUP, -ENOTSUP, 0), /* CMT_FLOAT */ + V4 (0xf8, -ENOTSUP, -ENOTSUP, 0), /* CMT_FLOAT */ + V2 (0xfc, -ENOTSUP, -ENOTSUP, 0), /* CMT_FLOAT */ + V1 (0xfe, -ENOTSUP, -ENOTSUP, 0), /* CMT_FLOAT */ + V1 (0xff, -EINTR, 0, 0), /* CMT_FLOAT => break */ }; static void test_zero(void) @@ -88,21 +89,33 @@ uint8_t in; int ret; - fprintf(stderr, "%3zu: %02zx expecting ret=%d (%s) type=%s...", - i, i, run->ret, xstrerror(run->ret), - val_typename(run->type)); + fprintf(stderr, "%3zu: %02zx expecting " + "type ret=%d (%s) type=%s & break ret=%d (%s)...", + i, i, run->ret_type, xstrerror(run->ret_type), + val_typename(run->type), + run->ret_break, xstrerror(run->ret_break)); in = i; buffer_init_static(&buf, &in, sizeof(in), false); + /* + * type + */ ret = cbor_peek_type(&buf, &type); - check_rets(run->ret, ret, "cbor_peek_type()"); + check_rets(run->ret_type, ret, "cbor_peek_type()"); if (!ret && (type != run->type)) fail("got %s", val_typename(type)); + /* + * break + */ + ret = cbor_peek_break(&buf); + + check_rets(run->ret_break, ret, "cbor_peek_break()"); + fprintf(stderr, "ok.\n"); } }