Add support for decimal fractions and big floats (#19)

In addition: some rearrangement of how tagged items are decoded in anticipation of support for more tagged items with structure.
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index 7866b37..ab4fd7a 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -90,6 +90,37 @@
 #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;
+         }
+         return (int32_t)i + 1000000; // Cast to int is OK as this is only a diagnostic and the sizes here are never over a few KB.
+      }
+   }
+   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
@@ -2331,3 +2362,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
+};
+
+
+int 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 */