lots of work on integer conversion
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index ca69756..12533e8 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -1088,6 +1088,11 @@
*/
static void QCBORDecode_GetUInt64(QCBORDecodeContext *pCtx, uint64_t *puValue);
+
+static void QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pCtx, int64_t nLabel, uint64_t *puValue);
+
+static void QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, uint64_t *puValue);
+
/**
@brief Decode next item as an unsigned 64-bit integer with basic conversions.
@@ -1102,6 +1107,10 @@
*/
static void QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pCtx, uint32_t uOptions, uint64_t *puValue);
+static void QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext *pCtx, int64_t nLabel, uint32_t uOptions, uint64_t *puValue);
+
+static void QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, uint32_t uOptions, uint64_t *puValue);
+
/**
@brief Decode next item as an unsigned 64-bit integer with conversions
@@ -1116,6 +1125,10 @@
*/
void QCBORDecode_GetUInt64ConvertAll(QCBORDecodeContext *pCtx, uint32_t uOptions, uint64_t *puValue);
+void QCBORDecode_GetUInt64ConvertAllInMapN(QCBORDecodeContext *pCtx, int64_t nLabel, uint32_t uOptions, uint64_t *puValue);
+
+void QCBORDecode_GetUInt64ConvertAllInMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, uint32_t uOptions, uint64_t *puValue);
+
/**
@brief Decode next item as a floating-point value.
@@ -1133,6 +1146,9 @@
*/
static void QCBORDecode_GetDouble(QCBORDecodeContext *pCtx, uint32_t uOptions, double *pValue);
+static void QCBORDecode_GetDoubleInMapN(QCBORDecodeContext *pCtx, int64_t nLabel, double *pdValue);
+
+static void QCBORDecode_GetDoubleInMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, double *pdValue);
/**
@brief Decode next item as a floating-point value with basic conversion.
@@ -1156,6 +1172,10 @@
*/
static void QCBORDecode_GetDoubleConvert(QCBORDecodeContext *pCtx, uint32_t uOptions, double *pValue);
+static void QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pCtx, int64_t nLabel, uint32_t uOptions, double *pdValue);
+
+static void QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, uint32_t uOptions, double *pdValue);
+
/**
@brief Decode next item as a floating-point value with conversion.
@@ -1177,6 +1197,10 @@
*/
void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pCtx, uint32_t uOptions, double *pValue);
+void QCBORDecode_GetDoubleConvertAllInMapN(QCBORDecodeContext *pCtx, int64_t nLabel, uint32_t uOptions, double *puValue);
+
+void QCBORDecode_GetDoubleConvertAllInMapSZ(QCBORDecodeContext *pCtx, const char *szLabel, uint32_t uOptions, double *puValue);
+
static void QCBORDecode_GetBytes(QCBORDecodeContext *pCtx, UsefulBufC *pBytes);
@@ -1260,36 +1284,15 @@
will return the item after the map. */
static void QCBORDecode_EnterMap(QCBORDecodeContext *pCtx);
-
-/*
- Find a map in a map by integer label and enter it.
-
- This will do duplicate detection on the particular label.
-
- Call QCBORDecode_ExitMap() to return to the mode / level
- from before this was called.
-
- Seek to to the beginning of the map.
- Consume items looking for nLabel
- */
void QCBORDecode_EnterMapInMapN(QCBORDecodeContext *pCtx, int64_t nLabel);
void QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pCtx, const char *szLabel);
static void QCBORDecode_ExitMap(QCBORDecodeContext *pCtx);
-/*
- Indicate if decoding is in map mode more not.
- */
-bool QCBORDecode_InMapMode(QCBORDecodeContext *pCtxt);
-/*
- Restarts fetching of items in a map to the start of the
- map. This is for GetNext. It has no effect on
- GetByLabel (which always searches from the start).
- */
-void QCBORDecode_RewindMap(QCBORDecodeContext *pCtxt);
+
static void QCBORDecode_EnterArray(QCBORDecodeContext *pCtx);
@@ -1302,7 +1305,18 @@
-
+/*
+ Restarts fetching of items in a map to the start of the
+ map. This is for GetNext. It has no effect on
+ GetByLabel (which always searches from the start).
+ */
+void QCBORDecode_RewindMap(QCBORDecodeContext *pCtxt);
+
+/*
+ Indicate if decoding is in map mode more not.
+ */
+bool QCBORDecode_InMapMode(QCBORDecodeContext *pCtxt);
+
/*
@@ -1614,19 +1628,52 @@
// Semi-private
void QCBORDecode_GetUInt64ConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *puValue, QCBORItem *pItem);
+void QCBORDecode_GetUInt64ConvertInternalInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, uint64_t *puValue, QCBORItem *pItem);
+
+void QCBORDecode_GetUInt64ConvertInternalInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, uint64_t *puValue, QCBORItem *pItem);
+
+
+
void QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *puValue)
{
QCBORItem Item;
QCBORDecode_GetUInt64ConvertInternal(pMe, uOptions, puValue, &Item);
}
+inline static void QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, uint64_t *puValue)
+{
+ QCBORItem Item;
+ QCBORDecode_GetUInt64ConvertInternalInMapN(pMe, nLabel, uOptions, puValue, &Item);
+}
+
+inline static void QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, uint64_t *puValue)
+{
+ QCBORItem Item;
+ QCBORDecode_GetUInt64ConvertInternalInMapSZ(pMe, szLabel, uOptions, puValue, &Item);
+}
+
static inline void QCBORDecode_GetUInt64(QCBORDecodeContext *pMe, uint64_t *puValue)
{
QCBORDecode_GetUInt64Convert(pMe, QCBOR_CONVERT_TYPE_UINT64, puValue);
}
+
+inline static void QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint64_t *puValue)
+{
+ QCBORDecode_GetUInt64ConvertInMapN(pMe, nLabel, QCBOR_CONVERT_TYPE_UINT64, puValue);
+}
+
+inline static void QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint64_t *puValue)
+{
+ QCBORDecode_GetUInt64ConvertInMapSZ(pMe, szLabel, QCBOR_CONVERT_TYPE_UINT64, puValue);
+}
+
void QCBORDecode_GetDoubleConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue, QCBORItem *pItem);
+void QCBORDecode_GetDoubleConvertInternalInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, double *pdValue, QCBORItem *pItem);
+
+void QCBORDecode_GetDoubleConvertInternalInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, double *pdValue, QCBORItem *pItem);
+
inline static void QCBORDecode_GetDoubleConvert(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue)
{
@@ -1634,12 +1681,32 @@
QCBORDecode_GetDoubleConvertInternal(pMe, uOptions, pValue, &Item);
}
+inline static void QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, double *pdValue)
+{
+ QCBORItem Item;
+ QCBORDecode_GetDoubleConvertInternalInMapN(pMe, nLabel, uOptions, pdValue, &Item);
+}
+
+inline static void QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, double *pdValue)
+{
+ QCBORItem Item;
+ QCBORDecode_GetDoubleConvertInternalInMapSZ(pMe, szLabel, uOptions, pdValue, &Item);
+}
inline static void QCBORDecode_GetDouble(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue)
{
QCBORDecode_GetDoubleConvert(pMe, QCBOR_CONVERT_TYPE_FLOAT, pValue);
}
+inline static void QCBORDecode_GetDoubleInMapN(QCBORDecodeContext *pMe, int64_t nLabel, double *pdValue)
+{
+ QCBORDecode_GetDoubleConvertInMapN(pMe, nLabel, QCBOR_CONVERT_TYPE_FLOAT, pdValue);
+}
+
+inline static void QCBORDecode_GetDoubleInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, double *pdValue)
+{
+ QCBORDecode_GetDoubleConvertInMapSZ(pMe, szLabel, QCBOR_CONVERT_TYPE_FLOAT, pdValue);
+}
// Semi private
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 850504b..84db9e0 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2242,7 +2242,7 @@
return;
}
- pMe->uLastError = CheckTagRequirement(TagSpec, pItem->uDataType);
+ pMe->uLastError = (uint8_t)CheckTagRequirement(TagSpec, pItem->uDataType);
}
void QCBORDecode_GetTaggedItemInMapSZ(QCBORDecodeContext *pMe,
@@ -2255,7 +2255,7 @@
return;
}
- pMe->uLastError = CheckTagRequirement(TagSpec, pItem->uDataType);
+ pMe->uLastError = (uint8_t)CheckTagRequirement(TagSpec, pItem->uDataType);
}
void QCBORDecode_GetTaggedStringInMapN(QCBORDecodeContext *pMe,
@@ -2575,7 +2575,7 @@
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
- pMe->uLastError = ConvertBigNum(&Item, pValue, pbIsNegative);
+ pMe->uLastError = (uint8_t)ConvertBigNum(&Item, pValue, pbIsNegative);
}
@@ -2762,6 +2762,18 @@
#include "fenv.h"
+/*
+Convert a integers and floats to an int64_t.
+
+\param[in] uOptions Bit mask list of conversion options.
+
+\retval QCBOR_ERR_CONVERSION_NOT_REQUESTED Conversion, possible, but not requested in uOptions.
+
+\retval QCBOR_ERR_UNEXPECTED_TYPE Of a type that can't be converted
+
+\retval QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW Conversion result is too large or too small.
+
+*/
static QCBORError ConvertInt64(const QCBORItem *pItem, uint32_t uOptions, int64_t *pnValue)
{
switch(pItem->uDataType) {
@@ -2807,6 +2819,7 @@
return QCBOR_SUCCESS;
}
+
void QCBORDecode_GetInt64ConvertInternal(QCBORDecodeContext *pMe,
uint32_t uOptions,
int64_t *pnValue,
@@ -2827,9 +2840,10 @@
*pItem = Item;
}
- pMe->uLastError = ConvertInt64(&Item, uOptions, pnValue);
+ pMe->uLastError = (uint8_t)ConvertInt64(&Item, uOptions, pnValue);
}
+
void QCBORDecode_GetInt64ConvertInternalInMapN(QCBORDecodeContext *pMe,
int64_t nLabel,
uint32_t uOptions,
@@ -2839,9 +2853,10 @@
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
- pMe->uLastError = ConvertInt64(&Item, uOptions, pnValue);
+ pMe->uLastError = (uint8_t)ConvertInt64(&Item, uOptions, pnValue);
}
+
void QCBORDecode_GetInt64ConvertInternalInMapSZ(QCBORDecodeContext *pMe,
const char * szLabel,
uint32_t uOptions,
@@ -2855,12 +2870,23 @@
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
- pMe->uLastError = ConvertInt64(&Item, uOptions, pnValue);
+ pMe->uLastError = (uint8_t)ConvertInt64(&Item, uOptions, pnValue);
}
+/*
+ Convert a large variety of integer types to an int64_t.
+ \param[in] uOptions Bit mask list of conversion options.
+
+ \retval QCBOR_ERR_CONVERSION_NOT_REQUESTED Conversion, possible, but not requested in uOptions.
+
+ \retval QCBOR_ERR_UNEXPECTED_TYPE Of a type that can't be converted
+
+ \retval QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW Conversion result is too large or too small.
+
+ */
static QCBORError Int64ConvertAll(const QCBORItem *pItem, uint32_t uOptions, int64_t *pnValue)
{
QCBORError uErr;
@@ -2906,7 +2932,6 @@
}
break;
-
case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
int64_t nMantissa;
@@ -2976,6 +3001,8 @@
#endif
}
}
+
+
/*
Public function, see header qcbor/qcbor_decode.h file
*/
@@ -2998,6 +3025,10 @@
pMe->uLastError = (uint8_t)Int64ConvertAll(&Item, uOptions, pnValue);
}
+
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
void QCBORDecode_GetInt64ConvertAllInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, int64_t *pnValue)
{
QCBORItem Item;
@@ -3018,11 +3049,12 @@
}
-
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
void QCBORDecode_GetInt64ConvertAllInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, int64_t *pnValue)
{
QCBORItem Item;
-
QCBORDecode_GetInt64ConvertInternalInMapSZ(pMe, szLabel, uOptions, pnValue, &Item);
if(pMe->uLastError == QCBOR_SUCCESS) {
@@ -3039,12 +3071,61 @@
}
+static QCBORError ConvertUint64(const QCBORItem *pItem, uint32_t uOptions, uint64_t *puValue)
+{
+ switch(pItem->uDataType) {
+ // TODO: type flaot
+ case QCBOR_TYPE_DOUBLE:
+ if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
+ feclearexcept(FE_ALL_EXCEPT);
+ double dRounded = round(pItem->val.dfnum);
+ // TODO: over/underflow
+ if(fetestexcept(FE_INVALID)) {
+ // TODO: better error code
+ return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+ } else if(isnan(dRounded)) {
+ // TODO: better error code
+ return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+ } else if(dRounded >= 0) {
+ *puValue = (uint64_t)dRounded;
+ } else {
+ return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+ }
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+ case QCBOR_TYPE_INT64:
+ if(uOptions & QCBOR_CONVERT_TYPE_INT64) {
+ if(pItem->val.int64 >= 0) {
+ *puValue = (uint64_t)pItem->val.int64;
+ } else {
+ return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+ }
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_UINT64:
+ if(uOptions & QCBOR_CONVERT_TYPE_UINT64) {
+ *puValue = pItem->val.uint64;
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ default:
+ return QCBOR_ERR_UNEXPECTED_TYPE;
+ }
+ return QCBOR_SUCCESS;
+}
void QCBORDecode_GetUInt64ConvertInternal(QCBORDecodeContext *pMe,
uint32_t uOptions,
- uint64_t *pValue,
+ uint64_t *puValue,
QCBORItem *pItem)
{
if(pMe->uLastError != QCBOR_SUCCESS) {
@@ -3063,63 +3144,149 @@
*pItem = Item;
}
- switch(Item.uDataType) {
- // TODO: type flaot
- case QCBOR_TYPE_DOUBLE:
- if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
- feclearexcept(FE_ALL_EXCEPT);
- double dRounded = round(Item.val.dfnum);
- // TODO: over/underflow
- if(fetestexcept(FE_INVALID)) {
- // TODO: better error code
- pMe->uLastError = QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
- } else if(isnan(dRounded)) {
- // TODO: better error code
- pMe->uLastError = QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
- } else if(dRounded >= 0) {
- *pValue = (uint64_t)dRounded;
- } else {
- pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
- }
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_INT64:
- if(uOptions & QCBOR_CONVERT_TYPE_INT64) {
- if(Item.val.int64 >= 0) {
- *pValue = (uint64_t)Item.val.int64;
- } else {
- pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
- }
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_UINT64:
- if(uOptions & QCBOR_CONVERT_TYPE_UINT64) {
- *pValue = Item.val.uint64;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- default:
- pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
- }
+ pMe->uLastError = (uint8_t)ConvertUint64(&Item, uOptions, puValue);
}
+void QCBORDecode_GetUint64ConvertInternalInMapN(QCBORDecodeContext *pMe,
+ int64_t nLabel,
+ uint32_t uOptions,
+ uint64_t *puValue,
+ QCBORItem *pItem)
+{
+ QCBORItem Item;
+ QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+
+ pMe->uLastError = (uint8_t)ConvertUint64(&Item, uOptions, puValue);
+}
+
+
+void QCBORDecode_GetUint64ConvertInternalInMapSZ(QCBORDecodeContext *pMe,
+ const char * szLabel,
+ uint32_t uOptions,
+ uint64_t *puValue,
+ QCBORItem *pItem)
+{
+ if(pMe->uLastError != QCBOR_SUCCESS) {
+ return;
+ }
+
+ QCBORItem Item;
+ QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+
+ pMe->uLastError = (uint8_t)ConvertUint64(&Item, uOptions, puValue);
+}
+
/*
Public function, see header qcbor/qcbor_decode.h file
*/
-void QCBORDecode_GetUInt64ConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *pValue)
+static QCBORError Uint64ConvertAll(const QCBORItem *pItem, uint32_t uOptions, uint64_t *puValue)
+{
+ QCBORError uErr;
+
+ switch(pItem->uDataType) {
+
+ case QCBOR_TYPE_POSBIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
+ return ConvertPositiveBigNumToUnsigned(pItem->val.bigNum, puValue);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_NEGBIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
+ return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+
+ case QCBOR_TYPE_DECIMAL_FRACTION:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ return ExponentitateNU(pItem->val.expAndMantissa.Mantissa.nInt,
+ pItem->val.expAndMantissa.nExponent,
+ puValue,
+ Exponentitate10);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_BIGFLOAT:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
+ return ExponentitateNU(pItem->val.expAndMantissa.Mantissa.nInt,
+ pItem->val.expAndMantissa.nExponent,
+ puValue,
+ Exponentitate2);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ // TODO: Would be better to convert to unsigned
+ int64_t nMantissa;
+ uErr = ConvertPositiveBigNumToSigned(pItem->val.expAndMantissa.Mantissa.bigNum, &nMantissa);
+ if(uErr != QCBOR_SUCCESS) {
+ return uErr;
+ }
+ return ExponentitateNU(nMantissa,
+ pItem->val.expAndMantissa.nExponent,
+ puValue,
+ Exponentitate10);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_BIGFLOAT_POS_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ // TODO: Would be better to convert to unsigned
+ int64_t nMantissa;
+ uErr = ConvertPositiveBigNumToSigned(pItem->val.expAndMantissa.Mantissa.bigNum, &nMantissa);
+ if(uErr != QCBOR_SUCCESS) {
+ return uErr;
+ }
+ return ExponentitateNU(nMantissa,
+ pItem->val.expAndMantissa.nExponent,
+ puValue,
+ Exponentitate2);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+#endif
+ default:
+ return QCBOR_ERR_UNEXPECTED_TYPE;
+ }
+}
+
+
+void QCBORDecode_GetUInt64ConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *puValue)
{
QCBORItem Item;
- QCBORDecode_GetUInt64ConvertInternal(pMe, uOptions, pValue, &Item);
+ QCBORDecode_GetUInt64ConvertInternal(pMe, uOptions, puValue, &Item);
if(pMe->uLastError == QCBOR_SUCCESS) {
// The above conversion succeeded
@@ -3131,108 +3298,99 @@
return;
}
- switch(Item.uDataType) {
-
- case QCBOR_TYPE_POSBIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
- pMe->uLastError = (uint8_t)ConvertPositiveBigNumToUnsigned(Item.val.bigNum, pValue);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_NEGBIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
- pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
-#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
-
- case QCBOR_TYPE_DECIMAL_FRACTION:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- pMe->uLastError = (uint8_t)ExponentitateNU(Item.val.expAndMantissa.Mantissa.nInt,
- Item.val.expAndMantissa.nExponent,
- pValue,
- Exponentitate10);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_BIGFLOAT:
- if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
- pMe->uLastError = (uint8_t)ExponentitateNU(Item.val.expAndMantissa.Mantissa.nInt,
- Item.val.expAndMantissa.nExponent,
- pValue,
- Exponentitate2);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
-
-
- case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- // TODO: Would be better to convert to unsigned
- int64_t nMantissa;
- pMe->uLastError = (uint8_t)ConvertPositiveBigNumToSigned(Item.val.expAndMantissa.Mantissa.bigNum, &nMantissa);
- if(!pMe->uLastError) {
- pMe->uLastError = (uint8_t)ExponentitateNU(nMantissa,
- Item.val.expAndMantissa.nExponent,
- pValue,
- Exponentitate10);
-
- }
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_BIGFLOAT_POS_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- // TODO: Would be better to convert to unsigned
- int64_t nMantissa;
- pMe->uLastError = (uint8_t)ConvertPositiveBigNumToSigned(Item.val.expAndMantissa.Mantissa.bigNum, &nMantissa);
- if(!pMe->uLastError) {
- pMe->uLastError = (uint8_t)ExponentitateNU(nMantissa,
- Item.val.expAndMantissa.nExponent,
- pValue,
- Exponentitate2);
- }
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- pMe->uLastError = QCBOR_ERR_NUMBER_SIGN_CONVERSION;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-#endif
- default:
- pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
- }
+ pMe->uLastError = (uint8_t)Uint64ConvertAll(&Item, uOptions, puValue);
}
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
+void QCBORDecode_GetUint64ConvertAllInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, uint64_t *puValue)
+{
+ QCBORItem Item;
+
+ QCBORDecode_GetUint64ConvertInternalInMapN(pMe, nLabel, uOptions, puValue, &Item);
+
+ if(pMe->uLastError == QCBOR_SUCCESS) {
+ // The above conversion succeeded
+ return;
+ }
+
+ if(pMe->uLastError != QCBOR_ERR_UNEXPECTED_TYPE) {
+ // The above conversion failed in a way that code below can't correct
+ return;
+ }
+
+ pMe->uLastError = (uint8_t)Uint64ConvertAll(&Item, uOptions, puValue);
+}
+
+
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
+void QCBORDecode_GetUint64ConvertAllInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, uint64_t *puValue)
+{
+ QCBORItem Item;
+ QCBORDecode_GetUint64ConvertInternalInMapSZ(pMe, szLabel, uOptions, puValue, &Item);
+
+ if(pMe->uLastError == QCBOR_SUCCESS) {
+ // The above conversion succeeded
+ return;
+ }
+
+ if(pMe->uLastError != QCBOR_ERR_UNEXPECTED_TYPE) {
+ // The above conversion failed in a way that code below can't correct
+ return;
+ }
+
+ pMe->uLastError = (uint8_t)Uint64ConvertAll(&Item, uOptions, puValue);
+}
+
+
+static QCBORError ConvertDouble(const QCBORItem *pItem, uint32_t uOptions, double *pdValue)
+{
+ switch(pItem->uDataType) {
+ // TODO: float when ifdefs are set
+ case QCBOR_TYPE_DOUBLE:
+ if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
+ if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
+ *pdValue = pItem->val.dfnum;
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ }
+ break;
+
+ case QCBOR_TYPE_INT64:
+ if(uOptions & QCBOR_CONVERT_TYPE_INT64) {
+ // TODO: how does this work?
+ *pdValue = (double)pItem->val.int64;
+
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_UINT64:
+ if(uOptions & QCBOR_CONVERT_TYPE_UINT64) {
+ *pdValue = (double)pItem->val.uint64;
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ default:
+ return QCBOR_ERR_UNEXPECTED_TYPE;
+ }
+
+ return QCBOR_SUCCESS;
+}
+
+
+
void QCBORDecode_GetDoubleConvertInternal(QCBORDecodeContext *pMe,
uint32_t uOptions,
- double *pValue,
+ double *pdValue,
QCBORItem *pItem)
{
if(pMe->uLastError != QCBOR_SUCCESS) {
@@ -3251,41 +3409,40 @@
*pItem = Item;
}
- switch(Item.uDataType) {
- // TODO: float when ifdefs are set
- case QCBOR_TYPE_DOUBLE:
- if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
- if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
- *pValue = Item.val.dfnum;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- }
- break;
-
- case QCBOR_TYPE_INT64:
- if(uOptions & QCBOR_CONVERT_TYPE_INT64) {
- // TODO: how does this work?
- *pValue = (double)Item.val.int64;
-
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_UINT64:
- if(uOptions & QCBOR_CONVERT_TYPE_UINT64) {
- *pValue = (double)Item.val.uint64;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
- default:
- pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
- }
+ pMe->uLastError = (uint8_t)ConvertDouble(&Item, uOptions, pdValue);
}
+void QCBORDecode_GetDoubleConvertInternalInMapN(QCBORDecodeContext *pMe,
+ int64_t nLabel,
+ uint32_t uOptions,
+ double *pdValue,
+ QCBORItem *pItem)
+{
+ QCBORItem Item;
+ QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+
+ pMe->uLastError = (uint8_t)ConvertDouble(&Item, uOptions, pdValue);
+}
+
+void QCBORDecode_GetDoubleConvertInternalInMapSZ(QCBORDecodeContext *pMe,
+ const char * szLabel,
+ uint32_t uOptions,
+ double *pdValue,
+ QCBORItem *pItem)
+{
+ if(pMe->uLastError != QCBOR_SUCCESS) {
+ return;
+ }
+
+ QCBORItem Item;
+ QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+
+ pMe->uLastError = (uint8_t)ConvertDouble(&Item, uOptions, pdValue);
+}
+
+
+
static double ConvertBigNumToDouble(const UsefulBufC BigNum)
{
double dResult;
@@ -3303,20 +3460,102 @@
return dResult;
}
-/*
- Public function, see header qcbor/qcbor_decode.h file
-*/
-void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue)
+static QCBORError DoubleConvertAll(const QCBORItem *pItem, uint32_t uOptions, double *pdValue)
{
/*
-
-
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
*/
+ switch(pItem->uDataType) {
+ // TODO: type float
+ case QCBOR_TYPE_DECIMAL_FRACTION:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ // TODO: rounding and overflow errors
+ *pdValue = (double)pItem->val.expAndMantissa.Mantissa.nInt *
+ pow(10.0, (double)pItem->val.expAndMantissa.nExponent);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_BIGFLOAT:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT ) {
+ *pdValue = (double)pItem->val.expAndMantissa.Mantissa.nInt *
+ exp2((double)pItem->val.expAndMantissa.nExponent);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_POSBIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
+ *pdValue = ConvertBigNumToDouble(pItem->val.bigNum);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_NEGBIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
+ *pdValue = -ConvertBigNumToDouble(pItem->val.bigNum);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ double dMantissa = ConvertBigNumToDouble(pItem->val.expAndMantissa.Mantissa.bigNum);
+ *pdValue = dMantissa * pow(10, (double)pItem->val.expAndMantissa.nExponent);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
+ double dMantissa = -ConvertBigNumToDouble(pItem->val.expAndMantissa.Mantissa.bigNum);
+ *pdValue = dMantissa * pow(10, (double)pItem->val.expAndMantissa.nExponent);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_BIGFLOAT_POS_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
+ double dMantissa = ConvertBigNumToDouble(pItem->val.expAndMantissa.Mantissa.bigNum);
+ *pdValue = dMantissa * exp2((double)pItem->val.expAndMantissa.nExponent);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ case QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM:
+ if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
+ double dMantissa = -ConvertBigNumToDouble(pItem->val.expAndMantissa.Mantissa.bigNum);
+ *pdValue = dMantissa * exp2((double)pItem->val.expAndMantissa.nExponent);
+ } else {
+ return QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
+ break;
+
+ default:
+ return QCBOR_ERR_UNEXPECTED_TYPE;
+ }
+
+ return QCBOR_SUCCESS;
+}
+
+
+/*
+ Public function, see header qcbor/qcbor_decode.h file
+*/
+void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, double *pdValue)
+{
+
QCBORItem Item;
- QCBORDecode_GetDoubleConvertInternal(pMe, uOptions, pValue, &Item);
+ QCBORDecode_GetDoubleConvertInternal(pMe, uOptions, pdValue, &Item);
if(pMe->uLastError == QCBOR_SUCCESS) {
// The above conversion succeeded
@@ -3328,83 +3567,50 @@
return;
}
- pMe->uLastError = QCBOR_SUCCESS;
-
- switch(Item.uDataType) {
- // TODO: type float
- case QCBOR_TYPE_DECIMAL_FRACTION:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- // TODO: rounding and overflow errors
- *pValue = (double)Item.val.expAndMantissa.Mantissa.nInt *
- pow(10.0, (double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_BIGFLOAT:
- if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT ) {
- *pValue = (double)Item.val.expAndMantissa.Mantissa.nInt *
- exp2((double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_POSBIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
- *pValue = ConvertBigNumToDouble(Item.val.bigNum);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_NEGBIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_BIG_NUM) {
- *pValue = -ConvertBigNumToDouble(Item.val.bigNum);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- double dMantissa = ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
- *pValue = dMantissa * pow(10, (double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
- double dMantissa = -ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
- *pValue = dMantissa * pow(10, (double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_BIGFLOAT_POS_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
- double dMantissa = ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
- *pValue = dMantissa * exp2((double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- case QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM:
- if(uOptions & QCBOR_CONVERT_TYPE_BIGFLOAT) {
- double dMantissa = -ConvertBigNumToDouble(Item.val.expAndMantissa.Mantissa.bigNum);
- *pValue = dMantissa * exp2((double)Item.val.expAndMantissa.nExponent);
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
- }
- break;
-
- default:
- pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
- }
+ pMe->uLastError = (uint8_t)DoubleConvertAll(&Item, uOptions, pdValue);
}
+
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
+void QCBORDecode_GetDoubleConvertAllInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, double *pdValue)
+{
+ QCBORItem Item;
+
+ QCBORDecode_GetDoubleConvertInternalInMapN(pMe, nLabel, uOptions, pdValue, &Item);
+
+ if(pMe->uLastError == QCBOR_SUCCESS) {
+ // The above conversion succeeded
+ return;
+ }
+
+ if(pMe->uLastError != QCBOR_ERR_UNEXPECTED_TYPE) {
+ // The above conversion failed in a way that code below can't correct
+ return;
+ }
+
+ pMe->uLastError = (uint8_t)DoubleConvertAll(&Item, uOptions, pdValue);
+}
+
+
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
+void QCBORDecode_GetDoubleConvertAllInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, double *pdValue)
+{
+ QCBORItem Item;
+ QCBORDecode_GetDoubleConvertInternalInMapSZ(pMe, szLabel, uOptions, pdValue, &Item);
+
+ if(pMe->uLastError == QCBOR_SUCCESS) {
+ // The above conversion succeeded
+ return;
+ }
+
+ if(pMe->uLastError != QCBOR_ERR_UNEXPECTED_TYPE) {
+ // The above conversion failed in a way that code below can't correct
+ return;
+ }
+
+ pMe->uLastError = (uint8_t)DoubleConvertAll(&Item, uOptions, pdValue);
+}