Support for 65-bit negative integers (#195)
This adds support for encoding and decoding 65-bit negative integers -2^63 to -2^64. Not a feature that is recommended for use, but this is a complete CBOR implementation.
This includes conversion to float of 65-big negative integers if requested.
* Support for 65-bit negative integers
* Test, doc and fixes
* testing, fixes and doc clean up
* documentation fixes
* remove some junk
---------
Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 693152f..332314b 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -884,10 +884,8 @@
pDecodedItem->uDataType = QCBOR_TYPE_INT64;
} else {
- /* C can't represent a negative integer in this range so it
- * is an error.
- */
- uReturn = QCBOR_ERR_INT_OVERFLOW;
+ pDecodedItem->val.uint64 = uArgument;
+ pDecodedItem->uDataType = QCBOR_TYPE_65BIT_NEG_INT;
}
}
@@ -4921,6 +4919,12 @@
}
break;
+ case QCBOR_TYPE_65BIT_NEG_INT:
+ /* This type occurs if the value won't fit into int64_t
+ * so this is always an error. */
+ return QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+ break;
+
default:
return QCBOR_ERR_UNEXPECTED_TYPE;
}
@@ -5291,12 +5295,15 @@
case QCBOR_TYPE_UINT64:
if(uConvertTypes & QCBOR_CONVERT_TYPE_XINT64) {
- *puValue = pItem->val.uint64;
+ *puValue = pItem->val.uint64;
} else {
return QCBOR_ERR_UNEXPECTED_TYPE;
}
break;
+ case QCBOR_TYPE_65BIT_NEG_INT:
+ return QCBOR_ERR_NUMBER_SIGN_CONVERSION;
+
default:
return QCBOR_ERR_UNEXPECTED_TYPE;
}
@@ -5634,6 +5641,10 @@
return QCBOR_ERR_HW_FLOAT_DISABLED;
#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+ case QCBOR_TYPE_65BIT_NEG_INT:
+ *pdValue = -(double)pItem->val.uint64 - 1;
+ break;
+
default:
return QCBOR_ERR_UNEXPECTED_TYPE;
}
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 146253d..a2a944a 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -665,6 +665,18 @@
/*
+ * Public functions for adding negative integers. See qcbor/qcbor_encode.h
+ */
+void QCBOREncode_AddNegativeUInt64(QCBOREncodeContext *pMe, const uint64_t uValue)
+{
+ // TODO: Error out in dCBOR mode
+ QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_NEGATIVE_INT, uValue, 0);
+
+ QCBOREncode_Private_IncrementMapOrArrayCount(pMe);
+}
+
+
+/*
* Public functions for adding signed integers. See qcbor/qcbor_encode.h
*/
void
@@ -676,9 +688,9 @@
if(nNum < 0) {
/* In CBOR -1 encodes as 0x00 with major type negative int.
* First add one as a signed integer because that will not
- * overflow. Then change the sign as needed for encoding. (The
+ * overflow. Then change the sign as needed for encoding (the
* opposite order, changing the sign and subtracting, can cause
- * an overflow when encoding INT64_MIN. */
+ * an overflow when encoding INT64_MIN). */
int64_t nTmp = nNum + 1;
uValue = (uint64_t)-nTmp;
uMajorType = CBOR_MAJOR_TYPE_NEGATIVE_INT;