sync up with master
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index f2e1592..1efebcf 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -63,15 +63,28 @@
*
* When QCBORDecode_EnterMap() is called, pre-order traversal
* continues to work. There is a cursor that is run over the tree with
- * calls to QCBORDecode_GetNext(). This can be intermixed with calls
- * TODO: this is not quite true
- * to QCBORDecode_GetXxxxInMapX(). The pre-order traversal is limited
- * just to the map entered. Attempts to QCBORDecode_GetNext() beyond
- * the end of the map will give the @ref QCBOR_ERR_NO_MORE_ITEMS
+ * calls to QCBORDecode_GetNext(). Attempts to QCBORDecode_GetNext() beyond the end
+ * of the map will give the @ref QCBOR_ERR_NO_MORE_ITEMS
* error.
*
- * There is also QCBORDecode_EnterArray() to decode arrays. It will
- * narrow the traversal to the extent of the array entered.
+ * Use of the travsal cursor can be mixed with the fetching of items
+ * by label with some caveats. When a non-aggregate item like an
+ * integer or string is fetched by label, the traversal cursor is
+ * unaffected so the mixing can be done freely. When an aggregate
+ * item is entered by label, the traversal cursor is set to the item
+ * after the aggregate item when it is exited. The traversal cursor
+ * can always be set to the start of the current entered map with
+ * QCBORDecode_Rewind(). (This behavior was incorrectly documented in
+ * previous versions of QCBOR. This behavior may not be ideal for some
+ * uses and may be considered inconsistent between aggregate and
+ * non-aggregate, but it can be relied on or can be worked around by
+ * ordering item fetching and/or use of QCBORDecode_Rewind(). This may
+ * be improved in a future version of QCBOR.)
+ * QCBORDecode_EnterArray() can be used to narrow the traversal to the
+ * extent of the array.
+ *
+ * QCBORDecode_EnterArray() can be used to narrow the traversal to the
+ * extent of the array.
*
* All the QCBORDecode_GetXxxxInMapX() methods support duplicate label
* detection and will result in an error if the map has duplicate
@@ -718,12 +731,17 @@
* fully exited.
*
* While in bounded mode, QCBORDecode_GetNext() works as usual on the
- * map and the in-order traversal cursor is maintained. It starts out
+ * map and the pre-order traversal cursor is maintained. It starts out
* at the first item in the map just entered. Attempts to get items
* off the end of the map will give error @ref QCBOR_ERR_NO_MORE_ITEMS
* rather going to the next item after the map as it would when not in
* bounded mode.
*
+ * It is possible to mix use of the traversal cursor with the fetching
+ * of items in a map by label with the caveat that fetching
+ * non-aggregate items behaves differently from entering subordinate
+ * aggregate items. See dicussion in @ref SpiffyDecode.
+ *
* Exiting leaves the pre-order cursor at the data item following the
* last entry in the map or at the end of the input CBOR if there
* nothing after the map.
@@ -894,6 +912,7 @@
* implementation can track.
*
* See also QCBORDecode_GetItemInMapN().
+>>>>>>> master
*/
void
QCBORDecode_GetItemsInMap(QCBORDecodeContext *pCtx, QCBORItem *pItemList);
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index b3bf91d..05d2466 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -5727,6 +5727,109 @@
0xa1, 0x80, 0x00
};
+/*
+ Lots of nesting for various nesting tests.
+ { 1:1,
+ 2:{
+ 21:21,
+ 22:{
+ 221:[2111, 2112, 2113],
+ 222:222,
+ 223: {}
+ },
+ 23: 23
+ },
+ 3:3,
+ 4: [ {} ]
+ }
+ */
+static const uint8_t spNested[] = {
+0xA4, /* Map of 4 */
+ 0x01, 0x01, /* Map entry 1 : 1 */
+ 0x02, 0xA3, /* Map entry 2 : {, an array of 3 */
+ 0x15, 0x15, /* Map entry 21 : 21 */
+ 0x16, 0xA3, /* Map entry 22 : {, a map of 3 */
+ 0x18, 0xDD, 0x83, /* Map entry 221 : [ an array of 3 */
+ 0x19, 0x08, 0x3F, /* Array item 2111 */
+ 0x19, 0x08, 0x40, /* Array item 2112 */
+ 0x19, 0x08, 0x41, /* Array item 2113 */
+ 0x18, 0xDE, 0x18, 0xDE, /* Map entry 222 : 222 */
+ 0x18, 0xDF, 0xA0, /* Map entry 223 : {} */
+ 0x17, 0x17, /* Map entry 23 : 23 */
+ 0x03, 0x03, /* Map entry 3 : 3 */
+ 0x04, 0x81, /* Map entry 4: [, an array of 1 */
+ 0xA0 /* Array entry {}, an empty map */
+};
+
+
+static int32_t EnterMapCursorTest(void)
+{
+ QCBORDecodeContext DCtx;
+ QCBORItem Item1;
+
+ int i;
+ for(i = 0; i < 13; i++) {
+ QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spNested), 0);
+ QCBORDecode_EnterMap(&DCtx, NULL);
+ int j;
+ /* Move travesal cursor */
+ for(j = 0; j < i; j++) {
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ }
+ QCBORDecode_EnterMapFromMapN(&DCtx, 2);
+ QCBORDecode_ExitMap(&DCtx);
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ if(Item1.label.int64 != 3) {
+ return 8000;
+ }
+ }
+
+ for(i = 0; i < 13; i++) {
+ QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spNested), 0);
+ QCBORDecode_EnterMap(&DCtx, NULL);
+ int j;
+ /* Move travesal cursor */
+ for(j = 0; j < i; j++) {
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ }
+ QCBORDecode_EnterMapFromMapN(&DCtx, 2);
+ QCBORDecode_EnterMapFromMapN(&DCtx, 22);
+ QCBORDecode_ExitMap(&DCtx);
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ if(Item1.label.int64 != 23) {
+ return 8000;
+ }
+ }
+
+ for(i = 0; i < 13; i++) {
+ QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spNested), 0);
+ QCBORDecode_EnterMap(&DCtx, NULL);
+ int j;
+ /* Move travesal cursor */
+ for(j = 0; j < i; j++) {
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ }
+ QCBORDecode_EnterMapFromMapN(&DCtx, 2);
+ QCBORDecode_EnterMapFromMapN(&DCtx, 22);
+ for(j = 0; j < i; j++) {
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ }
+ QCBORDecode_EnterArrayFromMapN(&DCtx, 221);
+ QCBORDecode_ExitArray(&DCtx);
+ QCBORDecode_ExitMap(&DCtx);
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ if(Item1.label.int64 != 23) {
+ return 8000;
+ }
+ QCBORDecode_ExitMap(&DCtx);
+ QCBORDecode_GetNext(&DCtx, &Item1);
+ if(Item1.label.int64 != 3) {
+ return 8000;
+ }
+ }
+
+ return 0;
+}
int32_t EnterMapTest(void)
@@ -6107,6 +6210,8 @@
return 3000;
}
+ nReturn = EnterMapCursorTest();
+
return nReturn;
}