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");
 	}
 }