Tests and documentation for CBOR Sequences (#46)

CBOR Sequences, RFC 8742, were always supported. This PR just adds documentation explaining how. It also adds regression tests.
diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index c2dddae..baed191 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -68,6 +68,7 @@
 		E73B575D2161CA7C0080D658 /* half_to_double_from_rfc7049.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = half_to_double_from_rfc7049.c; path = test/half_to_double_from_rfc7049.c; sourceTree = "<group>"; };
 		E73B57632161F8F70080D658 /* run_tests.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = run_tests.c; path = test/run_tests.c; sourceTree = "<group>"; tabWidth = 3; };
 		E73B57642161F8F80080D658 /* run_tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = run_tests.h; path = test/run_tests.h; sourceTree = "<group>"; };
+		E74BF411245D6713002CE8E8 /* UsefulBuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UsefulBuf.h; path = inc/qcbor/UsefulBuf.h; sourceTree = "<group>"; };
 		E772022723B52C02006E966E /* QCBOR_Disable_Exp_Mantissa */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR_Disable_Exp_Mantissa; sourceTree = BUILT_PRODUCTS_DIR; };
 		E776E07C214ADF7F00E67947 /* QCBOR */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR; sourceTree = BUILT_PRODUCTS_DIR; };
 		E776E08C214AE07400E67947 /* qcbor_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = qcbor_encode.c; path = src/qcbor_encode.c; sourceTree = "<group>"; tabWidth = 3; };
@@ -137,6 +138,7 @@
 		E776E092214AE07C00E67947 /* inc */ = {
 			isa = PBXGroup;
 			children = (
+				E74BF411245D6713002CE8E8 /* UsefulBuf.h */,
 				E78C91DF240C90C100F4CECE /* qcbor_common.h */,
 				E78C91DE240C90C100F4CECE /* qcbor_decode.h */,
 				E78C91E1240C90C100F4CECE /* qcbor_encode.h */,
@@ -210,7 +212,7 @@
 		E776E074214ADF7F00E67947 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0940;
+				LastUpgradeCheck = 1140;
 				ORGANIZATIONNAME = "Laurence Lundblade";
 				TargetAttributes = {
 					E776E07B214ADF7F00E67947 = {
@@ -361,6 +363,7 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
+				"HEADER_SEARCH_PATHS[arch=*]" = inc;
 				MACOSX_DEPLOYMENT_TARGET = 10.13;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				ONLY_ACTIVE_ARCH = YES;
@@ -420,6 +423,7 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
+				"HEADER_SEARCH_PATHS[arch=*]" = inc;
 				MACOSX_DEPLOYMENT_TARGET = 10.13;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = macosx;
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 9499e7f..f799517 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -49,6 +49,12 @@
 
 
 /**
+ @file qcbor_decode.h
+
+ This describes CBOR decoding.
+*/
+
+/**
  The decode mode options.
  */
 typedef enum {
@@ -812,12 +818,35 @@
 
  @param[in]  pCtx  The context to check.
 
- @return An error or @ref QCBOR_SUCCESS.
-
- This tells you if all the bytes given to QCBORDecode_Init() have been
- consumed and whether all maps and arrays were closed.  The decode is
- considered to be incorrect or incomplete if not and an error will be
- returned.
+ @retval  QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN   The CBOR is not well-formed
+ as some map or array was not closed off. This should always be treated as an
+ unrecoverable error.
+ 
+ @retval QCBOR_ERR_EXTRA_BYTES The CBOR was decoded correctly and
+ all maps and arrays are closed, but some of the bytes in the input were not consumed.
+ This may or may not be considered an error.
+ 
+ @retval QCBOR_SUCCES There were no errors and all bytes were
+ consumed.
+ 
+ This should always be called to determine if all maps and arrays
+ where correctly closed and that the CBOR was well-formed.
+ 
+ This calls the destructor for the string allocator, if one is in use.
+ 
+ Some CBOR protocols use a CBOR sequence [RFC 8742]
+ (https://tools.ietf.org/html/rfc8742) .  A CBOR sequence typically
+ doesn't start out with a map or an array. The end of the CBOR is
+ determined in some other way, perhaps by external framing, or by the
+ occurrence of some particular CBOR data item or such. The buffer given
+ to decode must start out with valid CBOR, but it can have extra bytes
+ at the end that are not CBOR or CBOR that is to be ignored.
+ 
+ QCBORDecode_Finish() should still be called when decoding CBOR
+ Sequences to check that the input decoded was well-formed. If the
+ input was well-formed and there are extra bytes at the end @ref
+ QCBOR_ERR_EXTRA_BYTES will be returned.  This can be considered a
+ successful decode.
  */
 QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
 
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 31fda52..46fa578 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -210,6 +210,13 @@
 
  Note that when you nest arrays or maps in a map, the nested array or
  map has a label.
+ 
+ Many CBOR-based protocols start with an array or map. This makes them
+ self-delimiting. No external length or end marker is needed to know
+ the end. It is also possible not start this way, in which case this
+ it is usually called a CBOR sequence which is described in [RFC 8742] (https://tools.ietf.org/html/rfc8742 ).
+ This encoder supports either just by whether the first item added is an
+ array, map or other.
 
  @anchor Tags-Overview
  Any CBOR data item can be tagged to add semantics, define a new data
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index be8586b..2be56d7 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -3787,3 +3787,134 @@
 }
 
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
+
+
+int32_t CBORSequenceDecodeTests(void)
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   QCBORError uCBORError;
+
+   // --- Test a sequence with extra bytes ---
+   
+   // The input for the date test happens to be a sequence so it
+   // is reused. It is a sequence because it doesn't start as
+   // an array or map.
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput),
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   // Get the first item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 1;
+   }
+   if(Item.uDataType != QCBOR_TYPE_DATE_STRING) {
+      return 2;
+   }
+   
+   // Get a second item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 2;
+   }
+   if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH) {
+      return 3;
+   }
+   
+   // A sequence can have stuff at the end that may
+   // or may not be valid CBOR. The protocol decoder knows
+   // when to stop by definition of the protocol, not
+   // when the top-level map or array is ended.
+   // Finish still has to be called to know that
+   // maps and arrays (if there were any) were closed
+   // off correctly. When called like this it
+   // must return the error QCBOR_ERR_EXTRA_BYTES.
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_ERR_EXTRA_BYTES) {
+      return 4;
+   }
+   
+   
+   // --- Test an empty input ----
+   uint8_t empty[1];
+   UsefulBufC Empty = {empty, 0};
+   QCBORDecode_Init(&DCtx,
+                    Empty,
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 5;
+   }
+   
+   
+   // --- Sequence with unclosed indefinite length array ---
+   static const uint8_t xx[] = {0x01, 0x9f, 0x02};
+   
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(xx),
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   // Get the first item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 7;
+   }
+   if(Item.uDataType != QCBOR_TYPE_INT64) {
+      return 8;
+   }
+   
+   // Get a second item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 9;
+   }
+   if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+      return 10;
+   }
+
+   // Try to finish before consuming all bytes to confirm
+   // that the still-open error is returned.
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
+      return 11;
+   }
+
+   
+   // --- Sequence with a closed indefinite length array ---
+   static const uint8_t yy[] = {0x01, 0x9f, 0xff};
+   
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(yy),
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   // Get the first item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 12;
+   }
+   if(Item.uDataType != QCBOR_TYPE_INT64) {
+      return 13;
+   }
+   
+   // Get a second item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 14;
+   }
+   if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+      return 15;
+   }
+
+   // Try to finish before consuming all bytes to confirm
+   // that the still-open error is returned.
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 16;
+   }
+
+   
+   return 0;
+}
+
diff --git a/test/qcbor_decode_tests.h b/test/qcbor_decode_tests.h
index 7c8c185..92e217c 100644
--- a/test/qcbor_decode_tests.h
+++ b/test/qcbor_decode_tests.h
@@ -252,4 +252,10 @@
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
 
+/*
+ Tests decoding of CBOR Sequences defined in RFC 8742
+ */
+int32_t CBORSequenceDecodeTests(void);
+
+
 #endif /* defined(__QCBOR__qcbort_decode_tests__) */
diff --git a/test/run_tests.c b/test/run_tests.c
index 5c0abe3..ac2ab78 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -104,6 +104,7 @@
     TEST_ENTRY(SetUpAllocatorTest),
     TEST_ENTRY(SimpleValuesIndefiniteLengthTest1),
     TEST_ENTRY(EncodeLengthThirtyoneTest),
+    TEST_ENTRY(CBORSequenceDecodeTests),
 #ifndef     QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
     TEST_ENTRY(EncodeLengthThirtyoneTest),
     TEST_ENTRY(ExponentAndMantissaDecodeTests),