QCBOR: Quiet static analyzers; add bigfloat support; documentation improvements

Refined use of types, particular integer types and their signedness so there
are fewer warnings from static analyzers. Added casts to make implicit
type conversions explicit and more clear for code reader. No actual bugs
or vulnerabilities where found by the static analyzer but a lot of lines
were changed.

Cleaner handling of too-long bstr and tstr error condition when decoding.

Add support for bigfloats and decimal fractions -- all of RFC 7049 is now
supported except duplicate detection when decoding maps and some of
strict mode. Dead-stripping and/or linking through a .a file will
automatically leave out the added code on the encoder side.
bytes or so of code on the decode side

Documentation corrections and improved code formatting, fewer
long lines, spelling... A lot of lines where change for this.

Repair a few tests that weren't testing what they were supposed
to be testing.

Change-Id: I4c9c56c1ee16812eac7a5c2f2ba0d896f3f1b5ae
Signed-off-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/lib/ext/qcbor/test/UsefulBuf_Tests.c b/lib/ext/qcbor/test/UsefulBuf_Tests.c
index f53693a..1c2634e 100644
--- a/lib/ext/qcbor/test/UsefulBuf_Tests.c
+++ b/lib/ext/qcbor/test/UsefulBuf_Tests.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2019, Laurence Lundblade.
+ Copyright (c) 2018-2020, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ==============================================================================*/
+ =============================================================================*/
 
 #include "UsefulBuf.h"
 
@@ -79,22 +79,17 @@
    UsefulBufC UBC2 = {"unbounce ", 9};
    UsefulOutBuf_InsertUsefulBuf(&UOB, UBC2, 10);
 
-   // Make it a null terminated string (because all the appends and inserts above not strcpy !)
-   UsefulOutBuf_AppendByte(&UOB, '\0');
 
+   const UsefulBufC Expected = UsefulBuf_FROM_SZ_LITERAL("heffalump unbounce bluster hunny");
 
    UsefulBufC U = UsefulOutBuf_OutUBuf(&UOB);
-
-   const char *expected = "heffalump unbounce bluster hunny";
-
-   if(UsefulBuf_IsNULLC(U) || U.len-1 != strlen(expected) || strcmp(expected, U.ptr) || UsefulOutBuf_GetError(&UOB)) {
+   if(UsefulBuf_IsNULLC(U) || UsefulBuf_Compare(Expected, U) || UsefulOutBuf_GetError(&UOB)) {
       szReturn = "OutUBuf";
    }
 
    UsefulBuf_MAKE_STACK_UB(buf, 50);
    UsefulBufC Out =  UsefulOutBuf_CopyOut(&UOB, buf);
-
-   if(UsefulBuf_IsNULLC(Out) || Out.len-1 != strlen(expected) || strcmp(expected, Out.ptr)) {
+   if(UsefulBuf_IsNULLC(Out) || UsefulBuf_Compare(Expected, Out)) {
       szReturn = "CopyOut";
    }
 
@@ -160,7 +155,8 @@
    - around MAX size_t
 
 
- Test these for the buffer size and the cursor, the insert amount, the append amount and the insert position
+ Test these for the buffer size and the cursor, the insert amount, the
+ append amount and the insert position
 
  */
 
@@ -314,10 +310,9 @@
    if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
      return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
 
-   char *sz = "not const"; // some data for the test
-   UsefulBuf B = (UsefulBuf){sz, sizeof(sz)};
+   UsefulBuf B = (UsefulBuf){(void *)Too.ptr, Too.len};
    UsefulBufC BC = UsefulBuf_Const(B);
-   if(BC.len != sizeof(sz) || BC.ptr != sz)
+   if(BC.len != Too.len || BC.ptr != Too.ptr)
       return "UsefulBufConst failed";
 
    return NULL;
diff --git a/lib/ext/qcbor/test/float_tests.c b/lib/ext/qcbor/test/float_tests.c
index eaf75aa..20057c3 100644
--- a/lib/ext/qcbor/test/float_tests.c
+++ b/lib/ext/qcbor/test/float_tests.c
@@ -1,14 +1,14 @@
 /*==============================================================================
  float_tests.c -- tests for float and conversion to/from half-precision
 
- Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
 
  SPDX-License-Identifier: BSD-3-Clause
 
  See BSD-3-Clause license in README.md
 
  Created on 9/19/18
- ==============================================================================*/
+ =============================================================================*/
 
 #include "float_tests.h"
 #include "qcbor.h"
@@ -26,7 +26,8 @@
             0x69, 0x6E, 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
         0xF9, 0x7C, 0x00,   // Infinity
         0x73,
-            0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x69, 0x6E, 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
+            0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x69, 0x6E,
+            0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
         0xF9, 0xFC, 0x00,   // -Inifinity
         0x63,
             0x4E, 0x61, 0x4E,
@@ -38,21 +39,29 @@
             0x6F, 0x6E, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64,
         0xF9, 0x35, 0x55,   // 0.333251953125
         0x76,
-            0x6C, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68, 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
+            0x6C, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68, 0x61, 0x6C,
+            0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
         0xF9, 0x7B, 0xFF,   // 65504.0
-        0x78, 0x18, 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x20, 0x68, 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
+        0x78, 0x18,
+            0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x20, 0x68,
+            0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69,
+            0x6F, 0x6E,
         0xF9, 0x7C, 0x00,   // Infinity
         0x72,
-            0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
+            0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75,
+            0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
         0xF9, 0x00, 0x01,   // 0.000000059604
         0x6F,
-            0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
+            0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x6E, 0x6F,
+            0x72, 0x6D, 0x61, 0x6C,
         0xF9, 0x03, 0xFF,   // 0.0000609755516
         0x71,
-            0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
+            0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75, 0x62,
+            0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
         0xF9, 0x04, 0x00,   // 0.000061988
         0x70,
-            0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65,
+            0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x73,
+            0x69, 0x6E, 0x67, 0x6C, 0x65,
         0xF9, 0x00, 0x00,
         0x03,
         0xF9, 0xC0, 0x00,    // -2
@@ -68,7 +77,7 @@
 };
 
 
-int HalfPrecisionDecodeBasicTests()
+int32_t HalfPrecisionDecodeBasicTests()
 {
     UsefulBufC HalfPrecision = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedHalf);
 
@@ -97,7 +106,9 @@
         return -4;
     }
 
-    QCBORDecode_GetNext(&DC, &Item); // TODO, is this really converting right? It is carrying payload, but this confuses things.
+    // TODO, is this really converting right? It is carrying payload, but
+    // this confuses things.
+    QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || !isnan(Item.val.dfnum)) {
         return -5;
     }
@@ -149,19 +160,23 @@
 
     // TODO: double check these four tests
     QCBORDecode_GetNext(&DC, &Item); // qNaN
-    if(Item.uDataType != QCBOR_TYPE_DOUBLE || UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff8000000000000ULL) {
+    if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
+       UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff8000000000000ULL) {
         return -15;
     }
     QCBORDecode_GetNext(&DC, &Item); // sNaN
-    if(Item.uDataType != QCBOR_TYPE_DOUBLE || UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff0000000000001ULL) {
+    if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
+       UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff0000000000001ULL) {
         return -16;
     }
     QCBORDecode_GetNext(&DC, &Item); // qNaN with payload 0x0f
-    if(Item.uDataType != QCBOR_TYPE_DOUBLE || UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff800000000000fULL) {
+    if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
+       UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff800000000000fULL) {
         return -17;
     }
     QCBORDecode_GetNext(&DC, &Item); // sNaN with payload 0x0f
-    if(Item.uDataType != QCBOR_TYPE_DOUBLE || UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff000000000000fULL) {
+    if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
+       UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff000000000000fULL) {
         return -18;
     }
 
@@ -175,12 +190,12 @@
 
 
 
-int HalfPrecisionAgainstRFCCodeTest()
+int32_t HalfPrecisionAgainstRFCCodeTest()
 {
     for(uint32_t uHalfP = 0; uHalfP < 0xffff; uHalfP += 60) {
         unsigned char x[2];
-        x[1] = uHalfP & 0xff;
-        x[0] = uHalfP >> 8;
+        x[1] = (uint8_t)(uHalfP & 0xff);
+        x[0] = (uint8_t)(uHalfP >> 8); // uHalfP is always less than 0xffff
         double d = decode_half(x);
 
         // Contruct the CBOR for the half-precision float by hand
@@ -188,11 +203,12 @@
         UsefulOutBuf UOB;
         UsefulOutBuf_Init(&UOB, __xx);
 
-        const uint8_t uHalfPrecInitialByte = HALF_PREC_FLOAT + (CBOR_MAJOR_TYPE_SIMPLE << 5); // 0xf9
+        const uint8_t uHalfPrecInitialByte = (uint8_t)(HALF_PREC_FLOAT + (CBOR_MAJOR_TYPE_SIMPLE << 5)); // 0xf9
         UsefulOutBuf_AppendByte(&UOB, uHalfPrecInitialByte); // The initial byte for a half-precision float
         UsefulOutBuf_AppendUint16(&UOB, (uint16_t)uHalfP);
 
-        // Now parse the hand-constructed CBOR. This will invoke the conversion to a float
+        // Now parse the hand-constructed CBOR. This will invoke the
+        // conversion to a float
         QCBORDecodeContext DC;
         QCBORDecode_Init(&DC, UsefulOutBuf_OutUBuf(&UOB), 0);
 
@@ -203,7 +219,8 @@
             return -1;
         }
 
-        //printf("%04x  QCBOR:%15.15f  RFC: %15.15f (%8x)\n", uHalfP,Item.val.fnum, d , UsefulBufUtil_CopyFloatToUint32(d));
+        //printf("%04x  QCBOR:%15.15f  RFC: %15.15f (%8x)\n",
+        //       uHalfP, Item.val.fnum, d , UsefulBufUtil_CopyFloatToUint32(d));
 
         if(isnan(d)) {
             // The RFC code uses the native instructions which may or may not
@@ -290,7 +307,7 @@
 };
 
 
-int DoubleAsSmallestTest()
+int32_t DoubleAsSmallestTest()
 {
     UsefulBuf_MAKE_STACK_UB(EncodedHalfsMem, 420);
 
@@ -340,16 +357,17 @@
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one third", 0.333251953125);
 
     // 76                                   # text(22)
-    //    6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
+    //   6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
     // F9 7BFF                              # primitive(31743)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision",65504.0);
 
     // 76                                   # text(22)
-    //    6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
+    //   6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
     // F9 7BFF                              # primitive(31743)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision point one",65504.1);
 
-    // Float 65536.0F is 0x47800000 in hex. It has an exponent of 16, which is larger than 15, the largest half-precision exponent
+    // Float 65536.0F is 0x47800000 in hex. It has an exponent of 16, which
+    // is larger than 15, the largest half-precision exponent
     // 78 18                                # text(24)
     //    746F6F2D6C617267652068616C662D707265636973696F6E # "too-large half-precision"
     // FA 47800000                          # primitive(31743)
@@ -395,17 +413,20 @@
     //    746F6F2D6C617267652073696E676C6520657870 # "too-large single exp"
     // FB 47F8000000000000                  # primitive(5185894970917126144)
     // (0x01LL << (DOUBLE_NUM_SIGNIFICAND_BITS-1)) | ((128LL + DOUBLE_EXPONENT_BIAS) << DOUBLE_EXPONENT_SHIFT);
-    QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large single exp", 5.104235503814077E+38); // Exponent too large for single
+    // Exponent too large for single
+    QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large single exp", 5.104235503814077E+38);
 
     // 66                                   # text(6)
     //    646664666465                      # "dfdfde"
     // FA 4B800000                          # primitive(1266679808)
-    QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest single with prec",16777216); // Single with no precision loss
+    // Single with no precision loss
+    QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest single with prec", 16777216);
 
     // 78 18                                # text(24)
     //    626967676573742073696E676C6520776974682070726563 # "biggest single with prec"
     // FA 4B800000                          # primitive(1266679808)
-    QCBOREncode_AddDoubleAsSmallestToMap(&EC, "first single with prec loss",16777217); // Double becuase of precision loss
+    // Double becuase of precision loss
+    QCBOREncode_AddDoubleAsSmallestToMap(&EC, "first single with prec loss", 16777217);
 
     // Just a convenient marker when cutting and pasting encoded CBOR
     QCBOREncode_AddSZStringToMapN(&EC, 1, "fin");
diff --git a/lib/ext/qcbor/test/float_tests.h b/lib/ext/qcbor/test/float_tests.h
index b7174c8..f777156 100644
--- a/lib/ext/qcbor/test/float_tests.h
+++ b/lib/ext/qcbor/test/float_tests.h
@@ -1,23 +1,25 @@
 /*==============================================================================
  float_tests.h -- tests for float and conversion to/from half-precision
 
- Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
 
  SPDX-License-Identifier: BSD-3-Clause
 
  See BSD-3-Clause license in README.md
 
  Created on 9/19/18
- ==============================================================================*/
+ =============================================================================*/
 
 #ifndef float_tests_h
 #define float_tests_h
 
-int HalfPrecisionDecodeBasicTests(void);
+#include <stdint.h>
 
-int DoubleAsSmallestTest(void);
+int32_t HalfPrecisionDecodeBasicTests(void);
 
-int HalfPrecisionAgainstRFCCodeTest(void);
+int32_t DoubleAsSmallestTest(void);
+
+int32_t HalfPrecisionAgainstRFCCodeTest(void);
 
 
 #endif /* float_tests_h */
diff --git a/lib/ext/qcbor/test/half_to_double_from_rfc7049.c b/lib/ext/qcbor/test/half_to_double_from_rfc7049.c
index 6380e51..d1e2f39 100644
--- a/lib/ext/qcbor/test/half_to_double_from_rfc7049.c
+++ b/lib/ext/qcbor/test/half_to_double_from_rfc7049.c
@@ -22,7 +22,7 @@
    b) the license may be an issue
 
  QCBOR does support half-precision, but rather than using
- floating point math like this, it does it with bit shifting
+ floating-point math like this, it does it with bit shifting
  and masking.
 
  This code is here to test that code.
diff --git a/lib/ext/qcbor/test/half_to_double_from_rfc7049.h b/lib/ext/qcbor/test/half_to_double_from_rfc7049.h
index 9f69e35..4642f04 100644
--- a/lib/ext/qcbor/test/half_to_double_from_rfc7049.h
+++ b/lib/ext/qcbor/test/half_to_double_from_rfc7049.h
@@ -1,14 +1,14 @@
 /*==============================================================================
  half_to_double_from_rfc7049.h -- interface to IETF float conversion code.
 
- Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
 
  SPDX-License-Identifier: BSD-3-Clause
 
  See BSD-3-Clause license in README.md
 
  Created on 9/23/18
-  ==============================================================================*/
+  ============================================================================*/
 
 #ifndef half_to_double_from_rfc7049_h
 #define half_to_double_from_rfc7049_h
diff --git a/lib/ext/qcbor/test/not_well_formed_cbor.h b/lib/ext/qcbor/test/not_well_formed_cbor.h
index d5bd233..e905cd1 100644
--- a/lib/ext/qcbor/test/not_well_formed_cbor.h
+++ b/lib/ext/qcbor/test/not_well_formed_cbor.h
@@ -58,22 +58,22 @@
     // indefinite length text string with indefinite string inside
     {(uint8_t[]){0x7f, 0x7f, 0x61, 0x00, 0xff, 0xff}, 6},
 
-    // Definite length maps and arrays must be closed by having the
+    // Definte length maps and arrays must be closed by having the
     // right number of items
 
-    // A definite length array that is supposed to have 1 item, but has none
+    // A definte length array that is supposed to have 1 item, but has none
     {(uint8_t[]){0x81}, 1},
-    // A definite length array that is supposed to have 2 items, but has only 1
+    // A definte length array that is supposed to have 2 items, but has only 1
     {(uint8_t[]){0x82, 0x00}, 2},
-    // A definite length array that is supposed to have 511 items, but has only 1
+    // A definte length array that is supposed to have 511 items, but has only 1
     {(uint8_t[]){0x9a, 0x01, 0xff, 0x00}, 4},
-    // A definite length map that is supposed to have 1 item, but has none
+    // A definte length map that is supposed to have 1 item, but has none
     {(uint8_t[]){0xa1}, 1},
-    // A definite length map that is supposed to have s item, but has only 1
+    // A definte length map that is supposed to have s item, but has only 1
     {(uint8_t[]){0xa2, 0x01, 0x02}, 3},
 
 
-    // Indefinite length maps and arrays must be ended by a break
+    // Indefinte length maps and arrays must be ended by a break
 
     // Indefinite length array with zero items and no break
     {(uint8_t[]){0x9f}, 1},
@@ -251,10 +251,10 @@
     {(uint8_t[]){0x41}, 1},
     // A text string is of length 1 without the 1 byte
     {(uint8_t[]){0x61}, 1},
-    // Byte string should have 2^32-1 bytes, but has one
-    {(uint8_t[]){0x5a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6},
-    // Byte string should have 2^32-1 bytes, but has one
-    {(uint8_t[]){0x7a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6},
+    // Byte string should have 2^32-15 bytes, but has one
+    {(uint8_t[]){0x5a, 0xff, 0xff, 0xff, 0xf0, 0x00}, 6},
+    // Byte string should have 2^32-15 bytes, but has one
+    {(uint8_t[]){0x7a, 0xff, 0xff, 0xff, 0xf0, 0x00}, 6},
 
 
     // Use of unassigned additional information values
diff --git a/lib/ext/qcbor/test/qcbor_decode_tests.c b/lib/ext/qcbor/test/qcbor_decode_tests.c
index 7de8c6c..a9e1fb2 100644
--- a/lib/ext/qcbor/test/qcbor_decode_tests.c
+++ b/lib/ext/qcbor/test/qcbor_decode_tests.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2019, Laurence Lundblade.
+ Copyright (c) 2018-2020, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ==============================================================================*/
+ =============================================================================*/
 
 #include "qcbor_decode_tests.h"
 #include "qcbor.h"
@@ -55,11 +55,6 @@
 
    fflush(stdout);
 }
-
-/*static void printencoded(const char *szLabel, const uint8_t *pEncoded, size_t nLen)
-{
-   PrintUsefulBufC(szLabel, (UsefulBufC){pEncoded, nLen});
-}*/
 #endif
 
 
@@ -92,7 +87,7 @@
 
 // return CBOR error or -1 if type of value doesn't match
 
-static int IntegerValuesParseTestInternal(QCBORDecodeContext *pDCtx)
+static int32_t IntegerValuesParseTestInternal(QCBORDecodeContext *pDCtx)
 {
    QCBORItem          Item;
    int nCBORError;
@@ -104,7 +99,7 @@
 
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
-   if(Item.uDataType != QCBOR_TYPE_INT64 || // Todo; fix this for 32-bit machines
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -9223372036854775807LL - 1)
       return -1;
 
@@ -419,10 +414,10 @@
 }
 
 
-// The largest negative int possible in CBOR.
-// Not possible in C.
-static const uint8_t spTooBigNegative[] = {
-   0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+// One less than the smallest negative integer allowed in C. Decoding
+// this should fail.
+static const uint8_t spTooSmallNegative[] = {
+   0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
 
@@ -430,7 +425,7 @@
    Tests the decoding of lots of different integers sizes
    and values.
  */
-int IntegerValuesParseTest()
+int32_t IntegerValuesParseTest()
 {
    int nReturn;
    QCBORDecodeContext DCtx;
@@ -447,7 +442,7 @@
 
    // The one large negative integer that can be parsed
    QCBORDecode_Init(&DCtx,
-                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooBigNegative),
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooSmallNegative),
                     QCBOR_DECODE_MODE_NORMAL);
 
    QCBORItem item;
@@ -460,8 +455,8 @@
 
 
 /*
-   Creates a simple CBOR array and returns it in *pEncoded. The array is malloced
-   and needs to be freed. This is used by several tests.
+   Creates a simple CBOR array and returns it in *pEncoded. The array is
+   malloced and needs to be freed. This is used by several tests.
 
    Two of the inputs can be set. Two other items in the array are fixed.
 
@@ -469,7 +464,7 @@
 
 static uint8_t spSimpleArrayBuffer[50];
 
-static int CreateSimpleArray(int nInt1, int nInt2, uint8_t **pEncoded, size_t *pEncodedLen)
+static int32_t CreateSimpleArray(int nInt1, int nInt2, uint8_t **pEncoded, size_t *pEncodedLen)
 {
    QCBOREncodeContext ECtx;
    int nReturn = -1;
@@ -511,6 +506,9 @@
 
 
 /*
+ Some basic CBOR with map and array used in a lot of tests.
+ The map labels are all strings
+
  {"first integer": 42,
   "an array of two strings": [
       "string1", "string2"
@@ -523,8 +521,7 @@
    }
   }
  */
-
-static uint8_t pValidMapEncoded[] = {
+static const uint8_t pValidMapEncoded[] = {
    0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e,
    0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a, 0x77, 0x61, 0x6e,
    0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20,
@@ -542,13 +539,22 @@
    0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
    0x73 } ;
 
-static int ParseOrderedArray(const uint8_t *pEncoded, size_t nLen, int64_t *pInt1, int64_t *pInt2,  const uint8_t **pBuf3, size_t *pBuf3Len,  const uint8_t **pBuf4, size_t *pBuf4Len)
+static int32_t ParseOrderedArray(const uint8_t *pEncoded,
+                             size_t nLen,
+                             int64_t *pInt1,
+                             int64_t *pInt2,
+                             const uint8_t **pBuf3,
+                             size_t *pBuf3Len,
+                             const uint8_t **pBuf4,
+                             size_t *pBuf4Len)
 {
    QCBORDecodeContext DCtx;
    QCBORItem          Item;
    int                nReturn = -1; // assume error until success
 
-   QCBORDecode_Init(&DCtx, (UsefulBufC){pEncoded, nLen}, QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    (UsefulBufC){pEncoded, nLen},
+                    QCBOR_DECODE_MODE_NORMAL);
 
    // Make sure the first thing is a map
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_ARRAY)
@@ -585,7 +591,7 @@
 
 
 
-int SimpleArrayTest()
+int32_t SimpleArrayTest()
 {
    uint8_t *pEncoded;
    size_t  nEncodedLen;
@@ -636,12 +642,14 @@
 static uint8_t sEmpties[] = {0x83, 0x00, 0x80, 0x84, 0x80, 0x81, 0x00, 0xa0,
                              0xa3, 0x01, 0xa0, 0x02, 0xa0, 0x03, 0x80};
 
-int EmptyMapsAndArraysTest()
+int32_t EmptyMapsAndArraysTest()
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sEmpties), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sEmpties),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    // Array with 3 items
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
@@ -759,15 +767,18 @@
 }
 
 
-static uint8_t spDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
+static uint8_t spDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+                                 0x81, 0x81, 0x81, 0x80};
 
-int ParseDeepArrayTest()
+int32_t ParseDeepArrayTest()
 {
    QCBORDecodeContext DCtx;
    int nReturn = 0;
    int i;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDeepArrays), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDeepArrays),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    for(i = 0; i < 10; i++) {
       QCBORItem Item;
@@ -784,12 +795,12 @@
 }
 
 // Big enough to test nesting to the depth of 24
-static uint8_t spTooDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-                                    0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-                                    0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-                                    0x80};
+static uint8_t spTooDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+                                    0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+                                    0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+                                    0x81, 0x81, 0x81, 0x80};
 
-int ParseTooDeepArrayTest()
+int32_t ParseTooDeepArrayTest()
 {
    QCBORDecodeContext DCtx;
    int nReturn = 0;
@@ -797,7 +808,9 @@
    QCBORItem Item;
 
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooDeepArrays), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooDeepArrays),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    for(i = 0; i < QCBOR_MAX_ARRAY_NESTING1; i++) {
 
@@ -818,16 +831,18 @@
 
 
 
-int ShortBufferParseTest()
+int32_t ShortBufferParseTest()
 {
    int nResult = 0;
 
-   for(int nNum = sizeof(spExpectedEncodedInts)-1; nNum; nNum--) {
+   for(size_t nNum = sizeof(spExpectedEncodedInts)-1; nNum; nNum--) {
       QCBORDecodeContext DCtx;
 
-      QCBORDecode_Init(&DCtx, (UsefulBufC){spExpectedEncodedInts, nNum}, QCBOR_DECODE_MODE_NORMAL);
+      QCBORDecode_Init(&DCtx,
+                       (UsefulBufC){spExpectedEncodedInts, nNum},
+                       QCBOR_DECODE_MODE_NORMAL);
 
-      const QCBORError nErr = IntegerValuesParseTestInternal(&DCtx);
+      const int nErr = IntegerValuesParseTestInternal(&DCtx);
 
       if(nErr != QCBOR_ERR_HIT_END && nErr != QCBOR_ERR_NO_MORE_ITEMS) {
          nResult = -1;
@@ -840,7 +855,7 @@
 
 
 
-int ShortBufferParseTest2()
+int32_t ShortBufferParseTest2()
 {
    uint8_t *pEncoded;
    int      nReturn;
@@ -868,15 +883,18 @@
 
 /*
  Decode and thoroughly check a moderately complex
- set of maps
+ set of maps. Can be run in QCBOR_DECODE_MODE_NORMAL or in
+ QCBOR_DECODE_MODE_MAP_STRINGS_ONLY.
  */
-static int ParseMapTest1(QCBORDecodeMode nMode)
+static int32_t ParseMapTest1(QCBORDecodeMode nMode)
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
 
-   QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, nMode);
+   QCBORDecode_Init(&DCtx,
+                    (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)},
+                    nMode);
 
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
@@ -995,13 +1013,15 @@
  Decode and thoroughly check a moderately complex
  set of maps
  */
-int ParseMapAsArrayTest()
+int32_t ParseMapAsArrayTest()
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_MAP_AS_ARRAY);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded),
+                    QCBOR_DECODE_MODE_MAP_AS_ARRAY);
 
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
@@ -1202,13 +1222,15 @@
  and made prettier and maybe a little more
  thorough.
  */
-static int ExtraBytesTest(int nLevel)
+static int32_t ExtraBytesTest(int nLevel)
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
 
-   QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)},
+                    QCBOR_DECODE_MODE_NORMAL);
 
    if(nLevel < 1) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
@@ -1394,37 +1416,52 @@
 
 
 
-
-int ParseMapTest()
+/*
+ Public function for initialization. See header qcbor.h
+ */
+int32_t ParseMapTest()
 {
-   // Parse a moderatly complex map structure very thoroughl
-   int n = ParseMapTest1(QCBOR_DECODE_MODE_NORMAL);
+   // Parse a moderatly complex map structure very thoroughly
+   int32_t nResult = ParseMapTest1(QCBOR_DECODE_MODE_NORMAL);
+   if(nResult) {
+      return nResult;
+   }
 
-   n = ParseMapTest1(QCBOR_DECODE_MODE_MAP_STRINGS_ONLY);
+   // Again, but in strings-only mode. It should succeed since the input
+   // map has only string labels.
+   nResult = ParseMapTest1(QCBOR_DECODE_MODE_MAP_STRINGS_ONLY);
+   if(nResult) {
+      return nResult;
+   }
 
-   if(!n) {
-      for(int i = 0; i < 10; i++) {
-         n = ExtraBytesTest(i);
-         if(n) {
-            break;
-         }
+   // Again, but try to finish the decoding before the end of the
+   // input at 10 different place and see that the right error code
+   // is returned.
+   for(int i = 0; i < 10; i++) {
+      nResult = ExtraBytesTest(i);
+      if(nResult) {
+         break;
       }
    }
 
-   return(n);
+   return nResult;
 }
 
 
-static uint8_t spSimpleValues[] = {0x8a, 0xf4, 0xf5, 0xf6, 0xf7, 0xff, 0xe0, 0xf3, 0xf8, 0x00, 0xf8, 0x13, 0xf8, 0x1f, 0xf8, 0x20, 0xf8, 0xff};
+static uint8_t spSimpleValues[] = {0x8a, 0xf4, 0xf5, 0xf6, 0xf7, 0xff,
+                                   0xe0, 0xf3, 0xf8, 0x00, 0xf8, 0x13,
+                                   0xf8, 0x1f, 0xf8, 0x20, 0xf8, 0xff};
 
-int ParseSimpleTest()
+int32_t ParseSimpleTest()
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
 
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues),
+                    QCBOR_DECODE_MODE_NORMAL);
 
 
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
@@ -1509,7 +1546,7 @@
 }
 
 
-int NotWellFormedTests()
+int32_t NotWellFormedTests()
 {
    // Loop over all the not-well-formed instance of CBOR
    // that are test vectors in not_well_formed_cbor.h
@@ -1518,7 +1555,8 @@
       const struct someBinaryBytes *pBytes = &paNotWellFormedCBOR[nIterate];
       const UsefulBufC Input = (UsefulBufC){pBytes->p, pBytes->n};
 
-      // Set up decoder context. String allocator needed for indefinite string test cases
+      // Set up decoder context. String allocator needed for indefinite
+      // string test cases
       QCBORDecodeContext DCtx;
       QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
       UsefulBuf_MAKE_STACK_UB(Pool, 100);
@@ -1545,10 +1583,48 @@
 
 
 struct FailInput {
-   UsefulBufC Input;  // CBOR to decode
-   QCBORError nError; // The error expected
+   UsefulBufC Input;
+   QCBORError nError;
 };
 
+
+static int32_t ProcessFailures(struct FailInput *pFailInputs, size_t nNumFails)
+{
+   for(struct FailInput *pF = pFailInputs; pF < pFailInputs + nNumFails; pF++) {
+      // Set up the decoding context including a memory pool so that
+      // indefinite length items can be checked
+      QCBORDecodeContext DCtx;
+      QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
+      UsefulBuf_MAKE_STACK_UB(Pool, 100);
+      QCBORError nCBORError = QCBORDecode_SetMemPool(&DCtx, Pool, 0);
+      if(nCBORError) {
+         return -9;
+      }
+
+      // Iterate until there is an error of some sort error
+      QCBORItem Item;
+      do {
+         // Set to something none-zero other than QCBOR_TYPE_NONE
+         memset(&Item, 0x33, sizeof(Item));
+
+         nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+      } while(nCBORError == QCBOR_SUCCESS);
+
+      // Must get the expected error or the this test fails
+      // The data and label type must also be QCBOR_TYPE_NONE
+      if(nCBORError != pF->nError ||
+         Item.uDataType != QCBOR_TYPE_NONE ||
+         Item.uLabelType != QCBOR_TYPE_NONE) {
+         // return index of CBOR + 100
+         const size_t nIndex = (size_t)(pF - pFailInputs)/sizeof(struct FailInput);
+         return (int32_t)(nIndex * 100 + nCBORError);
+      }
+   }
+
+   return 0;
+}
+
+
 struct FailInput  Failures[] = {
    // Most of this is copied from not_well_formed.h. Here the error code
    // returned is also checked.
@@ -1616,9 +1692,11 @@
    // Deeply nested indefinite length arrays with deepest one unclosed
    { {(uint8_t[]){0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 9}, QCBOR_ERR_HIT_END },
    // Mixed nesting with indefinite unclosed
-   { {(uint8_t[]){0x9f, 0x81, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff}, 9}, QCBOR_ERR_BAD_BREAK }, // TODO: think through this one
+   // TODO: think through this one
+   { {(uint8_t[]){0x9f, 0x81, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff}, 9}, QCBOR_ERR_BAD_BREAK },
    // Mixed nesting with definite unclosed
-   { {(uint8_t[]){0x9f, 0x82, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 10}, QCBOR_ERR_BAD_BREAK }, // TODO: think through this one
+   // TODO: think through this one
+   { {(uint8_t[]){0x9f, 0x82, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 10}, QCBOR_ERR_BAD_BREAK },
 
 
    // The "argument" for the data item is incomplete
@@ -1746,10 +1824,10 @@
    { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END },
    // A text string is of length 1 without the 1 byte
    { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END },
-   // Byte string should have 2^32-1 bytes, but has one
-   { {(uint8_t[]){0x5a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6}, QCBOR_ERR_HIT_END },
-   // Byte string should have 2^32-1 bytes, but has one
-   { {(uint8_t[]){0x7a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6}, QCBOR_ERR_HIT_END },
+   // Byte string should have 2^32-15 bytes, but has one
+   { {(uint8_t[]){0x5a, 0xff, 0xff, 0xff, 0xf0, 0x00}, 6}, QCBOR_ERR_HIT_END },
+   // Byte string should have 2^32-15 bytes, but has one
+   { {(uint8_t[]){0x7a, 0xff, 0xff, 0xff, 0xf0, 0x00}, 6}, QCBOR_ERR_HIT_END },
 
 
    // Use of unassigned additional information values
@@ -1815,46 +1893,23 @@
 
 
    // In addition to not-well-formed, some invalid CBOR
-   { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG },  // Text-based date, with an integer
-   { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG },   // Epoch date, with an byte string
-   { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG },   // tagged as both epoch and string dates
-   { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG },  // big num tagged an int, not a byte string
+   // Text-based date, with an integer
+   { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG },
+   // Epoch date, with an byte string
+   { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG },
+   // tagged as both epoch and string dates
+   { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG },
+   // big num tagged an int, not a byte string
+   { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG },
 };
 
-int DecodeFailureTests()
+int32_t DecodeFailureTests()
 {
-   // Loop over the failures
-   const struct FailInput * const pFEnd = &Failures[0] +
-                                          sizeof(Failures)/sizeof(struct FailInput);
-   for(const struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
+   int32_t nResult;
 
-      // Set up the decoding context including a memory pool so that
-      // indefinite length items can be checked
-      QCBORDecodeContext DCtx;
-      QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
-      UsefulBuf_MAKE_STACK_UB(Pool, 100);
-      QCBORError nCBORError = QCBORDecode_SetMemPool(&DCtx, Pool, 0);
-      if(nCBORError) {
-         return -9;
-      }
-
-      // Iterate until there is an error of some sort error
-      QCBORItem Item;
-      do {
-         // Set to something none-zero other than QCBOR_TYPE_NONE
-         memset(&Item, 0x33, sizeof(Item));
-
-         nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
-      } while(nCBORError == QCBOR_SUCCESS);
-
-      // Must get the expected error or the this test fails
-      // The data and label type must also be QCBOR_TYPE_NONE
-      if(nCBORError != pF->nError ||
-         Item.uDataType != QCBOR_TYPE_NONE ||
-         Item.uLabelType != QCBOR_TYPE_NONE) {
-         // return index of CBOR + 1000
-         return 1000 + (int)(pF - &Failures[0]);
-      }
+   nResult = ProcessFailures(Failures, sizeof(Failures)/sizeof(struct FailInput));
+   if(nResult) {
+      return nResult;
    }
 
    // Corrupt the UsefulInputBuf and see that
@@ -1885,6 +1940,29 @@
       }
    }
 
+/*
+   This test is disabled until QCBOREncode_EncodeHead() is brought in so
+ the size encoded can be tied to SIZE_MAX and work for all size CPUs.
+
+ This relies on the largest string allowed being SIZE_MAX -4 rather than
+ SIZE_MAX. That way the test can be performed.
+   {
+      QCBORDecodeContext DCtx;
+      QCBORItem          Item;
+
+      static uint8_t foo[] = {0x5b, 0xff, 0xff, 0xff, 0xff,
+                                    0xff, 0xff, 0xff, 0xff};
+
+      QCBORDecode_Init(&DCtx,
+                       UsefulBuf_FROM_BYTE_ARRAY_LITERAL(foo),
+                       QCBOR_DECODE_MODE_NORMAL);
+
+      if(QCBOR_ERR_STRING_TOO_LONG != QCBORDecode_GetNext(&DCtx, &Item)) {
+         return -4;
+      }
+   }
+*/
+
    return 0;
 }
 
@@ -1892,7 +1970,7 @@
 /* Try all 256 values of the byte at nLen including recursing for
  each of the values to try values at nLen+1 ... up to nLenMax
  */
-static void ComprehensiveInputRecurser(uint8_t *pBuf, int nLen, int nLenMax)
+static void ComprehensiveInputRecurser(uint8_t *pBuf, size_t nLen, size_t nLenMax)
 {
    if(nLen >= nLenMax) {
       return;
@@ -1900,7 +1978,7 @@
 
    for(int inputByte = 0; inputByte < 256; inputByte++) {
       // Set up the input
-      pBuf[nLen] = inputByte;
+      pBuf[nLen] = (uint8_t)inputByte;
       const UsefulBufC Input = {pBuf, nLen+1};
 
       // Get ready to parse
@@ -1928,7 +2006,7 @@
 /*
  Public function for initialization. See header qcbor.h
  */
-int ComprehensiveInputTest()
+int32_t ComprehensiveInputTest()
 {
    // Size 2 tests 64K inputs and runs quickly
    uint8_t pBuf[2];
@@ -1942,7 +2020,7 @@
 /*
  Public function for initialization. See header qcbor.h
  */
-int BigComprehensiveInputTest()
+int32_t BigComprehensiveInputTest()
 {
    // size 3 tests 16 million inputs and runs OK
    // in seconds on fast machines. Size 4 takes
@@ -1998,13 +2076,15 @@
 }
 
 
-int DateParseTest()
+int32_t DateParseTest()
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    const uint64_t uTags[] = {15};
    QCBORTagListIn TagList = {1, uTags};
@@ -2070,7 +2150,8 @@
       Item.val.epochDate.nSeconds == 0) {
       return -12;
    }
-   // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
+   // TODO: could use a few more tests with float, double, and half precsion
+   // and negative (but coverage is still pretty good)
 
    return 0;
 }
@@ -2082,15 +2163,27 @@
    0xd8, 0x04, // non-preferred serialization of tag 4
    0x82, 0x01, 0x03}; // fraction 1/3
 
-static uint8_t spEncodedLargeTag[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x80};
+/*
+ DB 9192939495969798 # tag(10489608748473423768)
+   80               # array(0)
+ */
+static uint8_t spEncodedLargeTag[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95,
+                                      0x96, 0x97, 0x98, 0x80};
 
-// 0x9192939495969798, 0x88, 0x01, 0x04
-static uint8_t spLotsOfTags[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0xd8, 0x88, 0xc5, 0xc4, 0x80};
+/*
+DB 9192939495969798 # tag(10489608748473423768)
+   D8 88            # tag(136)
+      C6            # tag(6)
+         C7         # tag(7)
+            80      # array(0)
+*/
+static uint8_t spLotsOfTags[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+                                 0x97, 0x98, 0xd8, 0x88, 0xc6, 0xc7, 0x80};
 
 /*
  The cbor.me parse of this.
  55799(55799(55799({6(7(-23)): 5859837686836516696(7({7(-20): 11({17(-18): 17(17(17("Organization"))),
- 9(-17): 773("SSG"), -15: 4(5(6(7(8(9(10(11(12(13(14(15("Confusion")))))))))))), 17(-16): 17("San Diego"),
+ 9(-17): 773("SSG"), -15: 16(17(6(7(8(9(10(11(12(13(14(15("Confusion")))))))))))), 17(-16): 17("San Diego"),
  17(-14): 17("US")}), 23(-19): 19({-11: 9({-9: -7}),
  90599561(90599561(90599561(-10))): 12(h'0102030405060708090A')})})),
  16(-22): 23({11(8(7(-5))): 8(-3)})})))
@@ -2108,7 +2201,7 @@
             0xd9, 0x03, 0x05, 0x63,
                0x53, 0x53, 0x47,
             0x2e,
-            0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x69,
+            0xd0, 0xd1, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x69,
                0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x69, 0x6f, 0x6e,
             0xd1, 0x2f,
             0xd1, 0x69,
@@ -2130,15 +2223,17 @@
       0xcb, 0xc8, 0xc7, 0x24,
       0xc8, 0x22};
 
-static int CheckCSRMaps(QCBORDecodeContext *pDC);
+static int32_t CheckCSRMaps(QCBORDecodeContext *pDC);
 
 
-int OptTagParseTest()
+int32_t OptTagParseTest()
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spOptTestInput), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spOptTestInput),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    //-------------------------
    // This text matches the magic number tag and the fraction tag
@@ -2153,16 +2248,25 @@
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -4;
    }
+
+#ifdef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
    if(Item.uDataType != QCBOR_TYPE_ARRAY ||
-      !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_FRACTION) ||
+      !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_DECIMAL_FRACTION) ||
       Item.val.uCount != 2) {
       return -5;
    }
+#else
+   if(Item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION) {
+      return -6;
+   }
+#endif
 
    // --------------------------------
    // This test decodes the very large tag, but it is not in
    // any list so it is ignored.
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag),
+                    QCBOR_DECODE_MODE_NORMAL);
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -6;
    }
@@ -2171,8 +2275,11 @@
    }
 
    // ----------------------------------
-   // This test sets up a caller-config list that includes the very large tage and then matches it.
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
+   // This test sets up a caller-config list that includes the very large
+   // tage and then matches it.
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag),
+                    QCBOR_DECODE_MODE_NORMAL);
    const uint64_t puList[] = {0x9192939495969798, 257};
    const QCBORTagListIn TL = {2, puList};
    QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TL);
@@ -2189,10 +2296,12 @@
    }
 
    //------------------------
-   // This test sets up a caller-configured list, and looks up something not in it
+   // Sets up a caller-configured list and look up something not in it
    const uint64_t puLongList[17] = {1,2,1};
    const QCBORTagListIn TLLong = {17, puLongList};
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag),
+                    QCBOR_DECODE_MODE_NORMAL);
    QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TLLong);
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -11;
@@ -2200,7 +2309,9 @@
 
    // -----------------------
    // This tests retrievel of the full tag list
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags),
+                    QCBOR_DECODE_MODE_NORMAL);
    uint64_t puTags[16];
    QCBORTagListOut Out = {0, 4, puTags};
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
@@ -2208,14 +2319,16 @@
    }
    if(puTags[0] != 0x9192939495969798 ||
       puTags[1] != 0x88 ||
-      puTags[2] != 0x05 ||
-      puTags[3] != 0x04) {
+      puTags[2] != 0x06 ||
+      puTags[3] != 0x07) {
       return -13;
    }
 
    // ----------------------
    // This text if too small of an out list
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags),
+                    QCBOR_DECODE_MODE_NORMAL);
    QCBORTagListOut OutSmall = {0, 3, puTags};
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &OutSmall) != QCBOR_ERR_TOO_MANY_TAGS) {
       return -14;
@@ -2223,14 +2336,18 @@
 
    // ---------------
    // Parse a version of the "CSR" that has had a ton of tags randomly inserted
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags),
+                    QCBOR_DECODE_MODE_NORMAL);
    int n = CheckCSRMaps(&DCtx);
    if(n) {
       return n-2000;
    }
 
-   Out = (QCBORTagListOut){0,16, puTags};
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
+   Out = (QCBORTagListOut){0, 16, puTags};
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    const uint64_t puTagList[] = {773, 1, 90599561};
    const QCBORTagListIn TagList = {3, puTagList};
@@ -2305,9 +2422,9 @@
       return -109;
    }
    if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
-      !QCBORDecode_IsTagged(&DCtx, &Item, 4) ||
+      !QCBORDecode_IsTagged(&DCtx, &Item, 16) ||
       Item.val.string.len != 9 ||
-      puTags[0] != 4 ||
+      puTags[0] != 16 ||
       puTags[11] != 0x0f ||
       Out.uNumUsed != 12) {
       return -110;
@@ -2429,13 +2546,15 @@
 static uint8_t spBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
 
-int BignumParseTest()
+int32_t BignumParseTest()
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNumInput), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNumInput),
+                    QCBOR_DECODE_MODE_NORMAL);
 
 
    //
@@ -2507,7 +2626,12 @@
 
 
 
-static int CheckItemWithIntLabel(QCBORDecodeContext *pCtx, uint8_t uDataType, uint8_t uNestingLevel, uint8_t uNextNest, int64_t nLabel, QCBORItem *pItem)
+static int32_t CheckItemWithIntLabel(QCBORDecodeContext *pCtx,
+                                 uint8_t uDataType,
+                                 uint8_t uNestingLevel,
+                                 uint8_t uNextNest,
+                                 int64_t nLabel,
+                                 QCBORItem *pItem)
 {
    QCBORItem Item;
    int nCBORError;
@@ -2515,7 +2639,10 @@
    if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
    if(Item.uDataType != uDataType) return -1;
    if(uNestingLevel > 0) {
-      if(Item.uLabelType != QCBOR_TYPE_INT64 &&  Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
+      if(Item.uLabelType != QCBOR_TYPE_INT64 &&
+         Item.uLabelType != QCBOR_TYPE_UINT64) {
+         return -1;
+      }
       if(Item.uLabelType == QCBOR_TYPE_INT64) {
          if(Item.label.int64 != nLabel) return -1;
       } else  {
@@ -2533,7 +2660,7 @@
 
 
 // Same code checks definite and indefinite length versions of the map
-static int CheckCSRMaps(QCBORDecodeContext *pDC)
+static int32_t CheckCSRMaps(QCBORDecodeContext *pDC)
 {
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
 
@@ -2598,22 +2725,26 @@
    0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
    0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
 
-int NestedMapTest()
+int32_t NestedMapTest()
 {
    QCBORDecodeContext DCtx;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    return CheckCSRMaps(&DCtx);
 }
 
 
 
-int StringDecoderModeFailTest()
+int32_t StringDecoderModeFailTest()
 {
    QCBORDecodeContext DCtx;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_MAP_STRINGS_ONLY);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput),
+                    QCBOR_DECODE_MODE_MAP_STRINGS_ONLY);
 
    QCBORItem Item;
    QCBORError nCBORError;
@@ -2647,11 +2778,13 @@
    0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff,
    0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
 
-int NestedMapTestIndefLen()
+int32_t NestedMapTestIndefLen()
 {
    QCBORDecodeContext DCtx;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInputIndefLen),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    return CheckCSRMaps(&DCtx);
 }
@@ -2675,7 +2808,7 @@
 }
 
 
-static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
+static int32_t parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
 {
    QCBORDecodeContext DC;
    QCBORDecode_Init(&DC, Nested, 0);
@@ -2709,7 +2842,7 @@
 }
 
 
-int IndefiniteLengthNestTest()
+int32_t IndefiniteLengthNestTest()
 {
    UsefulBuf_MAKE_STACK_UB(Storage, 50);
    int i;
@@ -2724,15 +2857,20 @@
 }
 
 
+// [1, [2, 3]]
+static const uint8_t spIndefiniteArray[]     = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff};
+// No closing break
+static const uint8_t spIndefiniteArrayBad1[] = {0x9f};
+// Not enough closing breaks
+static const uint8_t spIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff};
+// Too many closing breaks
+static const uint8_t spIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff};
+// Unclosed indeflen inside def len
+static const uint8_t spIndefiniteArrayBad4[] = {0x81, 0x9f};
+// confused tag
+static const uint8_t spIndefiniteArrayBad5[] = {0x9f, 0xd1, 0xff};
 
-static const uint8_t spIndefiniteArray[]     = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
-static const uint8_t spIndefiniteArrayBad1[] = {0x9f}; // No closing break
-static const uint8_t spIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
-static const uint8_t spIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
-static const uint8_t spIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
-static const uint8_t spIndefiniteArrayBad5[] = {0x9f, 0xd1, 0xff}; // confused tag
-
-int IndefiniteLengthArrayMapTest()
+int32_t IndefiniteLengthArrayMapTest()
 {
    int nResult;
    // --- first test -----
@@ -2933,7 +3071,16 @@
    0x01 // integer being labeled.
 };
 
-static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage) // TODO: size this
+/**
+ Make an indefinite length string
+
+ @param Storage Storage for string, must be 144 bytes in size
+ @return The indefinite length string
+
+ This makes an array with one indefinite length string that has 7 chunks
+ from size of 1 byte up to 64 bytes.
+ */
+static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
 {
    UsefulOutBuf UOB;
 
@@ -2941,13 +3088,15 @@
    UsefulOutBuf_AppendByte(&UOB, 0x81);
    UsefulOutBuf_AppendByte(&UOB, 0x5f);
 
-   int i = 0;
-   for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
+   uint8_t uStringByte = 0;
+   // Use of type int is intentional
+   for(int uChunkSize = 1; uChunkSize <= 128; uChunkSize *= 2) {
+      // Not using preferred encoding here, but that is OK.
       UsefulOutBuf_AppendByte(&UOB, 0x58);
-      UsefulOutBuf_AppendByte(&UOB, (uint8_t)nChunkSize);
-      for(int j = 0; j < nChunkSize; j++ ) {
-         UsefulOutBuf_AppendByte(&UOB, i);
-         i++;
+      UsefulOutBuf_AppendByte(&UOB, (uint8_t)uChunkSize);
+      for(int j = 0; j < uChunkSize; j++) {
+         UsefulOutBuf_AppendByte(&UOB, uStringByte);
+         uStringByte++;
       }
    }
    UsefulOutBuf_AppendByte(&UOB, 0xff);
@@ -2970,7 +3119,7 @@
 }
 
 
-int IndefiniteLengthStringTest()
+int32_t IndefiniteLengthStringTest()
 {
    QCBORDecodeContext DC;
    QCBORItem Item;
@@ -3003,7 +3152,9 @@
    }
 
    // ----- types mismatch ---
-   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad2),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -7;
@@ -3021,7 +3172,9 @@
    }
 
    // ----- not a string ---
-   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad3),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -11;
@@ -3039,7 +3192,9 @@
    }
 
    // ----- no end -----
-   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad4),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -15;
@@ -3080,7 +3235,8 @@
    UsefulBuf_MAKE_STACK_UB(BigIndefBStrStorage, 290);
    const UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
 
-   UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
+   // 80 is big enough for MemPool overhead, but not BigIndefBStr
+   UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80);
 
    QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
    if(QCBORDecode_SetMemPool(&DC,  MemPoolSmall, false)) {
@@ -3137,7 +3293,8 @@
    if(QCBORDecode_GetNext(&DC, &Item)){
       return -32;
    }
-   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING || Item.uDataType != QCBOR_TYPE_INT64 ||
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.uDataAlloc || !Item.uLabelAlloc ||
       UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
       return -33;
@@ -3151,14 +3308,16 @@
 }
 
 
-int AllocAllStringsTest()
+int32_t AllocAllStringsTest()
 {
    QCBORDecodeContext DC;
    QCBORError nCBORError;
 
 
    // First test, use the "CSRMap" as easy input and checking
-   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput),
+                    QCBOR_DECODE_MODE_NORMAL);
 
    UsefulBuf_MAKE_STACK_UB(Pool, sizeof(spCSRInput) + QCBOR_DECODE_MIN_MEM_POOL_SIZE);
 
@@ -3230,7 +3389,9 @@
 
    // Next parse with a pool that is too small
    UsefulBuf_MAKE_STACK_UB(SmallPool, QCBOR_DECODE_MIN_MEM_POOL_SIZE + 1);
-   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded),
+                    QCBOR_DECODE_MODE_NORMAL);
    QCBORDecode_SetMemPool(&DC, SmallPool, 1); // Turn on copying.
    if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
       return -8;
@@ -3254,7 +3415,7 @@
 
 
 
-int MemPoolTest(void)
+int32_t MemPoolTest(void)
 {
    // Set up the decoder with a tiny bit of CBOR to parse because
    // nothing can be done with it unless that is set up.
@@ -3352,7 +3513,7 @@
 }
 
 
-int SetUpAllocatorTest(void)
+int32_t SetUpAllocatorTest(void)
 {
    // Set up the decoder with a tiny bit of CBOR to parse because
    // nothing can be done with it unless that is set up.
@@ -3385,3 +3546,235 @@
    return 0;
 }
 
+
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+/*
+  [
+    4([-1, 3]),
+    4([-20, 4759477275222530853136]),
+    4([9223372036854775807, -4759477275222530853137]),
+    5([300, 100]),
+    5([-20, 4759477275222530853136]),
+    5([-9223372036854775807, -4759477275222530853137])
+    5([9223372036854775806, -4759477275222530853137])
+    5([9223372036854775806, 9223372036854775806])]
+ ]
+ */
+
+static const uint8_t spExpectedExponentsAndMantissas[] = {
+   0x87,
+   0xC4, 0x82, 0x20,
+               0x03,
+   0xC4, 0x82, 0x33,
+               0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+   0xC4, 0x82, 0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+               0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+   0xC5, 0x82, 0x19, 0x01, 0x2C,
+               0x18, 0x64,
+   0xC5, 0x82, 0x33,
+               0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+   0xC5, 0x82, 0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+               0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+   0xC5, 0x82, 0x1B, 0x7f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+               0x1B, 0x7f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE
+};
+
+int32_t ExponentAndMantissaDecodeTests(void)
+{
+   QCBORDecodeContext DC;
+   QCBORError         nCBORError;
+   QCBORItem          item;
+
+   static const uint8_t spBigNumMantissa[] = {0x01, 0x02, 0x03, 0x04, 0x05,
+                                              0x06, 0x07, 0x08, 0x09, 0x010};
+   UsefulBufC BN = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNumMantissa);
+
+
+   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedExponentsAndMantissas), QCBOR_DECODE_MODE_NORMAL);
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 1;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_ARRAY) {
+      return 2;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 3;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION ||
+      item.val.expAndMantissa.Mantissa.nInt != 3 ||
+      item.val.expAndMantissa.nExponent != -1) {
+      return 4;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 5;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM ||
+      item.val.expAndMantissa.nExponent != -20 ||
+      UsefulBuf_Compare(item.val.expAndMantissa.Mantissa.bigNum, BN)) {
+      return 6;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 7;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM ||
+      item.val.expAndMantissa.nExponent != 9223372036854775807 ||
+      UsefulBuf_Compare(item.val.expAndMantissa.Mantissa.bigNum, BN)) {
+      return 8;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 9;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_BIGFLOAT ||
+      item.val.expAndMantissa.Mantissa.nInt != 100 ||
+      item.val.expAndMantissa.nExponent != 300) {
+      return 10;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 11;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_BIGFLOAT_POS_BIGNUM ||
+      item.val.expAndMantissa.nExponent != -20 ||
+      UsefulBuf_Compare(item.val.expAndMantissa.Mantissa.bigNum, BN)) {
+      return 12;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 13;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM ||
+      item.val.expAndMantissa.nExponent != -9223372036854775807 ||
+      UsefulBuf_Compare(item.val.expAndMantissa.Mantissa.bigNum, BN)) {
+      return 14;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 15;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_BIGFLOAT ||
+      item.val.expAndMantissa.nExponent != 9223372036854775806 ||
+      item.val.expAndMantissa.Mantissa.nInt!= 9223372036854775806 ) {
+      return 16;
+   }
+
+   /* Now encode some stuff and then decode it */
+   uint8_t pBuf[40];
+   QCBOREncodeContext EC;
+   UsefulBufC Encoded;
+
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(pBuf));
+   QCBOREncode_OpenArray(&EC);
+   QCBOREncode_AddDecimalFraction(&EC, 999, 1000); // 999 * (10 ^ 1000)
+   QCBOREncode_AddBigFloat(&EC, 100, INT32_MIN);
+   QCBOREncode_AddDecimalFractionBigNum(&EC, BN, false, INT32_MAX);
+   QCBOREncode_CloseArray(&EC);
+   QCBOREncode_Finish(&EC, &Encoded);
+
+
+   QCBORDecode_Init(&DC, Encoded, QCBOR_DECODE_MODE_NORMAL);
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 13;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 13;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION ||
+      item.val.expAndMantissa.nExponent != 1000 ||
+      item.val.expAndMantissa.Mantissa.nInt != 999) {
+      return 15;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 13;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_BIGFLOAT ||
+      item.val.expAndMantissa.nExponent != INT32_MIN ||
+      item.val.expAndMantissa.Mantissa.nInt != 100) {
+      return 15;
+   }
+
+   nCBORError = QCBORDecode_GetNext(&DC, &item);
+   if(nCBORError != QCBOR_SUCCESS) {
+      return 13;
+   }
+
+   if(item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM ||
+      item.val.expAndMantissa.nExponent != INT32_MAX ||
+      UsefulBuf_Compare(item.val.expAndMantissa.Mantissa.bigNum, BN)) {
+      return 12;
+   }
+
+   return 0;
+}
+
+
+static struct FailInput ExponentAndMantissaFailures[] = {
+   // Exponent > INT64_MAX
+   { {(uint8_t[]){0xC4, 0x82, 0x1B, 0x7f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                  0xFF, 0xFF, 0x1B, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                  0xFF, 0xFF,}, 20}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+   // Mantissa > INT64_MAX
+   { {(uint8_t[]){0xC4, 0x82, 0x1B, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                  0xFF, 0xFF, 0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05,
+                  0x06, 0x07, 0x08, 0x09, 0x10}, 23}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+   // End of input
+   { {(uint8_t[]){0xC4, 0x82}, 2}, QCBOR_ERR_HIT_END},
+   // End of input
+   { {(uint8_t[]){0xC4, 0x82, 0x01}, 3}, QCBOR_ERR_HIT_END},
+   // bad content for big num
+   { {(uint8_t[]){0xC4, 0x82, 0x01, 0xc3, 0x01}, 5}, QCBOR_ERR_BAD_OPT_TAG},
+   // bad content for big num
+   { {(uint8_t[]){0xC4, 0x82, 0xc2, 0x01, 0x1f}, 5}, QCBOR_ERR_BAD_INT},
+   // Bad integer for exponent
+   { {(uint8_t[]){0xC4, 0x82, 0x01, 0x1f}, 4}, QCBOR_ERR_BAD_INT},
+   // Bad integer for mantissa
+   { {(uint8_t[]){0xC4, 0x82, 0x1f, 0x01}, 4}, QCBOR_ERR_BAD_INT},
+   // 3 items in array
+   { {(uint8_t[]){0xC4, 0x83, 0x03, 0x01, 02}, 5}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+   // unterminated indefinite length array
+   { {(uint8_t[]){0xC4, 0x9f, 0x03, 0x01, 0x02}, 5}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+   // Empty array
+   { {(uint8_t[]){0xC4, 0x80}, 2}, QCBOR_ERR_NO_MORE_ITEMS},
+   // Second is not an integer
+   { {(uint8_t[]){0xC4, 0x82, 0x03, 0x40}, 4}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+   // First is not an integer
+   { {(uint8_t[]){0xC4, 0x82, 0x40}, 3}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+   // Not an array
+   { {(uint8_t[]){0xC4, 0xa2}, 2}, QCBOR_ERR_BAD_EXP_AND_MANTISSA}
+};
+
+
+int32_t ExponentAndMantissaDecodeFailTests()
+{
+   return ProcessFailures(ExponentAndMantissaFailures,
+                          sizeof(ExponentAndMantissaFailures)/sizeof(struct FailInput));
+}
+
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
diff --git a/lib/ext/qcbor/test/qcbor_decode_tests.h b/lib/ext/qcbor/test/qcbor_decode_tests.h
index 6423ccf..e87490e 100644
--- a/lib/ext/qcbor/test/qcbor_decode_tests.h
+++ b/lib/ext/qcbor/test/qcbor_decode_tests.h
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2019, Laurence Lundblade.
+ Copyright (c) 2018-2020, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -28,11 +28,12 @@
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ==============================================================================*/
+ ============================================================================*/
 
 #ifndef __QCBOR__qcbort_decode_tests__
 #define __QCBOR__qcbort_decode_tests__
 
+#include <stdint.h>
 
 /*
  Notes:
@@ -51,20 +52,20 @@
  Parse a well-known set of integers including those around the boundaries and
  make sure the expected values come out
  */
-int IntegerValuesParseTest(void);
+int32_t IntegerValuesParseTest(void);
 
 
 /*
  Decode a simple CBOR encoded array and make sure it returns all the correct values.
  This is a decode test.
  */
-int SimpleArrayTest(void);
+int32_t SimpleArrayTest(void);
 
 
 /*
  Tests with empty maps and arrays
  */
-int EmptyMapsAndArraysTest(void);
+int32_t EmptyMapsAndArraysTest(void);
 
 
 /*
@@ -72,21 +73,21 @@
  reported nesting level is correct.  This uses test vector
  of CBOR encoded data with a depth of 10.  This a parse test.
  */
-int ParseDeepArrayTest(void);
+int32_t ParseDeepArrayTest(void);
 
 
 /*
  See that the correct error is reported when parsing
  an array of depth 11, one too large.
  */
-int ParseTooDeepArrayTest(void);
+int32_t ParseTooDeepArrayTest(void);
 
 
 /*
   Try to parse some legit CBOR types that this parsers
   doesn't support.
  */
-int UnsupportedCBORDecodeTest(void);
+int32_t UnsupportedCBORDecodeTest(void);
 
 
 /*
@@ -94,33 +95,33 @@
   it over and over with one more byte less each time. It should fail
   every time on incorrect CBOR input. This is a hostile input decode test.
  */
-int ShortBufferParseTest(void);
+int32_t ShortBufferParseTest(void);
 
 
 /*
    Same as ShortBufferParseTest, but with a different encoded CBOR input.
    It is another hostile input test
  */
-int ShortBufferParseTest2(void);
+int32_t ShortBufferParseTest2(void);
 
 
 /*
   Parses the somewhat complicated CBOR MAP and makes sure all the correct
   values parse out.  About 15 values are tested. This is a decode test.
  */
-int ParseMapTest(void);
+int32_t ParseMapTest(void);
 
 
 /*
 Test the decoder mode where maps are treated as arrays.
  */
-int ParseMapAsArrayTest(void);
+int32_t ParseMapAsArrayTest(void);
 
 
 /*
  Test parsing of some simple values like true, false, null...
  */
-int ParseSimpleTest(void);
+int32_t ParseSimpleTest(void);
 
 
 /*
@@ -128,13 +129,13 @@
  (This is the CBORbis RFC which is not yet published at the
  time this test was added).
  */
-int NotWellFormedTests(void);
+int32_t NotWellFormedTests(void);
 
 
 /*
  Tests a number of failure cases on bad CBOR to get the right error code
  */
-int DecodeFailureTests(void);
+int32_t DecodeFailureTests(void);
 
 
 /*
@@ -145,7 +146,7 @@
  (Parsing all possible 3 byte strings takes too long on all but
   very fast machines).
  */
-int ComprehensiveInputTest(void);
+int32_t ComprehensiveInputTest(void);
 
 
 /*
@@ -155,64 +156,64 @@
  is only practical as a once-in-a-while regression test on
  fast machines.
  */
-int BigComprehensiveInputTest(void);
+int32_t BigComprehensiveInputTest(void);
 
 
 /*
  Thest the date types -- epoch and strings
  */
-int DateParseTest(void);
+int32_t DateParseTest(void);
 
 
 /*
   Test optional tags like the CBOR magic number.
  */
-int OptTagParseTest(void);
+int32_t OptTagParseTest(void);
 
 
 /*
  Parse some big numbers, positive and negative
  */
-int BignumParseTest(void);
+int32_t BignumParseTest(void);
 
 
 /*
  Test of mode where only string labels are allowed
  */
-int StringDecoderModeFailTest(void);
+int32_t StringDecoderModeFailTest(void);
 
 
 /*
  Parse some nested maps
  */
-int NestedMapTest(void);
+int32_t NestedMapTest(void);
 
 
 /*
  Parse maps with indefinite lengths
  */
-int NestedMapTestIndefLen(void);
+int32_t NestedMapTestIndefLen(void);
 
 
 /*
  Parse some maps and arrays with indefinite lengths.
  Includes some error cases.
  */
-int IndefiniteLengthArrayMapTest(void);
+int32_t IndefiniteLengthArrayMapTest(void);
 
 
 /*
  Parse indefinite length strings. Uses
  MemPool. Includes error cases.
  */
-int IndefiniteLengthStringTest(void);
+int32_t IndefiniteLengthStringTest(void);
 
 
 /*
  Test deep nesting of indefinite length
  maps and arrays including too deep.
  */
-int IndefiniteLengthNestTest(void);
+int32_t IndefiniteLengthNestTest(void);
 
 
 /*
@@ -220,19 +221,34 @@
  just indefinite length strings, are
  allocated. Includes error test cases.
  */
-int AllocAllStringsTest(void);
+int32_t AllocAllStringsTest(void);
 
 
 /*
  Direct test of MemPool string allocator
  */
-int MemPoolTest(void);
+int32_t MemPoolTest(void);
 
 
 /*
  Test the setting up of an external string allocator.
  */
-int SetUpAllocatorTest(void);
+int32_t SetUpAllocatorTest(void);
+
+
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+/*
+ Test decoding of decimal fractions and big floats, both of which are
+ made up of an exponent and mantissa.
+ */
+int32_t ExponentAndMantissaDecodeTests(void);
+
+
+/*
+ Hostile input tests for decimal fractions and big floats.
+ */
+int32_t ExponentAndMantissaDecodeFailTests(void);
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
 
 #endif /* defined(__QCBOR__qcbort_decode_tests__) */
diff --git a/lib/ext/qcbor/test/qcbor_encode_tests.c b/lib/ext/qcbor/test/qcbor_encode_tests.c
index 7866b37..9ef596f 100644
--- a/lib/ext/qcbor/test/qcbor_encode_tests.c
+++ b/lib/ext/qcbor/test/qcbor_encode_tests.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2019, Laurence Lundblade.
+ Copyright (c) 2018-2020, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ==============================================================================*/
+ =============================================================================*/
 
 #include "qcbor.h"
 #include "qcbor_encode_tests.h"
@@ -47,11 +47,12 @@
 
  */
 
-//#define PRINT_FUNCTIONS_FOR_DEBUGGINGXX
+//#define PRINT_FUNCTIONS_FOR_DEBUGGING
 
-#ifdef  PRINT_FUNCTIONS_FOR_DEBUGGINGXX
+#ifdef  PRINT_FUNCTIONS_FOR_DEBUGGING
 #include <stdio.h>
 
+#if 0
 // ifdef these out to not have compiler warnings
 static void printencoded(const uint8_t *pEncoded, size_t nLen)
 {
@@ -64,6 +65,7 @@
 
    fflush(stdout);
 }
+#endif
 
 
 // Do the comparison and print out where it fails
@@ -71,7 +73,10 @@
    size_t i;
    for(i = 0; i < U1.len; i++) {
       if(((uint8_t *)U1.ptr)[i] != ((uint8_t *)U2.ptr)[i]) {
-         printf("Position: %d  Actual: 0x%x   Expected: 0x%x\n", i, ((uint8_t *)U1.ptr)[i], ((uint8_t *)U2.ptr)[i]);
+         printf("Position: %d  Actual: 0x%x   Expected: 0x%x\n",
+                (uint32_t)i,
+                ((uint8_t *)U1.ptr)[i],
+                ((uint8_t *)U2.ptr)[i]);
          return 1;
       }
    }
@@ -90,6 +95,42 @@
 #endif
 
 
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+/*
+ Returns 0 if UsefulBufs are equal
+ Returns 1000000 + offeset if they are not equal.
+
+
+
+*/
+struct UBCompareDiagnostic {
+   uint8_t uActual;
+   uint8_t uExpected;
+   size_t  uOffset;
+};
+
+static int32_t
+UsefulBuf_CompareWithDiagnostic(UsefulBufC Actual,
+                                UsefulBufC Expected,
+                                struct UBCompareDiagnostic *pDiag) {
+   size_t i;
+   for(i = 0; i < Actual.len; i++) {
+      if(((uint8_t *)Actual.ptr)[i] != ((uint8_t *)Expected.ptr)[i]) {
+         if(pDiag) {
+            pDiag->uActual   = ((uint8_t *)Actual.ptr)[i];
+            pDiag->uExpected = ((uint8_t *)Expected.ptr)[i];
+            pDiag->uOffset   = i;
+         }
+         // Cast to int is OK as this is only a diagnostic and the sizes
+         // here are never over a few KB.
+         return (int32_t)i + 1000000;
+      }
+   }
+   return 0;
+
+}
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
+
 
 // One big buffer that is used by all the tests to encode into
 // Putting it in uninitialized data is better than using a lot
@@ -101,7 +142,7 @@
 /*
  Some very minimal tests.
  */
-int BasicEncodeTest()
+int32_t BasicEncodeTest()
 {
    // Very simple CBOR, a map with one boolean that is true in it
    QCBOREncodeContext EC;
@@ -138,7 +179,8 @@
    }
 
 
-   // Make another encoded message with the CBOR from the previous put into this one
+   // Make another encoded message with the CBOR from the previous
+   // put into this one
    UsefulBuf_MAKE_STACK_UB(MemoryForEncoded2, 20);
    QCBOREncode_Init(&EC, MemoryForEncoded2);
    QCBOREncode_OpenArray(&EC);
@@ -215,7 +257,10 @@
 
    // 2    1:1   2:1   3:1
    QCBORDecode_GetNext(&DC, &Item);
-   if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1 || Item.uLabelType != QCBOR_TYPE_INT64 || Item.label.int64 != -70000) {
+   if(Item.uDataType != QCBOR_TYPE_MAP ||
+      Item.val.uCount != 1 ||
+      Item.uLabelType != QCBOR_TYPE_INT64 ||
+      Item.label.int64 != -70000) {
       return -11;
    }
 
@@ -466,9 +511,10 @@
 --XXXXboundary text--";
 
 
-int AllAddMethodsTest()
+int32_t AllAddMethodsTest()
 {
-   // TODO: this test should be broken down into several so it is more managable. Tags and labels could be more sensible
+   // TODO: this test should be broken down into several so it is more
+   // managable. Tags and labels could be more sensible
    QCBOREncodeContext ECtx;
    int nReturn = 0;
 
@@ -476,7 +522,8 @@
 
    QCBOREncode_OpenArray(&ECtx);
 
-   // Some ints that are tagged and have strings preceeding them (not labels becase it is not a map)
+   // Some ints that are tagged and have strings preceeding them
+   // (not labels becase it is not a map)
    QCBOREncode_AddSZString(&ECtx, "UINT62");
    QCBOREncode_AddTag(&ECtx, 100);
    QCBOREncode_AddUInt64(&ECtx, 89989909);
@@ -519,7 +566,9 @@
    // text blobs
    QCBOREncode_AddText(&ECtx, UsefulBuf_FROM_SZ_LITERAL("bar bar foo bar"));
    QCBOREncode_AddSZString(&ECtx, "oof\n");
-   QCBOREncode_AddURI(&ECtx, UsefulBuf_FROM_SZ_LITERAL("http://stackoverflow.com/questions/28059697/how-do-i-toggle-between-debug-and-release-builds-in-xcode-6-7-8"));
+   const char *szURL =
+      "http://stackoverflow.com/questions/28059697/how-do-i-toggle-between-debug-and-release-builds-in-xcode-6-7-8";
+   QCBOREncode_AddURI(&ECtx, UsefulBuf_FromSZ(szURL));
    QCBOREncode_AddB64Text(&ECtx, UsefulBuf_FROM_SZ_LITERAL("YW55IGNhcm5hbCBwbGVhc3VyZQ=="));
    QCBOREncode_AddRegex(&ECtx, UsefulBuf_FROM_SZ_LITERAL("[^abc]+"));
    QCBOREncode_AddMIMEData(&ECtx, UsefulBuf_FromSZ(szMIME));
@@ -534,7 +583,9 @@
    QCBOREncode_AddTextToMapN(&ECtx,22, UsefulBuf_FROM_SZ_LITERAL("foo foo foo foo"));
    QCBOREncode_AddSZStringToMap(&ECtx, "^^", "oooooooof");
    QCBOREncode_AddSZStringToMapN(&ECtx, 99, "ffffoooooooof");
-   QCBOREncode_AddURIToMap(&ECtx, "RFC", UsefulBuf_FROM_SZ_LITERAL("https://tools.ietf.org/html/rfc7049#section-2.4.5"));
+   QCBOREncode_AddURIToMap(&ECtx,
+                           "RFC",
+                           UsefulBuf_FROM_SZ_LITERAL("https://tools.ietf.org/html/rfc7049#section-2.4.5"));
    QCBOREncode_AddURIToMapN(&ECtx, 0x89, UsefulBuf_FROM_SZ_LITERAL("http://cbor.me/"));
    QCBOREncode_AddB64TextToMap(&ECtx, "whenim64", UsefulBuf_FROM_SZ_LITERAL("cGxlYXN1cmUu"));
    QCBOREncode_AddB64TextToMapN(&ECtx, 64, UsefulBuf_FROM_SZ_LITERAL("c3VyZS4="));
@@ -608,7 +659,9 @@
    QCBOREncode_CloseMap(&ECtx);
 
    // UUIDs
-   static const uint8_t ppppUUID[] = {0x53, 0x4D, 0x41, 0x52, 0x54, 0x43, 0x53, 0x4C, 0x54, 0x54, 0x43, 0x46, 0x49, 0x43, 0x41, 0x32};
+   static const uint8_t ppppUUID[] = {0x53, 0x4D, 0x41, 0x52, 0x54, 0x43,
+                                      0x53, 0x4C, 0x54, 0x54, 0x43, 0x46,
+                                      0x49, 0x43, 0x41, 0x32};
    const UsefulBufC XXUUID = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(ppppUUID);
    QCBOREncode_AddBinaryUUID(&ECtx, XXUUID);
    QCBOREncode_OpenMap(&ECtx);
@@ -738,7 +791,7 @@
   to expected values generated from http://cbor.me.
 
  */
-int IntegerValuesTest1()
+int32_t IntegerValuesTest1()
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
@@ -823,7 +876,7 @@
 static const uint8_t spExpectedEncodedSimple[] = {
    0x85, 0xf5, 0xf4, 0xf6, 0xf7, 0xa1, 0x65, 0x55, 0x4e, 0x44, 0x65, 0x66, 0xf7};
 
-int SimpleValuesTest1()
+int32_t SimpleValuesTest1()
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
@@ -870,7 +923,7 @@
 static const uint8_t spExpectedEncodedSimpleIndefiniteLength[] = {
    0x9f, 0xf5, 0xf4, 0xf6, 0xf7, 0xbf, 0x65, 0x55, 0x4e, 0x44, 0x65, 0x66, 0xf7, 0xff, 0xff};
 
-int SimpleValuesIndefiniteLengthTest1()
+int32_t SimpleValuesIndefiniteLengthTest1()
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
@@ -1065,7 +1118,7 @@
    0x31
 };
 
-int EncodeLengthThirtyoneTest()
+int32_t EncodeLengthThirtyoneTest()
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
@@ -1076,18 +1129,18 @@
    // add array with 31 items
    QCBOREncode_OpenArrayInMap(&ECtx, "arr");
    for (size_t ix = 0; ix < 31; ix++) {
-      QCBOREncode_AddInt64(&ECtx, ix);
+      QCBOREncode_AddInt64(&ECtx, (int64_t)ix);
    }
    QCBOREncode_CloseArray(&ECtx);
 
    // add map with 31 items
    QCBOREncode_OpenMapInMap(&ECtx, "map");
-   for (size_t ix = 0; ix < 31; ix++) {
+   for (int ix = 0; ix < 31; ix++) {
       // make sure we have unique keys in the map (a-z then follow by A-Z)
-      char c = 'a';
+      int c = 'a';
       if (ix < 26) c = c + ix;
       else c = 'A' + (ix - 26);
-      char buffer[2] = { c, 0 };
+      char buffer[2] = { (char)c, 0 };
       QCBOREncode_AddInt64ToMap(&ECtx, buffer, ix);
    }
    QCBOREncode_CloseMap(&ECtx);
@@ -1145,7 +1198,7 @@
    0x32, 0x5a, 0x62, 0x53, 0x44, 0xc1, 0x19, 0x03, 0xe7
 };
 
-int EncodeDateTest()
+int32_t EncodeDateTest()
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
@@ -1182,7 +1235,7 @@
 }
 
 
-int ArrayNestingTest1()
+int32_t ArrayNestingTest1()
 {
    QCBOREncodeContext ECtx;
    int i;
@@ -1205,7 +1258,7 @@
 
 
 
-int ArrayNestingTest2()
+int32_t ArrayNestingTest2()
 {
    QCBOREncodeContext ECtx;
    int i;
@@ -1229,7 +1282,7 @@
 
 
 
-int ArrayNestingTest3()
+int32_t ArrayNestingTest3()
 {
    QCBOREncodeContext ECtx;
    int i;
@@ -1346,7 +1399,7 @@
    0xff, 0xff};
 
 
-int EncodeRawTest()
+int32_t EncodeRawTest()
 {
    QCBOREncodeContext ECtx;
 
@@ -1372,7 +1425,7 @@
 /*
  This returns a pointer to spBigBuf
  */
-static int CreateMap(uint8_t **pEncoded, size_t *pEncodedLen)
+static int32_t CreateMap(uint8_t **pEncoded, size_t *pEncodedLen)
 {
    QCBOREncodeContext ECtx;
    int nReturn = -1;
@@ -1469,7 +1522,7 @@
    0x73 } ;
 
 
-int MapEncodeTest()
+int32_t MapEncodeTest()
 {
    uint8_t *pEncodedMaps;
    size_t nEncodedMapLen;
@@ -1489,11 +1542,13 @@
 /*
  @brief  Encode the RTIC results
 
- @param[in]     nRResult        CBOR_SIMPLEV_TRUE, CBOR_SIMPLEV_FALSE or CBOR_SIMPLEV_NULL
- @param[in]     time            Time stamp in UNIX epoch time or 0 for no time stamp
+ @param[in]     nRResult        CBOR_SIMPLEV_TRUE, CBOR_SIMPLEV_FALSE or
+                                CBOR_SIMPLEV_NULL
+ @param[in]     time            Time stamp in UNIX epoch time or 0 for none
  @param[in]     szAlexString    Diagnostic code.
  @param[in[     pOut            Buffer to put the result in
- @param[in/out] pnLen           Size of pOut buffer when called; length of data output in buffer on return
+ @param[in/out] pnLen           Size of pOut buffer when called; length of data
+                                output in buffer on return
 
  @return
  One of the CBOR encoder errors. QCBOR_SUCCESS, which is has value 0, if no error.
@@ -1507,11 +1562,17 @@
 
  */
 
-static UsefulBufC FormatRTICResults(int nRResult, uint64_t time, const char *szType, const char *szAlexString, UsefulBuf Storage)
+static UsefulBufC
+FormatRTICResults(uint8_t uRResult,
+                  int64_t time,
+                  const char *szType,
+                  const char *szAlexString,
+                  UsefulBuf Storage)
 {
    // Buffer that the result will be written in to
    // It is fixed size and small that a stack variable will be fine
-   // QCBOREncode will never write off the end of this buffer. If it won't fit QCBOREncode_Finish will return an error.
+   // QCBOREncode will never write off the end of this buffer. If it won't
+   // fit QCBOREncode_Finish will return an error.
 
    // Context for the encoder
    QCBOREncodeContext ECtx;
@@ -1523,8 +1584,9 @@
 
    { // Brace / indention just to show CBOR encoding nesting
 
-      // The result: 0 if scan happened and found nothing; 1 if it happened and found something wrong; 2 if it didn't happen
-      QCBOREncode_AddSimpleToMap(&ECtx, "integrity", nRResult);
+      // The result: 0 if scan happened and found nothing; 1 if it happened and
+      // found something wrong; 2 if it didn't happen
+      QCBOREncode_AddSimpleToMap(&ECtx, "integrity", uRResult);
 
       // Add the diagnostic code
       QCBOREncode_AddSZStringToMap(&ECtx, "type", szType);
@@ -1616,7 +1678,7 @@
    0xaa, 0xbb, 0x01, 0x01};
 
 
-int RTICResultsTest()
+int32_t RTICResultsTest()
 {
    const UsefulBufC Encoded = FormatRTICResults(CBOR_SIMPLEV_FALSE, 1477263730,
                                           "recent", "0xA1eC5001",
@@ -1652,7 +1714,7 @@
 /*
  Very basic bstr wrapping test
  */
-int BstrWrapTest()
+int32_t BstrWrapTest()
 {
    QCBOREncodeContext EC;
 
@@ -1690,7 +1752,8 @@
    QCBOREncode_CloseArray(&EC);
    UsefulBufC BStr;
    QCBOREncode_CloseBstrWrap(&EC, &BStr);
-   // 3 is one byte for the wrapping bstr, 1 for an array of length 1, and 1 byte for a NULL
+   // 3 is one byte for the wrapping bstr, 1 for an array of length 1,
+   // and 1 byte for a NULL
    if(BStr.ptr != NULL || BStr.len != 3) {
       return -5;
    }
@@ -1714,9 +1777,9 @@
 
 
 
-int BstrWrapErrorTest()
+int32_t BstrWrapErrorTest()
 {
-   // -------------- Test closing a bstrwrap when it is an array that is open -----------
+   // ---- Test closing a bstrwrap when it is an array that is open ---------
    QCBOREncodeContext EC;
 
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
@@ -1738,7 +1801,7 @@
       return -1;
    }
 
-   // ----------- test closing a bstrwrap when nothing is open ---------------------
+   // -------- test closing a bstrwrap when nothing is open ----------------
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    QCBOREncode_CloseBstrWrap(&EC, &Wrapped);
    if(QCBOREncode_Finish(&EC, &Encoded2) != QCBOR_ERR_TOO_MANY_CLOSES) {
@@ -1879,7 +1942,7 @@
 }
 
 // Part of bstr_wrap_nest_test
-static int DecodeNextNested2(UsefulBufC Wrapped)
+static int32_t DecodeNextNested2(UsefulBufC Wrapped)
 {
    int nReturn;
    QCBORDecodeContext DC;
@@ -1945,7 +2008,7 @@
 }
 
 
-int BstrWrapNestTest()
+int32_t BstrWrapNestTest()
 {
    QCBOREncodeContext EC;
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
@@ -1957,24 +2020,24 @@
 
    for(int i = 0; i < BSTR_TEST_DEPTH-2; i++) {
       QCBOREncode_BstrWrap(&EC);
-      QCBOREncode_AddUInt64(&EC, i);
+      QCBOREncode_AddInt64(&EC, i);
    }
 
    for(int i = 0; i < BSTR_TEST_DEPTH-2; i++) {
       QCBOREncode_CloseBstrWrap(&EC, NULL);
-      QCBOREncode_AddUInt64(&EC, i);
+      QCBOREncode_AddInt64(&EC, i);
    }
 
    for(int i = 0; i < (BSTR_TEST_DEPTH-2)/3; i++) {
       QCBOREncode_OpenMap(&EC);
       QCBOREncode_BstrWrapInMapN(&EC, i+0x20);
       QCBOREncode_OpenArray(&EC);
-      QCBOREncode_AddUInt64(&EC, i+0x10);
+      QCBOREncode_AddInt64(&EC, i+0x10);
    }
 
    for(int i = 0; i < (BSTR_TEST_DEPTH-2)/3; i++) {
       QCBOREncode_CloseArray(&EC);
-      QCBOREncode_AddUInt64(&EC, i+0x30);
+      QCBOREncode_AddInt64(&EC, i+0x30);
       QCBOREncode_CloseBstrWrap(&EC, NULL);
       QCBOREncode_AddSZStringToMapN(&EC, i+0x40, "hello");
       QCBOREncode_CloseMap(&EC);
@@ -2101,7 +2164,7 @@
  be nice as it would make the test really good. That would require
  bring in ECDSA crypto to this test.
  */
-int CoseSign1TBSTest()
+int32_t CoseSign1TBSTest()
 {
    // All of this is from RFC 8152 C.2.1
    const char          *szKid     = "11";
@@ -2167,13 +2230,14 @@
 }
 
 
-int EncodeErrorTests()
+int32_t EncodeErrorTests()
 {
    QCBOREncodeContext EC;
 
 
    // ------ Test for QCBOR_ERR_BUFFER_TOO_LARGE ------
-   // Do all of these tests with NULL buffers so no actual large allocations are neccesary
+   // Do all of these tests with NULL buffers so no actual
+   // large allocations are neccesary
    const UsefulBuf Buffer = (UsefulBuf){NULL, UINT32_MAX};
 
    // First verify no error from a big buffer
@@ -2331,3 +2395,204 @@
 
    return 0;
 }
+
+
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+/*
+   [
+      4([-1, 3]),
+      4([-20, 4759477275222530853136]),
+      4([9223372036854775807, -4759477275222530853137]),
+      5([300, 100]),
+      5([-20, 4759477275222530853136]),
+      5([-9223372036854775808, -4759477275222530853137])
+ ]
+ */
+static const uint8_t spExpectedExponentAndMantissaArray[] = {
+   0x86, 0xC4, 0x82, 0x20, 0x03, 0xC4, 0x82, 0x33,
+   0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+   0x07, 0x08, 0x09, 0x10, 0xC4, 0x82, 0x1B, 0x7F,
+   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3,
+   0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+   0x08, 0x09, 0x10, 0xC5, 0x82, 0x19, 0x01, 0x2C,
+   0x18, 0x64, 0xC5, 0x82, 0x33, 0xC2, 0x4A, 0x01,
+   0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+   0x10, 0xC5, 0x82, 0x3B, 0x7F, 0xFF, 0xFF, 0xFF,
+   0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x4A, 0x01, 0x02,
+   0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10};
+
+
+/*
+  {
+    "decimal fraction": 4([-1, 3]),
+    300: 4([-1, 3]),
+    "decimal fraction bignum postive": 4([-200, 4759477275222530853136]),
+    400: 4([2147483647, 4759477275222530853136]),
+    "decimal fraction bignum negative": 4([9223372036854775807, -4759477275222530853137]),
+    500: 4([9223372036854775807, -4759477275222530853137]),
+    "big float": 5([300, 100]),
+    600: 5([300, 100]),
+    "big float bignum positive": 5([-20, 4759477275222530853136]),
+    700: 5([-20, 4759477275222530853136]),
+    "big float bignum negative": 5([-9223372036854775808, -4759477275222530853137]),
+    800: 5([-9223372036854775808, -4759477275222530853137])
+  }
+ */
+static const uint8_t spExpectedExponentAndMantissaMap[] = {
+   0xAC, 0x70, 0x64, 0x65, 0x63, 0x69, 0x6D, 0x61,
+   0x6C, 0x20, 0x66, 0x72, 0x61, 0x63, 0x74, 0x69,
+   0x6F, 0x6E, 0xC4, 0x82, 0x20, 0x03, 0x19, 0x01,
+   0x2C, 0xC4, 0x82, 0x20, 0x03, 0x78, 0x1F, 0x64,
+   0x65, 0x63, 0x69, 0x6D, 0x61, 0x6C, 0x20, 0x66,
+   0x72, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20,
+   0x62, 0x69, 0x67, 0x6E, 0x75, 0x6D, 0x20, 0x70,
+   0x6F, 0x73, 0x74, 0x69, 0x76, 0x65, 0xC4, 0x82,
+   0x38, 0xC7, 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04,
+   0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x19, 0x01,
+   0x90, 0xC4, 0x82, 0x1A, 0x7F, 0xFF, 0xFF, 0xFF,
+   0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+   0x07, 0x08, 0x09, 0x10, 0x78, 0x20, 0x64, 0x65,
+   0x63, 0x69, 0x6D, 0x61, 0x6C, 0x20, 0x66, 0x72,
+   0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x62,
+   0x69, 0x67, 0x6E, 0x75, 0x6D, 0x20, 0x6E, 0x65,
+   0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0xC4, 0x82,
+   0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+   0xFF, 0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05,
+   0x06, 0x07, 0x08, 0x09, 0x10, 0x19, 0x01, 0xF4,
+   0xC4, 0x82, 0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
+   0xFF, 0xFF, 0xFF, 0xC3, 0x4A, 0x01, 0x02, 0x03,
+   0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x69,
+   0x62, 0x69, 0x67, 0x20, 0x66, 0x6C, 0x6F, 0x61,
+   0x74, 0xC5, 0x82, 0x19, 0x01, 0x2C, 0x18, 0x64,
+   0x19, 0x02, 0x58, 0xC5, 0x82, 0x19, 0x01, 0x2C,
+   0x18, 0x64, 0x78, 0x19, 0x62, 0x69, 0x67, 0x20,
+   0x66, 0x6C, 0x6F, 0x61, 0x74, 0x20, 0x62, 0x69,
+   0x67, 0x6E, 0x75, 0x6D, 0x20, 0x70, 0x6F, 0x73,
+   0x69, 0x74, 0x69, 0x76, 0x65, 0xC5, 0x82, 0x33,
+   0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+   0x07, 0x08, 0x09, 0x10, 0x19, 0x02, 0xBC, 0xC5,
+   0x82, 0x33, 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04,
+   0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x78, 0x19,
+   0x62, 0x69, 0x67, 0x20, 0x66, 0x6C, 0x6F, 0x61,
+   0x74, 0x20, 0x62, 0x69, 0x67, 0x6E, 0x75, 0x6D,
+   0x20, 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76,
+   0x65, 0xC5, 0x82, 0x3B, 0x7F, 0xFF, 0xFF, 0xFF,
+   0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x4A, 0x01, 0x02,
+   0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+   0x19, 0x03, 0x20, 0xC5, 0x82, 0x3B, 0x7F, 0xFF,
+   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x4A,
+   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+   0x09, 0x10
+};
+
+
+int32_t ExponentAndMantissaEncodeTests()
+{
+   QCBOREncodeContext EC;
+   UsefulBufC         EncodedExponentAndMantissa;
+
+   // Constant for the big number used in all the tests.
+   static const uint8_t spBigNum[] = {0x01, 0x02, 0x03, 0x04, 0x05,
+                                      0x06, 0x07, 0x08, 0x09, 0x010};
+   const UsefulBufC   BigNum = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum);
+
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenArray(&EC);
+   QCBOREncode_AddDecimalFraction(&EC, 3, -1); // 3 * (10 ^ -1)
+   QCBOREncode_AddDecimalFractionBigNum(&EC, BigNum , false, -20);
+   QCBOREncode_AddDecimalFractionBigNum(&EC, BigNum, true, INT64_MAX);
+   QCBOREncode_AddBigFloat(&EC, 100, 300);
+   QCBOREncode_AddBigFloatBigNum(&EC, BigNum, false, -20);
+   QCBOREncode_AddBigFloatBigNum(&EC, BigNum, true, INT64_MIN);
+   QCBOREncode_CloseArray(&EC);
+
+   if(QCBOREncode_Finish(&EC, &EncodedExponentAndMantissa)) {
+      return -2;
+   }
+
+   int nReturn = UsefulBuf_CompareWithDiagnostic(EncodedExponentAndMantissa,
+                                                 UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedExponentAndMantissaArray),
+                                                 NULL);
+   if(nReturn) {
+      return nReturn;
+   }
+
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenMap(&EC);
+
+   QCBOREncode_AddDecimalFractionToMap(&EC, "decimal fraction", 3, -1);
+
+   QCBOREncode_AddDecimalFractionToMapN(&EC, 300, 3, -1);
+
+   QCBOREncode_AddDecimalFractionBigNumToMap(&EC,
+                                             "decimal fraction bignum postive",
+                                             BigNum,
+                                             false,
+                                             -200);
+
+   QCBOREncode_AddDecimalFractionBigNumToMapN(&EC,
+                                              400,
+                                              BigNum,
+                                              false,
+                                              INT32_MAX);
+
+   QCBOREncode_AddDecimalFractionBigNumToMap(&EC,
+                                             "decimal fraction bignum negative",
+                                             BigNum,
+                                             true,
+                                             INT64_MAX);
+
+   QCBOREncode_AddDecimalFractionBigNumToMapN(&EC,
+                                              500,
+                                              BigNum,
+                                              true,
+                                              INT64_MAX);
+
+   QCBOREncode_AddBigFloatToMap(&EC, "big float", 100, 300);
+
+   QCBOREncode_AddBigFloatToMapN(&EC, 600, 100, 300);
+
+   QCBOREncode_AddBigFloatBigNumToMap(&EC,
+                                      "big float bignum positive",
+                                      BigNum,
+                                      false,
+                                      -20);
+
+   QCBOREncode_AddBigFloatBigNumToMapN(&EC,
+                                       700,
+                                       BigNum,
+                                       false,
+                                       -20);
+
+   QCBOREncode_AddBigFloatBigNumToMap(&EC,
+                                      "big float bignum negative",
+                                      BigNum,
+                                      true,
+                                      INT64_MIN);
+
+   QCBOREncode_AddBigFloatBigNumToMapN(&EC,
+                                       800,
+                                       BigNum,
+                                       true,
+                                       INT64_MIN);
+
+   QCBOREncode_CloseMap(&EC);
+
+   if(QCBOREncode_Finish(&EC, &EncodedExponentAndMantissa)) {
+      return -3;
+   }
+
+
+   struct UBCompareDiagnostic Diag;
+
+   nReturn = UsefulBuf_CompareWithDiagnostic(EncodedExponentAndMantissa,
+                                             UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedExponentAndMantissaMap),
+                                             &Diag);
+   if(nReturn) {
+      return nReturn + 1000000; // +1000000 to distinguish from first test above
+   }
+
+   return 0;
+}
+
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
diff --git a/lib/ext/qcbor/test/qcbor_encode_tests.h b/lib/ext/qcbor/test/qcbor_encode_tests.h
index 7909288..d768889 100644
--- a/lib/ext/qcbor/test/qcbor_encode_tests.h
+++ b/lib/ext/qcbor/test/qcbor_encode_tests.h
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2019, Laurence Lundblade.
+ Copyright (c) 2018-2020, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -28,16 +28,18 @@
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ==============================================================================*/
+ =============================================================================*/
 
 #ifndef __QCBOR__qcbor_encode_tests__
 #define __QCBOR__qcbor_encode_tests__
 
+#include <stdint.h>
 
 /*
  Notes:
 
- - All the functions in qcbor.h are called once in the aggregation of all the tests below.
+ - All the functions in qcbor.h are called once in the aggregation of all
+   the tests below.
 
  - All the types that are supported are given as input and parsed by these tests
 
@@ -50,122 +52,133 @@
 /*
  Most basic test.
  */
-int BasicEncodeTest(void);
+int32_t BasicEncodeTest(void);
 
 
 /*
- Encode lots of integer values, particularly around the boundary and make sure they
- Match the expected binary output. Primarily an encoding test.
+ Encode lots of integer values, particularly around the boundary and
+ make sure they Match the expected binary output. Primarily an
+ encoding test.
  */
-int IntegerValuesTest1(void);
+int32_t IntegerValuesTest1(void);
 
 
 /*
- Create nested arrays to the max depth allowed and make sure it succeeds.
- This is an encoding test.
+ Create nested arrays to the max depth allowed and make sure it
+ succeeds.  This is an encoding test.
  */
-int ArrayNestingTest1(void);
+int32_t ArrayNestingTest1(void);
 
 
 /*
- Create nested arrays to one more than the meax depth and make sure it fails.
- This is an encoding test.
+ Create nested arrays to one more than the meax depth and make sure it
+ fails.  This is an encoding test.
  */
-int ArrayNestingTest2(void);
+int32_t ArrayNestingTest2(void);
 
 
 /*
- Encoding test.
- Create arrays to max depth and close one extra time and look for correct error code
+ Encoding test.  Create arrays to max depth and close one extra time
+ and look for correct error code
  */
-int ArrayNestingTest3(void);
+int32_t ArrayNestingTest3(void);
 
 
 /*
- This tests the QCBOREncode_AddRaw() function by adding two chunks or RAWCBOR to an
- array and comparing with expected values. This is an encoding test.
+ This tests the QCBOREncode_AddRaw() function by adding two chunks or
+ RAWCBOR to an array and comparing with expected values. This is an
+ encoding test.
  */
-int EncodeRawTest(void);
+int32_t EncodeRawTest(void);
 
 
 /*
- This creates a somewhat complicated CBOR MAP and verifies it against expected
- data. This is an encoding test.
+ This creates a somewhat complicated CBOR MAP and verifies it against
+ expected data. This is an encoding test.
  */
-int MapEncodeTest(void);
+int32_t MapEncodeTest(void);
 
 
 /*
  Encodes a goodly number of floats and doubles and checks encoding is right
  */
-int FloatValuesTest1(void);
+int32_t FloatValuesTest1(void);
 
 
 /*
  Encodes true, false and the like
  */
-int SimpleValuesTest1(void);
+int32_t SimpleValuesTest1(void);
 
 
 /*
  Encodes basic maps and arrays with indefinite length
  */
-int SimpleValuesIndefiniteLengthTest1(void);
+int32_t SimpleValuesIndefiniteLengthTest1(void);
+
 
 /*
- Indefinite length arrays and maps use the 'magic' number 31, verify that
- everything with length 31 still works properly
+ Indefinite length arrays and maps use the 'magic' number 31, verify
+ that everything with length 31 still works properly
  */
-int EncodeLengthThirtyoneTest(void);
+int32_t EncodeLengthThirtyoneTest(void);
 
 
 /*
  Encodes most data formats that are supported */
-int EncodeDateTest(void);
+int32_t EncodeDateTest(void);
 
 
 /*
  Encodes particular data structure that a particular app will need...
  */
-int RTICResultsTest(void);
+int32_t RTICResultsTest(void);
 
 
 /*
  Calls all public encode methods in qcbor.h once.
  */
-int AllAddMethodsTest(void);
+int32_t AllAddMethodsTest(void);
 
 /*
  The binary string wrapping of maps and arrays used by COSE
  */
-int  BstrWrapTest(void);
+int32_t  BstrWrapTest(void);
 
 
 /*
  Test error cases for bstr wrapping encoding such as closing an open
  array with CloseBstrWrap
  */
-int BstrWrapErrorTest(void);
+int32_t BstrWrapErrorTest(void);
 
 
 /*
  Test complicated nested bstr wrapping
  */
-int BstrWrapNestTest(void);
+int32_t BstrWrapNestTest(void);
 
 
 /*
  Test encoding a COSE_Sign1 with bstr wrapping
  */
-int CoseSign1TBSTest(void);
+int32_t CoseSign1TBSTest(void);
 
 
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+/*
+ Test encoding of decimal fractions and big floats, both of which are
+ made up of an exponent and mantissa
+ */
+int32_t ExponentAndMantissaEncodeTests(void);
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
+
 /*
  Test the error cases when encoding CBOR such as buffer too large,
  buffer too small, array nesting too deep. Aims to cover the error
  codes returned when encoding CBOR
  */
-int EncodeErrorTests(void);
+int32_t EncodeErrorTests(void);
 
 
 #endif /* defined(__QCBOR__qcbor_encode_tests__) */
diff --git a/lib/ext/qcbor/test/run_tests.c b/lib/ext/qcbor/test/run_tests.c
index 52c4f8f..f8ed83b 100644
--- a/lib/ext/qcbor/test/run_tests.c
+++ b/lib/ext/qcbor/test/run_tests.c
@@ -1,14 +1,14 @@
 /*==============================================================================
  run_tests.c -- test aggregator and results reporting
 
- Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
 
  SPDX-License-Identifier: BSD-3-Clause
 
  See BSD-3-Clause license in README.md
 
  Created on 9/30/18
- ==============================================================================*/
+ =============================================================================*/
 
 #include "run_tests.h"
 #include "UsefulBuf.h"
@@ -24,7 +24,7 @@
  Test configuration
  */
 
-typedef int (test_fun_t)(void);
+typedef int32_t (test_fun_t)(void);
 typedef const char * (test_fun2_t)(void);
 
 
@@ -103,6 +103,12 @@
     TEST_ENTRY(SetUpAllocatorTest),
     TEST_ENTRY(SimpleValuesIndefiniteLengthTest1),
     TEST_ENTRY(EncodeLengthThirtyoneTest),
+#ifndef     QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+    TEST_ENTRY(EncodeLengthThirtyoneTest),
+    TEST_ENTRY(ExponentAndMantissaDecodeTests),
+    TEST_ENTRY(ExponentAndMantissaDecodeFailTests),
+    TEST_ENTRY(ExponentAndMantissaEncodeTests),
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 };
 
 
@@ -131,12 +137,12 @@
    }
 
    bool bDidSomeOutput = false;
-   for(int n = nMax; n > 0; n/=10) {
-      int x = nNum/n;
-      if(x || bDidSomeOutput){
+   for(int32_t n = nMax; n > 0; n/=10) {
+      int nDigitValue = nNum/n;
+      if(nDigitValue || bDidSomeOutput){
          bDidSomeOutput = true;
-         UsefulOutBuf_AppendByte(&OutBuf, '0' + x);
-         nNum -= x * n;
+         UsefulOutBuf_AppendByte(&OutBuf, (uint8_t)('0' + nDigitValue));
+         nNum -= nDigitValue * n;
       }
    }
    if(!bDidSomeOutput){
@@ -151,10 +157,14 @@
 /*
  Public function. See run_test.h.
  */
-int RunTests(const char *szTestNames[], OutputStringCB pfOutput, void *poutCtx, int *pNumTestsRun)
+int RunTestsQCBOR(const char *szTestNames[],
+             OutputStringCB pfOutput,
+             void *poutCtx,
+             int *pNumTestsRun)
 {
     int nTestsFailed = 0;
     int nTestsRun = 0;
+
     UsefulBuf_MAKE_STACK_UB(StringStorage, 12);
 
     test_entry2 *t2;
@@ -228,7 +238,7 @@
             }
         }
 
-        int nTestResult = (t->test_fun)();
+        int32_t nTestResult = (t->test_fun)();
         nTestsRun++;
         if(pfOutput) {
             (*pfOutput)(t->szTestName, poutCtx, 0);
@@ -269,13 +279,16 @@
 /*
  Public function. See run_test.h.
  */
-static void PrintSize(const char *szWhat, uint32_t uSize, OutputStringCB pfOutput, void *pOutCtx)
+static void PrintSize(const char *szWhat,
+                      uint32_t uSize,
+                      OutputStringCB pfOutput,
+                      void *pOutCtx)
 {
    UsefulBuf_MAKE_STACK_UB(buffer, 20);
 
    (*pfOutput)(szWhat, pOutCtx, 0);
    (*pfOutput)(" ", pOutCtx, 0);
-   (*pfOutput)(NumToString(uSize, buffer), pOutCtx, 0);
+   (*pfOutput)(NumToString((int32_t)uSize, buffer), pOutCtx, 0);
    (*pfOutput)("", pOutCtx, 1);
 }
 
@@ -283,15 +296,15 @@
 /*
  Public function. See run_test.h.
  */
-void PrintSizes(OutputStringCB pfOutput, void *pOutCtx)
+void PrintSizesQCBOR(OutputStringCB pfOutput, void *pOutCtx)
 {
-   // Type and size of return from sizeof() varies. These will never be large so cast is safe
-   PrintSize("sizeof(QCBORTrackNesting)",   (uint32_t)sizeof(QCBORTrackNesting), pfOutput, pOutCtx);
+   // These will never be large so cast is safe
+   PrintSize("sizeof(QCBORTrackNesting)",   (uint32_t)sizeof(QCBORTrackNesting),  pfOutput, pOutCtx);
    PrintSize("sizeof(QCBOREncodeContext)",  (uint32_t)sizeof(QCBOREncodeContext), pfOutput, pOutCtx);
    PrintSize("sizeof(QCBORDecodeNesting)",  (uint32_t)sizeof(QCBORDecodeNesting), pfOutput, pOutCtx);
    PrintSize("sizeof(QCBORDecodeContext)",  (uint32_t)sizeof(QCBORDecodeContext), pfOutput, pOutCtx);
-   PrintSize("sizeof(QCBORItem)",           (uint32_t)sizeof(QCBORItem), pfOutput, pOutCtx);
-   PrintSize("sizeof(QCBORTagListIn)",      (uint32_t)sizeof(QCBORTagListIn), pfOutput, pOutCtx);
-   PrintSize("sizeof(QCBORTagListOut)",     (uint32_t)sizeof(QCBORTagListOut), pfOutput, pOutCtx);
+   PrintSize("sizeof(QCBORItem)",           (uint32_t)sizeof(QCBORItem),          pfOutput, pOutCtx);
+   PrintSize("sizeof(QCBORTagListIn)",      (uint32_t)sizeof(QCBORTagListIn),     pfOutput, pOutCtx);
+   PrintSize("sizeof(QCBORTagListOut)",     (uint32_t)sizeof(QCBORTagListOut),    pfOutput, pOutCtx);
    (*pfOutput)("", pOutCtx, 1);
 }
diff --git a/lib/ext/qcbor/test/run_tests.h b/lib/ext/qcbor/test/run_tests.h
index 734d4f8..ce44673 100644
--- a/lib/ext/qcbor/test/run_tests.h
+++ b/lib/ext/qcbor/test/run_tests.h
@@ -1,14 +1,14 @@
 /*==============================================================================
  run_tests.h -- test aggregator and results reporting
 
- Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
 
  SPDX-License-Identifier: BSD-3-Clause
 
  See BSD-3-Clause license in README.md
 
  Created 9/30/18
- ==============================================================================*/
+ =============================================================================*/
 
 /**
  @file run_tests.h
@@ -53,7 +53,10 @@
 
  @return The number of tests that failed. Zero means overall success.
  */
-int RunTests(const char *szTestNames[], OutputStringCB pfOutput, void *pOutCtx, int *pNumTestsRun);
+int RunTestsQCBOR(const char *szTestNames[],
+                  OutputStringCB pfOutput,
+                  void *pOutCtx,
+                  int *pNumTestsRun);
 
 
 /**
@@ -62,5 +65,5 @@
  @param[in] pfOutput     Function that is called to output text strings.
  @param[in] pOutCtx      Context pointer passed to output function.
  */
-void PrintSizes(OutputStringCB pfOutput, void *pOutCtx);
+void PrintSizesQCBOR(OutputStringCB pfOutput, void *pOutCtx);