first version of peek next
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 1033871..81636f0 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -866,6 +866,28 @@
/**
+ @brief Get the next data item without consuming it.
+
+ @param[in] pCtx The decoder context.
+ @param[out] pDecodedItem Holds the CBOR item just decoded.
+
+ This is the same as QCBORDecode_GetNext() but does not consume
+ the data item. This only looks ahead one item. Calling it
+ repeatedly will just return the same item over and over.
+
+ This uses a lot of stack, far more than anything else
+ here in qcbor_decode.h because it saves a copy of most of
+ the decode context temporarily.
+
+ This is useful for looking ahead to determine the type
+ of a data item to know which type-specific spiffy decode
+ function to call.
+ */
+QCBORError
+QCBORDecode_PeekNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
+
+
+/**
@brief Gets the next item including full list of tags for item.
@param[in] pCtx The decoder context.
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 001a778..afc3651 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2030,6 +2030,9 @@
}
+/*
+ Public function, see header qcbor/qcbor_decode.h file
+ */
QCBORError
QCBORDecode_GetNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
{
@@ -2046,6 +2049,24 @@
/*
Public function, see header qcbor/qcbor_decode.h file
*/
+QCBORError
+QCBORDecode_PeekNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
+{
+ const QCBORDecodeNesting SaveNesting = pMe->nesting;
+ const UsefulInputBuf Save = pMe->InBuf;
+
+ QCBORError uErr = QCBORDecode_GetNext(pMe, pDecodedItem);
+
+ pMe->nesting = SaveNesting;
+ pMe->InBuf = Save;
+
+ return uErr;
+}
+
+
+/*
+ Public function, see header qcbor/qcbor_decode.h file
+ */
void QCBORDecode_VGetNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
{
if(pMe->uLastError != QCBOR_SUCCESS) {
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index edcaad7..70fd3b1 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -6586,3 +6586,206 @@
return 0;
}
+
+
+
+
+int32_t PeekTest()
+{
+ QCBORItem Item;
+ QCBORError nCBORError;
+ QCBORDecodeContext DCtx;
+
+ QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), 0);
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return 100+(int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 3) {
+ return 200;
+ }
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 3) {
+ return 300;
+ }
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return 400 + (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 3) {
+ return 500;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 3) {
+ return 600;
+ }
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return 900 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataType != QCBOR_TYPE_INT64 ||
+ Item.val.int64 != 42 ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.label.string, "first integer")) {
+ return 1000;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 1100 + (int32_t)nCBORError;
+ }
+
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataType != QCBOR_TYPE_INT64 ||
+ Item.val.int64 != 42 ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.label.string, "first integer")) {
+ return 1200;
+ }
+
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 1300 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.label.string, "an array of two strings") ||
+ Item.uDataType != QCBOR_TYPE_ARRAY ||
+ Item.val.uCount != 2)
+ return 1400;
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 1500 + (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "string1")) {
+ return 1600;
+ }
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return 1700 + (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "string2")) {
+ return 1800;
+ }
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "string2")) {
+ return 1900;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return (int32_t)nCBORError;
+ }
+ if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "string2")) {
+ return 2000;
+ }
+
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 2100 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.label.string, "map in a map") ||
+ Item.uDataType != QCBOR_TYPE_MAP ||
+ Item.val.uCount != 4) {
+ return 2100;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 2200 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("bytes 1"))||
+ Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "xxxx")) {
+ return 2300;
+ }
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return 2400 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ UsefulBufCompareToSZ(Item.label.string, "bytes 2") ||
+ Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "yyyy")) {
+ return 2500;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 2600 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ UsefulBufCompareToSZ(Item.label.string, "bytes 2") ||
+ Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "yyyy")) {
+ return 2700;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 2800 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.label.string, "another int") ||
+ Item.uDataType != QCBOR_TYPE_INT64 ||
+ Item.val.int64 != 98)
+ return 2900;
+
+ if((nCBORError = QCBORDecode_PeekNext(&DCtx, &Item))) {
+ return 3000 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("text 2"))||
+ Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "lies, damn lies and statistics")) {
+ return 3100;
+ }
+
+ if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+ return 3200 + (int32_t)nCBORError;
+ }
+ if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+ UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("text 2"))||
+ Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+ Item.uDataAlloc ||
+ Item.uLabelAlloc ||
+ UsefulBufCompareToSZ(Item.val.string, "lies, damn lies and statistics")) {
+ return 3300;
+ }
+
+ return 0;
+}
diff --git a/test/qcbor_decode_tests.h b/test/qcbor_decode_tests.h
index 3cbb82d..7e11e35 100644
--- a/test/qcbor_decode_tests.h
+++ b/test/qcbor_decode_tests.h
@@ -298,4 +298,11 @@
int32_t SpiffyIndefiniteLengthStringsTests(void);
+/*
+ Test PeekNext().
+ */
+int32_t PeekTest(void);
+
+
+
#endif /* defined(__QCBOR__qcbort_decode_tests__) */
diff --git a/test/run_tests.c b/test/run_tests.c
index 0383b21..aa42013 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -118,6 +118,7 @@
TEST_ENTRY(CBORSequenceDecodeTests),
TEST_ENTRY(IntToTests),
TEST_ENTRY(DecodeTaggedTypeTests),
+ TEST_ENTRY(PeekTest),
#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
TEST_ENTRY(EncodeLengthThirtyoneTest),
TEST_ENTRY(ExponentAndMantissaDecodeTests),