blob: a3360045b2f9f59ebe2091c531914ec9019d9383 [file] [log] [blame]
Laurence Lundbladec4474172020-10-02 14:52:16 -07001/* =========================================================================
2 example.c -- Example code for QCBOR
Laurence Lundbladed4cd7232020-07-03 19:30:48 -07003
Laurence Lundblade5c91eb32021-04-03 23:56:54 -07004 Copyright (c) 2020-2021, Laurence Lundblade. All rights reserved.
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02005 Copyright (c) 2021, Arm Limited. All rights reserved.
Laurence Lundbladed4cd7232020-07-03 19:30:48 -07006
Laurence Lundbladec4474172020-10-02 14:52:16 -07007 SPDX-License-Identifier: BSD-3-Clause
Laurence Lundbladed4cd7232020-07-03 19:30:48 -07008
Laurence Lundbladee8f58162024-08-22 10:30:08 -07009 See BSD-3-Clause license in file named "LICENSE"
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070010
Laurence Lundbladec4474172020-10-02 14:52:16 -070011 Created on 6/30/2020
12 ========================================================================== */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070013
14#include <stdio.h>
15#include "example.h"
Laurence Lundblade7596eef2024-12-21 10:08:32 -070016#include "qcbor/qcbor_main_encode.h"
17#include "qcbor/qcbor_number_encode.h"
Laurence Lundbladec9a1fc32024-12-12 13:00:06 -080018#include "qcbor/qcbor_main_decode.h"
Laurence Lundblade67257dc2020-07-27 03:33:37 -070019#include "qcbor/qcbor_spiffy_decode.h"
Laurence Lundblade33ed26f2024-11-24 10:26:43 -080020#include "qcbor/qcbor_number_decode.h"
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070021
Laurence Lundbladec4474172020-10-02 14:52:16 -070022
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070023/**
24 * This is a simple example of encoding and decoding some CBOR from
25 * and to a C structure.
26 *
27 * This also includes a comparison between the original structure
28 * and the one decoded from the CBOR to confirm correctness.
29 */
30
31
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070032#define MAX_CYLINDERS 16
33
Laurence Lundbladeda319282020-07-06 23:04:58 -070034/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070035 * The data structure representing a car engine that is encoded and
36 * decoded in this example.
Laurence Lundbladeda319282020-07-06 23:04:58 -070037 */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070038typedef struct
39{
Laurence Lundbladec4474172020-10-02 14:52:16 -070040 UsefulBufC Manufacturer;
41 int64_t uDisplacement;
42 int64_t uHorsePower;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020043#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladec4474172020-10-02 14:52:16 -070044 double dDesignedCompresion;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020045#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladec4474172020-10-02 14:52:16 -070046 int64_t uNumCylinders;
47 bool bTurboCharged;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020048#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladec4474172020-10-02 14:52:16 -070049 struct {
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070050 double dMeasuredCompression;
Laurence Lundbladec4474172020-10-02 14:52:16 -070051 } cylinders[MAX_CYLINDERS];
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020052#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeda319282020-07-06 23:04:58 -070053} CarEngine;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070054
55
Laurence Lundbladeda319282020-07-06 23:04:58 -070056/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070057 * @brief Initialize the Engine data structure with values to encode.
58 *
59 * @param[out] pE The Engine structure to fill in
Laurence Lundbladeda319282020-07-06 23:04:58 -070060 */
61void EngineInit(CarEngine *pE)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070062{
Laurence Lundbladec4474172020-10-02 14:52:16 -070063 pE->Manufacturer = UsefulBuf_FROM_SZ_LITERAL("Porsche");
64 pE->uDisplacement = 3296;
65 pE->uHorsePower = 210;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020066#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladec4474172020-10-02 14:52:16 -070067 pE->dDesignedCompresion = 9.1;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020068#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladec4474172020-10-02 14:52:16 -070069 pE->uNumCylinders = 6;
70 pE->bTurboCharged = false;
71
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020072#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070073 pE->cylinders[0].dMeasuredCompression = 9.0;
74 pE->cylinders[1].dMeasuredCompression = 9.2;
75 pE->cylinders[2].dMeasuredCompression = 8.9;
76 pE->cylinders[3].dMeasuredCompression = 8.9;
77 pE->cylinders[4].dMeasuredCompression = 9.1;
78 pE->cylinders[5].dMeasuredCompression = 9.0;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020079#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070080}
81
82
Laurence Lundbladeda319282020-07-06 23:04:58 -070083/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070084 * @brief Compare two Engine structure for equality.
85 *
86 * @param[in] pE1 First Engine to compare.
87 * @param[in] pE2 Second Engine to compare.
88 *
89 * @retval Return @c true if the two Engine data structures are exactly the
90 * same.
Laurence Lundbladeda319282020-07-06 23:04:58 -070091 */
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070092static bool EngineCompare(const CarEngine *pE1, const CarEngine *pE2)
Laurence Lundbladee6bbf552020-07-05 22:57:57 -070093{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070094 if(pE1->uNumCylinders != pE2->uNumCylinders) {
95 return false;
96 }
97 if(pE1->bTurboCharged != pE2->bTurboCharged) {
98 return false;
99 }
100 if(pE1->uDisplacement != pE2->uDisplacement) {
101 return false;
102 }
103 if(pE1->uHorsePower != pE2->uHorsePower) {
104 return false;
105 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200106#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700107 if(pE1->dDesignedCompresion != pE2->dDesignedCompresion) {
108 return false;
109 }
110 for(int64_t i = 0; i < pE2->uNumCylinders; i++) {
111 if(pE1->cylinders[i].dMeasuredCompression !=
112 pE2->cylinders[i].dMeasuredCompression) {
113 return false;
114 }
115 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200116#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700117
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700118 if(UsefulBuf_Compare(pE1->Manufacturer, pE2->Manufacturer)) {
119 return false;
120 }
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700121
122 return true;
123}
124
125
Laurence Lundbladeda319282020-07-06 23:04:58 -0700126/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700127 * @brief Encode an initialized CarEngine data structure in CBOR.
128 *
129 * @param[in] pEngine The data structure to encode.
130 * @param[in] Buffer Pointer and length of buffer to output to.
131 *
132 * @return The pointer and length of the encoded CBOR or
133 * @ref NULLUsefulBufC on error.
134 *
Laurence Lundblade88ba5662024-11-03 02:10:24 -0800135 * This encodes the input structure @c pEngine as a CBOR map of
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700136 * label-value pairs. An array of float is one of the items in the
137 * map.
138 *
139 * This uses the UsefulBuf convention of passing in a non-const empty
140 * buffer to be filled in and returning a filled in const buffer. The
141 * buffer to write into is given as a pointer and length in a
142 * UsefulBuf. The buffer returned with the encoded CBOR is a
143 * UsefulBufC also a pointer and length. In this implementation the
144 * pointer to the returned data is exactly the same as that of the
145 * empty buffer. The returned length will be smaller than or equal to
146 * that of the empty buffer. This gives correct const-ness for the
147 * buffer passed in and the data returned.
148 *
149 * @c Buffer must be big enough to hold the output. If it is not @ref
150 * NULLUsefulBufC will be returned. @ref NULLUsefulBufC will be
151 * returned for any other encoding errors.
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700152 *
153 * This can be called with @c Buffer set to @ref SizeCalculateUsefulBuf
154 * in which case the size of the encoded engine will be calculated,
155 * but no actual encoded CBOR will be output. The calculated size is
156 * in @c .len of the returned @ref UsefulBufC.
Laurence Lundbladeda319282020-07-06 23:04:58 -0700157 */
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700158UsefulBufC EncodeEngine(const CarEngine *pEngine, UsefulBuf Buffer)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700159{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700160 /* Set up the encoding context with the output buffer */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700161 QCBOREncodeContext EncodeCtx;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700162 QCBOREncode_Init(&EncodeCtx, Buffer);
Laurence Lundblade06c83042020-07-03 23:04:53 -0700163
Laurence Lundbladec4474172020-10-02 14:52:16 -0700164 /* Proceed to output all the items, letting the internal error
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700165 * tracking do its work */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700166 QCBOREncode_OpenMap(&EncodeCtx);
Laurence Lundblade0f143652024-10-06 11:06:19 -0700167 QCBOREncode_AddTextToMapSZ(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
168 QCBOREncode_AddInt64ToMapSZ(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
169 QCBOREncode_AddInt64ToMapSZ(&EncodeCtx, "Displacement", pEngine->uDisplacement);
170 QCBOREncode_AddInt64ToMapSZ(&EncodeCtx, "Horsepower", pEngine->uHorsePower);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200171#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade0f143652024-10-06 11:06:19 -0700172 QCBOREncode_AddDoubleToMapSZ(&EncodeCtx, "DesignedCompression", pEngine->dDesignedCompresion);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200173#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade0f143652024-10-06 11:06:19 -0700174 QCBOREncode_OpenArrayInMapSZ(&EncodeCtx, "Cylinders");
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200175#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade06c83042020-07-03 23:04:53 -0700176 for(int64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700177 QCBOREncode_AddDouble(&EncodeCtx,
178 pEngine->cylinders[i].dMeasuredCompression);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700179 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200180#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700181 QCBOREncode_CloseArray(&EncodeCtx);
Laurence Lundblade0f143652024-10-06 11:06:19 -0700182 QCBOREncode_AddBoolToMapSZ(&EncodeCtx, "Turbo", pEngine->bTurboCharged);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700183 QCBOREncode_CloseMap(&EncodeCtx);
184
Laurence Lundblade06c83042020-07-03 23:04:53 -0700185 /* Get the pointer and length of the encoded output. If there was
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700186 * any encoding error, it will be returned here */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700187 UsefulBufC EncodedCBOR;
188 QCBORError uErr;
189 uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
190 if(uErr != QCBOR_SUCCESS) {
Laurence Lundbladec4474172020-10-02 14:52:16 -0700191 return NULLUsefulBufC;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700192 } else {
193 return EncodedCBOR;
194 }
195}
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700196
197
Laurence Lundbladeda319282020-07-06 23:04:58 -0700198/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700199 * Error results when decoding an Engine data structure.
Laurence Lundbladeda319282020-07-06 23:04:58 -0700200 */
Laurence Lundblade06c83042020-07-03 23:04:53 -0700201typedef enum {
202 EngineSuccess,
203 CBORNotWellFormed,
204 TooManyCylinders,
205 EngineProtocolerror,
206 WrongNumberOfCylinders
207} EngineDecodeErrors;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700208
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700209
Laurence Lundbladeda319282020-07-06 23:04:58 -0700210/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700211 * Convert @ref QCBORError to @ref EngineDecodeErrors.
Laurence Lundbladeda319282020-07-06 23:04:58 -0700212 */
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700213static EngineDecodeErrors ConvertError(QCBORError uErr)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700214{
Laurence Lundblade06c83042020-07-03 23:04:53 -0700215 EngineDecodeErrors uReturn;
216
217 switch(uErr)
218 {
219 case QCBOR_SUCCESS:
220 uReturn = EngineSuccess;
221 break;
222
223 case QCBOR_ERR_HIT_END:
224 uReturn = CBORNotWellFormed;
225 break;
226
227 default:
228 uReturn = EngineProtocolerror;
229 break;
230 }
231
232 return uReturn;
233}
234
235
Laurence Lundbladeda319282020-07-06 23:04:58 -0700236/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700237 * @brief Simplest engine decode using spiffy decode features.
238 *
239 * @param[in] EncodedEngine Pointer and length of CBOR-encoded engine.
240 * @param[out] pE The structure filled in from the decoding.
241 *
242 * @return The decode error or success.
243 *
244 * This decodes the CBOR into the engine structure.
245 *
246 * As QCBOR automatically supports both definite and indefinite maps
247 * and arrays, this will decode either.
248 *
249 * This uses QCBOR's spiffy decode functions, so the implementation is
250 * simple and closely parallels the encode implementation in
251 * EncodeEngineDefiniteLength().
252 *
253 * Another way to decode without using spiffy decode functions is to
254 * use QCBORDecode_GetNext() to traverse the whole tree. This
255 * requires a more complex implementation, but is faster and will pull
256 * in less code from the CBOR library. The speed advantage is likely
257 * of consequence when decoding much much larger CBOR on slow small
258 * CPUs.
259 *
260 * A middle way is to use the spiffy decode
261 * QCBORDecode_GetItemsInMap(). The implementation has middle
262 * complexity and uses less CPU.
Laurence Lundblade06c83042020-07-03 23:04:53 -0700263 */
Laurence Lundblade67257dc2020-07-27 03:33:37 -0700264EngineDecodeErrors DecodeEngineSpiffy(UsefulBufC EncodedEngine, CarEngine *pE)
Laurence Lundblade06c83042020-07-03 23:04:53 -0700265{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700266 QCBORError uErr;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700267 QCBORDecodeContext DecodeCtx;
268
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700269 /* Let QCBORDecode internal error tracking do its work. */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700270 QCBORDecode_Init(&DecodeCtx, EncodedEngine, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade6545d1b2020-10-14 11:13:13 -0700271 QCBORDecode_EnterMap(&DecodeCtx, NULL);
Laurence Lundblade323f8a92020-09-06 19:43:09 -0700272 QCBORDecode_GetTextStringInMapSZ(&DecodeCtx, "Manufacturer", &(pE->Manufacturer));
Laurence Lundblade06c83042020-07-03 23:04:53 -0700273 QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Displacement", &(pE->uDisplacement));
274 QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Horsepower", &(pE->uHorsePower));
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200275#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700276 QCBORDecode_GetDoubleInMapSZ(&DecodeCtx, "DesignedCompression", &(pE->dDesignedCompresion));
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200277#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeda319282020-07-06 23:04:58 -0700278 QCBORDecode_GetBoolInMapSZ(&DecodeCtx, "Turbo", &(pE->bTurboCharged));
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700279
Laurence Lundblade06c83042020-07-03 23:04:53 -0700280 QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "NumCylinders", &(pE->uNumCylinders));
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700281
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700282 /* Check the internal tracked error now before going on to
283 * reference any of the decoded data, particularly
284 * pE->uNumCylinders */
Laurence Lundblade06c83042020-07-03 23:04:53 -0700285 uErr = QCBORDecode_GetError(&DecodeCtx);
286 if(uErr != QCBOR_SUCCESS) {
287 goto Done;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700288 }
289
290 if(pE->uNumCylinders > MAX_CYLINDERS) {
Laurence Lundblade06c83042020-07-03 23:04:53 -0700291 return TooManyCylinders;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700292 }
293
294 QCBORDecode_EnterArrayFromMapSZ(&DecodeCtx, "Cylinders");
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200295#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700296 for(int64_t i = 0; i < pE->uNumCylinders; i++) {
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700297 QCBORDecode_GetDouble(&DecodeCtx,
298 &(pE->cylinders[i].dMeasuredCompression));
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700299 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200300#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700301 QCBORDecode_ExitArray(&DecodeCtx);
302 QCBORDecode_ExitMap(&DecodeCtx);
303
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700304 /* Catch further decoding error here */
Laurence Lundblade06c83042020-07-03 23:04:53 -0700305 uErr = QCBORDecode_Finish(&DecodeCtx);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700306
Laurence Lundblade06c83042020-07-03 23:04:53 -0700307Done:
308 return ConvertError(uErr);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700309}
310
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700311
Maxim Zhukovd538f0a2022-12-20 20:40:38 +0300312int32_t RunQCborExample(void)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700313{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700314 CarEngine InitialEngine;
315 CarEngine DecodedEngine;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700316
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800317 /* For every buffer used by QCBOR a pointer and a length are always
318 * carried in a UsefulBuf. This is a secure coding and hygene
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700319 * practice to help make sure code never runs off the end of a
320 * buffer.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800321 *
322 * UsefulBuf structures are passed as a stack parameter to make the
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700323 * code prettier. The object code generated isn't much different
324 * from passing a pointer parameter and a length parameter.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800325 *
326 * This macro is equivalent to:
327 * uint8_t __pBufEngineBuffer[300];
328 * UsefulBuf EngineBuffer = {__pBufEngineBuffer, 300};
329 */
330 UsefulBuf_MAKE_STACK_UB( EngineBuffer, 300);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700331
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800332 /* The pointer in UsefulBuf is not const and used for representing
333 * a buffer to be written to. For UsefulbufC, the pointer is const
334 * and is used to represent a buffer that has been written to.
335 */
336 UsefulBufC EncodedEngine;
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800337 EngineDecodeErrors uErr;
Laurence Lundblade1818e632020-07-26 04:14:08 -0700338
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700339 /* Initialize the structure with some values. */
340 EngineInit(&InitialEngine);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700341
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700342 /* Encode the engine structure. */
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700343 EncodedEngine = EncodeEngine(&InitialEngine, EngineBuffer);
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700344 if(UsefulBuf_IsNULLC(EncodedEngine)) {
345 printf("Engine encode failed\n");
346 goto Done;
347 }
348 printf("Example: Definite Length Engine Encoded in %zu bytes\n",
349 EncodedEngine.len);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700350
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700351 /* Decode the CBOR */
Laurence Lundbladec4474172020-10-02 14:52:16 -0700352 uErr = DecodeEngineSpiffy(EncodedEngine, &DecodedEngine);
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700353 printf("Example: Spiffy Engine Decode Result: %d\n", uErr);
354 if(uErr) {
355 goto Done;
Laurence Lundbladec4474172020-10-02 14:52:16 -0700356 }
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700357
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700358 /* Check the results */
359 if(!EngineCompare(&InitialEngine, &DecodedEngine)) {
360 printf("Example: Spiffy Engine Decode comparison fail\n");
Laurence Lundbladec4474172020-10-02 14:52:16 -0700361 }
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700362
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700363
364 /* Further example of how to calculate the encoded size, then allocate */
365 UsefulBufC EncodedEngineSize;
366 EncodedEngineSize = EncodeEngine(&InitialEngine, SizeCalculateUsefulBuf);
367 if(UsefulBuf_IsNULLC(EncodedEngine)) {
368 printf("Engine encode size calculation failed\n");
369 goto Done;
370 }
371 (void)EncodedEngineSize; /* Supress unsed variable warning */
372 /* Here malloc could be called to allocate a buffer. Then
373 * EncodeEngine() can be called a second time to actually
374 * encode. (The actual code is not live here to avoid a
375 * dependency on malloc()).
376 * UsefulBuf MallocedBuffer;
377 * MallocedBuffer.len = EncodedEngineSize.len;
378 * MallocedBuffer.ptr = malloc(EncodedEngineSize.len);
379 * EncodedEngine = EncodeEngine(&InitialEngine, MallocedBuffer);
380 */
381
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700382Done:
Laurence Lundbladec4474172020-10-02 14:52:16 -0700383 printf("\n");
384
385 return 0;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700386}