test indefinite length strings with map searching
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 6943cf5..13a0608 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -121,7 +121,6 @@
they are on the item being sought, in which case the
unrecoverable error will be returned. Unrecoverable
errors are those indicated by QCBORDecode_IsUnrecoverableError().
-
@anchor Tag-Usage
@@ -167,6 +166,12 @@
accept", however these days that is less in favor. See
https://tools.ietf.org/id/draft-thomson-postel-was-wrong-03.html.
+ Map searching works with indefinite length strings. A string allocator must
+ be set up the same as for any handling of indefinite length strings.
+ However, It currently over-allocates memory from the string pool
+ and thus requires a much larger string pool than it should. The
+ over-allocation happens every time a map is searched by label.
+ (This may be corrected in the future).
*/
@@ -521,6 +526,90 @@
double *pdValue);
+/**
+ @brief Decode next item into a double floating-point value with basic conversion.
+
+ @param[in] pCtx The decode context.
+ @param[in] uConvertTypes The integer conversion options.
+ @param[out] pdValue The returned floating-point value.
+
+ This will decode CBOR integer and floating-point numbers, returning
+ them as a double floating-point number. This function supports @ref
+ QCBOR_CONVERT_TYPE_XINT64 and @ref QCBOR_CONVERT_TYPE_FLOAT
+ conversions. If the encoded CBOR is not one of the requested types or a type
+ not supported by this function, @ref QCBOR_ERR_UNEXPECTED_TYPE is
+ set.
+
+ See @ref Decode-Errors for discussion on how error handling works.
+
+ If floating-point HW use is disabled this will set
+ @ref QCBOR_ERR_HW_FLOAT_DISABLED if a single-precision
+ number is encountered. If half-precision support is disabled,
+ this will set QCBOR_ERR_HALF_PRECISION_DISABLED if
+ a half-precision number is encountered.
+
+ Positive and negative integers can always be converted to
+ floating-point, so this will never error on CBOR major type 0 or 1.
+
+ Note that a large 64-bit integer can have more precision (64 bits)
+ than even a double floating-point (52 bits) value, so there is loss
+ of precision in some conversions.
+
+ See also QCBORDecode_GetDouble() and QCBORDecode_GetDoubleConvertAll().
+*/
+static void QCBORDecode_GetDoubleConvert(QCBORDecodeContext *pCtx,
+ uint32_t uConvertTypes,
+ double *pdValue);
+
+static void QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pCtx,
+ int64_t nLabel,
+ uint32_t uConvertTypes,
+ double *pdValue);
+
+static void QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pCtx,
+ const char *szLabel,
+ uint32_t uConvertTypes,
+ double *pdValue);
+
+
+/**
+ @brief Decode next item as a double floating-point value with conversion.
+
+ @param[in] pCtx The decode context.
+ @param[in] uConvertTypes The integer conversion options.
+ @param[out] pdValue The returned floating-point value.
+
+ This is the same as QCBORDecode_GetDoubleConvert() but supports many
+ more conversions at the cost of linking in more object code. The
+ conversion types supported are @ref QCBOR_CONVERT_TYPE_XINT64, @ref
+ QCBOR_CONVERT_TYPE_FLOAT, @ref QCBOR_CONVERT_TYPE_BIG_NUM, @ref
+ QCBOR_CONVERT_TYPE_DECIMAL_FRACTION and @ref
+ QCBOR_CONVERT_TYPE_BIGFLOAT.
+
+ Big numbers, decimal fractions and big floats that are too small or
+ too large to be reprented as a double floating-point number will be
+ returned as plus or minus zero or infinity rather than setting an
+ under or overflow error.
+
+ There is often loss of precision in the conversion.
+
+ See also QCBORDecode_GetDoubleConvert() and QCBORDecode_GetDoubleConvert().
+*/
+void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pCtx,
+ uint32_t uConvertTypes,
+ double *pdValue);
+
+void QCBORDecode_GetDoubleConvertAllInMapN(QCBORDecodeContext *pCtx,
+ int64_t nLabel,
+ uint32_t uConvertTypes,
+ double *pdValue);
+
+void QCBORDecode_GetDoubleConvertAllInMapSZ(QCBORDecodeContext *pCtx,
+ const char *szLabel,
+ uint32_t uConvertTypes,
+ double *pdValue);
+
+
/**
@@ -824,90 +913,6 @@
-/**
- @brief Decode next item into a double floating-point value with basic conversion.
-
- @param[in] pCtx The decode context.
- @param[in] uConvertTypes The integer conversion options.
- @param[out] pdValue The returned floating-point value.
-
- This will decode CBOR integer and floating-point numbers, returning
- them as a double floating-point number. This function supports @ref
- QCBOR_CONVERT_TYPE_XINT64 and @ref QCBOR_CONVERT_TYPE_FLOAT
- conversions. If the encoded CBOR is not one of the requested types or a type
- not supported by this function, @ref QCBOR_ERR_UNEXPECTED_TYPE is
- set.
-
- See @ref Decode-Errors for discussion on how error handling works.
-
- If floating-point HW use is disabled this will set
- @ref QCBOR_ERR_HW_FLOAT_DISABLED if a single-precision
- number is encountered. If half-precision support is disabled,
- this will set QCBOR_ERR_HALF_PRECISION_DISABLED if
- a half-precision number is encountered.
-
- Positive and negative integers can always be converted to
- floating-point, so this will never error on CBOR major type 0 or 1.
-
- Note that a large 64-bit integer can have more precision (64 bits)
- than even a double floating-point (52 bits) value, so there is loss
- of precision in some conversions.
-
- See also QCBORDecode_GetDouble() and QCBORDecode_GetDoubleConvertAll().
-*/
-static void QCBORDecode_GetDoubleConvert(QCBORDecodeContext *pCtx,
- uint32_t uConvertTypes,
- double *pdValue);
-
-static void QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pCtx,
- int64_t nLabel,
- uint32_t uConvertTypes,
- double *pdValue);
-
-static void QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pCtx,
- const char *szLabel,
- uint32_t uConvertTypes,
- double *pdValue);
-
-
-/**
- @brief Decode next item as a double floating-point value with conversion.
-
- @param[in] pCtx The decode context.
- @param[in] uConvertTypes The integer conversion options.
- @param[out] pdValue The returned floating-point value.
-
- This is the same as QCBORDecode_GetDoubleConvert() but supports many
- more conversions at the cost of linking in more object code. The
- conversion types supported are @ref QCBOR_CONVERT_TYPE_XINT64, @ref
- QCBOR_CONVERT_TYPE_FLOAT, @ref QCBOR_CONVERT_TYPE_BIG_NUM, @ref
- QCBOR_CONVERT_TYPE_DECIMAL_FRACTION and @ref
- QCBOR_CONVERT_TYPE_BIGFLOAT.
-
- Big numbers, decimal fractions and big floats that are too small or
- too large to be reprented as a double floating-point number will be
- returned as plus or minus zero or infinity rather than setting an
- under or overflow error.
-
- There is often loss of precision in the conversion.
-
- See also QCBORDecode_GetDoubleConvert() and QCBORDecode_GetDoubleConvert().
-*/
-void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pCtx,
- uint32_t uConvertTypes,
- double *pdValue);
-
-void QCBORDecode_GetDoubleConvertAllInMapN(QCBORDecodeContext *pCtx,
- int64_t nLabel,
- uint32_t uConvertTypes,
- double *pdValue);
-
-void QCBORDecode_GetDoubleConvertAllInMapSZ(QCBORDecodeContext *pCtx,
- const char *szLabel,
- uint32_t uConvertTypes,
- double *pdValue);
-
-
/**
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index f536f90..f084c8d 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2559,8 +2559,6 @@
If an item was not found, its data type is set to QCBOR_TYPE_NONE.
*/
-// TODO: make this handle indefinite length strings, possibly with
-// allocation only when returning the string.
static QCBORError
MapSearch(QCBORDecodeContext *pMe,
QCBORItem *pItemArray,
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 17b9c0f..205eada 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -6447,3 +6447,69 @@
return 0;
}
+
+
+static const uint8_t spMapWithIndefLenStrings[] = {
+ 0xbf,
+ 0x7f, 0x61, 'l', 0x64, 'a', 'b', 'e', 'l' , 0x61, '1', 0xff,
+ 0x5f, 0x42, 0x01, 0x02, 0x43, 0x03, 0x04, 0x05, 0xff,
+ 0x7f, 0x62, 'd', 'y', 0x61, 'm', 0x61, 'o', 0xff,
+ 0x03,
+ 0x7f, 0x62, 'l', 'a', 0x63, 'b', 'e', 'l', 0x61, '2', 0xff,
+ 0xc3,
+ 0x5f, 0x42, 0x00, 0x01, 0x42, 0x00, 0x01, 0x41, 0x01, 0xff,
+ 0xff
+};
+
+int32_t SpiffyIndefiniteLengthStringsTests()
+{
+ QCBORDecodeContext DCtx;
+
+ QCBORDecode_Init(&DCtx,
+ UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spMapWithIndefLenStrings),
+ QCBOR_DECODE_MODE_NORMAL);
+
+ MakeUsefulBufOnStack(StringBuf, 200);
+ QCBORDecode_SetMemPool(&DCtx, StringBuf, false);
+
+ UsefulBufC ByteString;
+ QCBORDecode_EnterMap(&DCtx);
+ QCBORDecode_GetByteStringInMapSZ(&DCtx, "label1", &ByteString);
+ if(QCBORDecode_GetAndResetError(&DCtx)) {
+ return 1;
+ }
+
+ const uint8_t pExectedBytes[] = {0x01, 0x02, 0x03, 0x04, 0x05};
+ if(UsefulBuf_Compare(ByteString, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExectedBytes))) {
+ return 2;
+ }
+
+ uint64_t uInt;
+ QCBORDecode_GetUInt64InMapSZ(&DCtx, "dymo", &uInt);
+ if(QCBORDecode_GetAndResetError(&DCtx)) {
+ return 3;
+ }
+ if(uInt != 3) {
+ return 4;
+ }
+
+ double uDouble;
+ QCBORDecode_GetDoubleConvertAllInMapSZ(&DCtx,
+ "label2",
+ 0xff,
+ &uDouble);
+ if(QCBORDecode_GetAndResetError(&DCtx)) {
+ return 5;
+ }
+ if(uDouble != -16777474) {
+ return 6;
+ }
+
+ QCBORDecode_ExitMap(&DCtx);
+
+ if(QCBORDecode_Finish(&DCtx)) {
+ return 99;
+ }
+
+ return 0;
+}
diff --git a/test/qcbor_decode_tests.h b/test/qcbor_decode_tests.h
index 1c01ee4..3cbb82d 100644
--- a/test/qcbor_decode_tests.h
+++ b/test/qcbor_decode_tests.h
@@ -291,4 +291,11 @@
*/
int32_t TooLargeInputTest(void);
+
+/*
+ Test spiffy decoding of indefinite length strings.
+ */
+int32_t SpiffyIndefiniteLengthStringsTests(void);
+
+
#endif /* defined(__QCBOR__qcbort_decode_tests__) */
diff --git a/test/run_tests.c b/test/run_tests.c
index 926ce47..0609736 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -121,6 +121,7 @@
TEST_ENTRY(ExponentAndMantissaDecodeTests),
TEST_ENTRY(ExponentAndMantissaDecodeFailTests),
TEST_ENTRY(ExponentAndMantissaEncodeTests),
+ TEST_ENTRY(SpiffyIndefiniteLengthStringsTests),
#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
};