close-to-final arrangement of integer conversion code
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 0eabfb1..8b5d056 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -320,6 +320,22 @@
}
+static void DecodeNesting_PrepareForMapSearch(QCBORDecodeNesting *pNesting, QCBORDecodeNesting *pSave)
+{
+ *pSave = *pNesting;
+ pNesting->pCurrent = pNesting->pCurrentMap;
+
+ if(pNesting->pCurrent->uCount != UINT16_MAX) {
+ pNesting->pCurrent->uCount = pNesting->pCurrent->uSaveCount;
+ }
+}
+
+static void DecodeNesting_RestoreFromMapSearch(QCBORDecodeNesting *pNesting, QCBORDecodeNesting *pSave)
+{
+ *pNesting = *pSave;
+}
+
+
/*
This list of built-in tags. Only add tags here that are
@@ -1283,6 +1299,7 @@
// Tell the caller what level is next. This tells them what maps/arrays
// were closed out and makes it possible for them to reconstruct
// the tree with just the information returned by GetNext
+ // TODO: pull this into DecodeNesting_GetLevel
if(me->nesting.pCurrent->uMapMode && me->nesting.pCurrent->uCount == 0) {
// At end of a map / array in map mode, so next nest is 0 to
// indicate this end.
@@ -2012,8 +2029,8 @@
If an item was not found, its data type is set to none.
*/
-QCBORError
-GetItemsInMap(QCBORDecodeContext *pMe, QCBORItem *pItemArray, size_t *puOffset, size_t *puEndOffset)
+static QCBORError
+MapSearch(QCBORDecodeContext *pMe, QCBORItem *pItemArray, size_t *puOffset, size_t *puEndOffset)
{
QCBORError nReturn;
@@ -2022,12 +2039,8 @@
return QCBOR_ERR_NOT_ENTERED;
}
- QCBORDecodeNesting N = pMe->nesting;
- pMe->nesting.pCurrent = pMe->nesting.pCurrentMap;
-
- if(pMe->nesting.pCurrent->uCount != UINT16_MAX) {
- pMe->nesting.pCurrent->uCount = pMe->nesting.pCurrent->uSaveCount;
- }
+ QCBORDecodeNesting SaveNesting;
+ DecodeNesting_PrepareForMapSearch(&(pMe->nesting), &SaveNesting);
UsefulInputBuf_Seek(&(pMe->InBuf), pMe->nesting.pCurrent->uOffset);
@@ -2110,7 +2123,7 @@
}
Done:
- pMe->nesting = N;
+ DecodeNesting_RestoreFromMapSearch(&(pMe->nesting), &SaveNesting);
return nReturn;
}
@@ -2130,7 +2143,7 @@
Dummy.uLabelType = QCBOR_TYPE_NONE;
- QCBORError nReturn = GetItemsInMap(pMe, &Dummy, NULL, &uEndOffset);
+ QCBORError nReturn = MapSearch(pMe, &Dummy, NULL, &uEndOffset);
(void)nReturn; // TODO:
// }
@@ -2156,7 +2169,7 @@
One[0].uDataType = uQcborType;
One[1].uLabelType = QCBOR_TYPE_NONE; // Indicates end of array
- QCBORError nReturn = GetItemsInMap(pMe, One, NULL, NULL);
+ QCBORError nReturn = MapSearch(pMe, One, NULL, NULL);
if(nReturn) {
return nReturn;
}
@@ -2183,7 +2196,7 @@
One[0].uDataType = uQcborType;
One[1].uLabelType = QCBOR_TYPE_NONE; // Indicates end of array
- QCBORError nReturn = GetItemsInMap(pMe, One, NULL, NULL);
+ QCBORError nReturn = MapSearch(pMe, One, NULL, NULL);
if(nReturn) {
return nReturn;
}
@@ -2202,20 +2215,26 @@
static int FinishEnter(QCBORDecodeContext *pMe, size_t uOffset)
{
+ /* Need to get the current pre-order nesting level and cursor to be
+ at the first item in the map/array just entered.
+
+ Also need to current map nesting level and start cursor to
+ be at the right place.
+
+ The UsefulInBuf offset could be anywhere, so no assumption is
+ made about it.
+
+ No assumption is made about the pre-order nesting level either.
+
+ However the map mode nesting level is assumed to be one above
+ the map level that is being entered.
+ */
/* Seek to the data item that is the map or array */
UsefulInputBuf_Seek(&(pMe->InBuf), uOffset);
- pMe->nesting.pCurrent = pMe->nesting.pCurrentMap;
+ pMe->nesting.pCurrent = pMe->nesting.pCurrentMap; // TODO: part of DecodeNesting
- /* Skip the data item that is the map or array */
- QCBORItem MapToEnter;
- // TODO: check error
- QCBORDecode_GetNext(pMe, &MapToEnter);
-
- /* Enter map mode with an offset that is the first item
- in the map or array. */
- // TODO: what if map or array is empty?
- DecodeNesting_EnterMapMode(&(pMe->nesting), UsefulInputBuf_Tell(&(pMe->InBuf)));
-
+ // TODO: check error?
+ QCBORDecode_EnterMapMode(pMe, QCBOR_TYPE_MAP);
printdecode(pMe, "Entered Map in Map");
@@ -2234,7 +2253,7 @@
One[1].uLabelType = QCBOR_TYPE_NONE;
size_t uOffset;
- QCBORError nReturn = GetItemsInMap(pMe, One, &uOffset, NULL);
+ QCBORError nReturn = MapSearch(pMe, One, &uOffset, NULL);
if(nReturn) {
return nReturn;
}
@@ -2258,7 +2277,7 @@
size_t uOffset;
- QCBORError nReturn = GetItemsInMap(pMe, One, &uOffset, NULL);
+ QCBORError nReturn = MapSearch(pMe, One, &uOffset, NULL);
if(nReturn) {
return nReturn;
@@ -2281,7 +2300,7 @@
size_t uOffset;
- QCBORError nReturn = GetItemsInMap(pMe, One, &uOffset, NULL);
+ QCBORError nReturn = MapSearch(pMe, One, &uOffset, NULL);
if(nReturn != QCBOR_SUCCESS) {
return nReturn;
@@ -2304,7 +2323,7 @@
size_t uOffset;
- QCBORError nReturn = GetItemsInMap(pMe, One, &uOffset, NULL);
+ QCBORError nReturn = MapSearch(pMe, One, &uOffset, NULL);
if(nReturn != QCBOR_SUCCESS) {
return nReturn;
@@ -2320,7 +2339,7 @@
/* Next item must be map or this generates an error */
-QCBORError QCBORDecode_EnterMap(QCBORDecodeContext *pMe)
+QCBORError QCBORDecode_EnterMapMode(QCBORDecodeContext *pMe, uint8_t uType)
{
QCBORItem Item;
QCBORError nReturn;
@@ -2330,7 +2349,7 @@
if(nReturn != QCBOR_SUCCESS) {
return nReturn;
}
- if(Item.uDataType != QCBOR_TYPE_MAP) {
+ if(Item.uDataType != uType) {
return QCBOR_ERR_UNEXPECTED_TYPE;
}
@@ -2345,7 +2364,7 @@
QCBORError QCBORDecode_GetItemsInMap(QCBORDecodeContext *pCtx, QCBORItem *pItemList)
{
- return GetItemsInMap(pCtx, pItemList, NULL, NULL);
+ return MapSearch(pCtx, pItemList, NULL, NULL);
}
@@ -2397,7 +2416,7 @@
Dummy.uLabelType = QCBOR_TYPE_NONE;
- QCBORError nReturn = GetItemsInMap(pMe, &Dummy, NULL, &uEndOffset);
+ QCBORError nReturn = MapSearch(pMe, &Dummy, NULL, &uEndOffset);
(void)nReturn; // TODO:
//}
@@ -2846,7 +2865,7 @@
a big float, a decimal fraction or a big num. Conversion will be dones as
expected. Some cases will error out with under or over flow.
*/
-static void QCBORDecode_GetInt64ConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, int64_t *pValue, QCBORItem *pItem)
+void QCBORDecode_GetInt64ConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, int64_t *pValue, QCBORItem *pItem)
{
if(pMe->uLastError != QCBOR_SUCCESS) {
return;
@@ -2907,20 +2926,6 @@
}
}
-/* This works for signed, unsigned and float data items */
-void QCBORDecode_GetInt64Convert(QCBORDecodeContext *pMe, uint32_t uOptions, int64_t *pValue)
-{
- QCBORItem Item;
- QCBORDecode_GetInt64ConvertInternal(pMe, uOptions, pValue, &Item);
-}
-
-
-// TODO make this inline
-void QCBORDecode_GetInt64(QCBORDecodeContext *pMe, uint32_t uOptions, int64_t *pValue)
-{
- QCBORDecode_GetInt64Convert(pMe, QCBOR_TYPE_INT64, pValue);
-}
-
/*
@@ -3122,22 +3127,6 @@
}
-/* This works for signed, unsigned and float */
-void QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *pValue)
-{
- QCBORItem Item;
- QCBORDecode_GetUInt64ConvertInternal(pMe, uOptions, pValue, &Item);
-}
-
-
-// TODO make this inline
-void QCBORDecode_GetUInt64(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *pValue)
-{
- QCBORDecode_GetUInt64Convert(pMe, QCBOR_TYPE_UINT64, pValue);
-}
-
-
-
void QCBORDecode_GetUInt64ConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *pValue)
{
@@ -3265,35 +3254,34 @@
}
-
-/*
-
- Convert from bignums,
-
- https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
-
- */
-void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue)
+void QCBORDecode_GetDoubleConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue, QCBORItem *pItem)
{
- /* the same range of conversions */
-
- QCBORItem Item;
- QCBORError nError;
-
- nError = QCBORDecode_GetNext(pMe, &Item);
- if(nError) {
- pMe->uLastError = (uint8_t)nError;
+ if(pMe->uLastError != QCBOR_SUCCESS) {
return;
}
+ QCBORItem Item;
+ QCBORError uError;
+
+ uError = QCBORDecode_GetNext(pMe, &Item);
+ if(uError) {
+ pMe->uLastError = (uint8_t)uError;
+ return;
+ }
+
+ if(pItem) {
+ *pItem = Item;
+ }
switch(Item.uDataType) {
- // TODO: type float
+ // TODO: float when ifdefs are set
case QCBOR_TYPE_DOUBLE:
if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
- *pValue = Item.val.dfnum;
- } else {
- pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ if(uOptions & QCBOR_CONVERT_TYPE_FLOAT) {
+ *pValue = Item.val.dfnum;
+ } else {
+ pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
+ }
}
break;
@@ -3301,6 +3289,7 @@
if(uOptions & QCBOR_CONVERT_TYPE_INT64) {
// TODO: how does this work?
*pValue = (double)Item.val.int64;
+
} else {
pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
}
@@ -3308,13 +3297,42 @@
case QCBOR_TYPE_UINT64:
if(uOptions & QCBOR_CONVERT_TYPE_UINT64) {
- // TODO: check more carefully how this cast works.
- *pValue = (double)Item.val.uint64;
+ *pValue = (double)Item.val.uint64;
} else {
pMe->uLastError = QCBOR_ERR_CONVERSION_NOT_REQUESTED;
}
+ break;
+
+ default:
+ pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+ }
+}
+/*
+
+
+ https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
+
+ */
+void QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue)
+{
+ QCBORItem Item;
+
+ QCBORDecode_GetDoubleConvertInternal(pMe, uOptions, pValue, &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;
+ }
+
+ switch(Item.uDataType) {
+ // TODO: type float
case QCBOR_TYPE_DECIMAL_FRACTION:
if(uOptions & QCBOR_CONVERT_TYPE_DECIMAL_FRACTION) {
// TODO: rounding and overflow errors