Reduce encode code size; new function QCBOREncode_AddSimple
Reduces object code size for minimal encode use case by about 50 bytes through some re factoring of the encoder. Size is reduced for maximal use cases too.
QCBOREncode_AddSimple() is made public.
* Readme and copyright updates
* Core encoder optimizations
* Tidy up and rearrange
* Documentation fixes
* Make AddSimple public
* Test fan out is working
---------
Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 774f272..e86108b 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -535,7 +535,7 @@
*
* Error handling is the same as for QCBOREncode_AddInt64().
*/
-void
+static void
QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
static void
@@ -695,7 +695,7 @@
* See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
* QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
*/
-void
+static void
QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
static void
@@ -719,7 +719,7 @@
* See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
* QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
*/
-void
+static void
QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
static void
@@ -753,7 +753,7 @@
* tags. See QCBORDecode_GetNext() for discussion of decoding custom
* tags.
*/
-void
+static void
QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
@@ -1748,7 +1748,6 @@
QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
-
/**
* @brief Add a NULL to the encoded output.
*
@@ -1796,6 +1795,33 @@
/**
+ * @brief Add a simple value.
+ *
+ * @param[in] pMe The encode context.
+ * @param[in] uNum The simple value.
+ *
+ * Use QCBOREncode_AddBool(), QCBOREncode_AddUndef()... instead of this.
+ *
+ * Use this to add simple values beyond those in defined RFC
+ * 8949. Simple values must be registered with IANA. There is no range
+ * of values for proprietary use.
+ * https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xhtml
+ */
+static void
+QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum);
+
+static void
+QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
+ const char *szLabel,
+ const uint8_t uSimple);
+
+static void
+QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
+ const int64_t nLabel,
+ const uint8_t uSimple);
+
+
+/**
* @brief Indicates that the next items added are in an array.
*
* @param[in] pCtx The encoding context to open the array in.
@@ -2122,7 +2148,7 @@
* must be enclosed in a map or array. At the top level the raw
* CBOR must be a single data item.
*/
-static void
+void
QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
static void
@@ -2287,8 +2313,6 @@
* 100,010 byte buffer and encode it normally. Alternatively, you can
* encode the head in a 10 byte buffer with this function, hash that and
* then hash the 100,000 bytes using the same hash context.
- *
- * See also QCBOREncode_AddBytesLenOnly();
*/
UsefulBufC
QCBOREncode_EncodeHead(UsefulBuf Buffer,
@@ -2304,6 +2328,13 @@
========================================================================= */
/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
+void QCBOREncode_Private_AppendCBORHead(QCBOREncodeContext *pMe,
+ const uint8_t uMajorType,
+ const uint64_t uArgument,
+ const uint8_t uMinLen);
+
+
+/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
void
QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
uint8_t uMajorType,
@@ -2336,13 +2367,6 @@
/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
void
-QCBOREncode_Private_AddType7(QCBOREncodeContext *pCtx,
- uint8_t uMinLen,
- uint64_t uNum);
-
-
-/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
-void
QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
uint64_t uTag,
UsefulBufC BigNumMantissa,
@@ -2350,6 +2374,31 @@
int64_t nMantissa,
int64_t nExponent);
+
+/**
+ * @brief Semi-private method to add simple items and floating-point.
+ *
+ * @param[in] pMe The encoding context.
+ * @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
+ * @param[in] uArgument The value to add.
+ *
+ * This is used to add simple types like true and false and float-point
+ * values, both of which are type 7.
+ *
+ * Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
+ * QCBOREncode_AddUndef() QCBOREncode_AddDouble() instead of this.
+ *
+ * Error handling is the same as QCBOREncode_AddInt64().
+ */
+static inline void
+QCBOREncode_Private_AddType7(QCBOREncodeContext *pMe,
+ const uint8_t uMinLen,
+ const uint64_t uArgument)
+{
+ QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_SIMPLE, uArgument, uMinLen);
+}
+
+
/**
* @brief Semi-private method to add only the type and length of a byte string.
*
@@ -2370,7 +2419,7 @@
* output buffer, rather than two, roughly cutting memory use in half.
*
* This is only used for this odd case, but this is a supported
- * tested function.
+ * tested function for QCBOR 1.0.
*
* See also QCBOREncode_EncodeHead().
*/
@@ -2389,6 +2438,10 @@
UsefulBufC Bytes);
+/* Forward declaration */
+static void
+QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString);
+
@@ -2397,10 +2450,7 @@
const char *szLabel,
const int64_t uNum)
{
- /* Use _AddBuffer() because _AddSZString() is defined below, not above */
- QCBOREncode_Private_AddBuffer(pMe,
- CBOR_MAJOR_TYPE_TEXT_STRING,
- UsefulBuf_FromSZ(szLabel));
+ QCBOREncode_AddSZString(pMe, szLabel);
QCBOREncode_AddInt64(pMe, uNum);
}
@@ -2415,14 +2465,18 @@
static inline void
+QCBOREncode_AddUInt64(QCBOREncodeContext *pMe, const uint64_t uValue)
+{
+ QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_POSITIVE_INT, uValue, 0);
+}
+
+
+static inline void
QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
const char *szLabel,
const uint64_t uNum)
{
- /* Use _AddBuffer() because _AddSZString() is defined below, not above */
- QCBOREncode_Private_AddBuffer(pMe,
- CBOR_MAJOR_TYPE_TEXT_STRING,
- UsefulBuf_FromSZ(szLabel));
+ QCBOREncode_AddSZString(pMe, szLabel);
QCBOREncode_AddUInt64(pMe, uNum);
}
@@ -2486,7 +2540,37 @@
}
+
+/*
+ * Public functions for adding a tag. See qcbor/qcbor_encode.h
+ */
+static inline void
+QCBOREncode_AddTag(QCBOREncodeContext *pMe, const uint64_t uTag)
+{
+ QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_TAG, uTag, 0);
+}
+
+
+
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
+
+static inline void
+QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pMe, const double dNum)
+{
+ QCBOREncode_Private_AddType7(pMe,
+ sizeof(uint64_t),
+ UsefulBufUtil_CopyDoubleToUint64(dNum));
+}
+
+static inline void
+QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pMe, const float fNum)
+{
+ QCBOREncode_Private_AddType7(pMe,
+ sizeof(uint32_t),
+ UsefulBufUtil_CopyFloatToUint32(fNum));
+}
+
+
static inline void
QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
const char *szLabel,
@@ -2562,6 +2646,8 @@
+
+
static inline void
QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
const uint8_t uTag,
@@ -2694,12 +2780,17 @@
QCBOREncode_OpenBytes(pMe, pPlace);
}
+
+/*
+ * Public functions for adding only a byte string length. See qcbor/qcbor_encode.h
+ */
static inline void
QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
{
- QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
+ QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes.len, 0);
}
+
static inline void
QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
const char *szLabel,
@@ -3628,29 +3719,36 @@
}
-
static inline void
-QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
+QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
{
+ /* This check often is optimized out because uNum is known at compile time. */
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ if(uNum >= CBOR_SIMPLEV_RESERVED_START && uNum <= CBOR_SIMPLEV_RESERVED_END) {
+ pMe->uError = QCBOR_ERR_ENCODE_UNSUPPORTED;
+ return;
+ }
+#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
QCBOREncode_Private_AddType7(pMe, 0, uNum);
}
static inline void
-QCBOREncode_Private_AddSimpleToMap(QCBOREncodeContext *pMe,
+QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
const char *szLabel,
const uint8_t uSimple)
{
QCBOREncode_AddSZString(pMe, szLabel);
- QCBOREncode_Private_AddSimple(pMe, uSimple);
+ QCBOREncode_AddSimple(pMe, uSimple);
}
static inline void
-QCBOREncode_Private_AddSimpleToMapN(QCBOREncodeContext *pMe,
+QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
const int64_t nLabel,
const uint8_t uSimple)
{
QCBOREncode_AddInt64(pMe, nLabel);
- QCBOREncode_Private_AddSimple(pMe, uSimple);
+ QCBOREncode_AddSimple(pMe, uSimple);
}
@@ -3661,7 +3759,7 @@
if(b) {
uSimple = CBOR_SIMPLEV_TRUE;
}
- QCBOREncode_Private_AddSimple(pMe, uSimple);
+ QCBOREncode_AddSimple(pMe, uSimple);
}
static inline void
@@ -3682,7 +3780,7 @@
static inline void
QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
{
- QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_NULL);
+ QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
}
static inline void
@@ -3703,7 +3801,7 @@
static inline void
QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
{
- QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
+ QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
}
static inline void
@@ -3859,11 +3957,6 @@
}
-static inline void
-QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
-{
- QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
-}
static inline void
QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index 35c60a7..a061809 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -377,9 +377,7 @@
/* Used internally in the impementation here Must not conflict with
* any of the official CBOR types
*/
-#define CBOR_MAJOR_NONE_TYPE_RAW 9
#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
-#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
#define CBOR_MAJOR_NONE_TYPE_OPEN_BSTR 12