blob: 02345ecf8a97e6ab28d5e8a54c3cdbfe7e12dd64 [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 Lundbladec4474172020-10-02 14:52:16 -07009 See BSD-3-Clause license in README.md
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"
16#include "qcbor/qcbor_encode.h"
17#include "qcbor/qcbor_decode.h"
Laurence Lundblade67257dc2020-07-27 03:33:37 -070018#include "qcbor/qcbor_spiffy_decode.h"
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070019
Laurence Lundbladec4474172020-10-02 14:52:16 -070020
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070021/**
22 * This is a simple example of encoding and decoding some CBOR from
23 * and to a C structure.
24 *
25 * This also includes a comparison between the original structure
26 * and the one decoded from the CBOR to confirm correctness.
27 */
28
29
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070030#define MAX_CYLINDERS 16
31
Laurence Lundbladeda319282020-07-06 23:04:58 -070032/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070033 * The data structure representing a car engine that is encoded and
34 * decoded in this example.
Laurence Lundbladeda319282020-07-06 23:04:58 -070035 */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070036typedef struct
37{
Laurence Lundbladec4474172020-10-02 14:52:16 -070038 UsefulBufC Manufacturer;
39 int64_t uDisplacement;
40 int64_t uHorsePower;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020041#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladec4474172020-10-02 14:52:16 -070042 double dDesignedCompresion;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020043#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladec4474172020-10-02 14:52:16 -070044 int64_t uNumCylinders;
45 bool bTurboCharged;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020046#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladec4474172020-10-02 14:52:16 -070047 struct {
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070048 double dMeasuredCompression;
Laurence Lundbladec4474172020-10-02 14:52:16 -070049 } cylinders[MAX_CYLINDERS];
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020050#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeda319282020-07-06 23:04:58 -070051} CarEngine;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070052
53
Laurence Lundbladeda319282020-07-06 23:04:58 -070054/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070055 * @brief Initialize the Engine data structure with values to encode.
56 *
57 * @param[out] pE The Engine structure to fill in
Laurence Lundbladeda319282020-07-06 23:04:58 -070058 */
59void EngineInit(CarEngine *pE)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070060{
Laurence Lundbladec4474172020-10-02 14:52:16 -070061 pE->Manufacturer = UsefulBuf_FROM_SZ_LITERAL("Porsche");
62 pE->uDisplacement = 3296;
63 pE->uHorsePower = 210;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020064#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladec4474172020-10-02 14:52:16 -070065 pE->dDesignedCompresion = 9.1;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020066#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladec4474172020-10-02 14:52:16 -070067 pE->uNumCylinders = 6;
68 pE->bTurboCharged = false;
69
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020070#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070071 pE->cylinders[0].dMeasuredCompression = 9.0;
72 pE->cylinders[1].dMeasuredCompression = 9.2;
73 pE->cylinders[2].dMeasuredCompression = 8.9;
74 pE->cylinders[3].dMeasuredCompression = 8.9;
75 pE->cylinders[4].dMeasuredCompression = 9.1;
76 pE->cylinders[5].dMeasuredCompression = 9.0;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +020077#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -070078}
79
80
Laurence Lundbladeda319282020-07-06 23:04:58 -070081/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070082 * @brief Compare two Engine structure for equality.
83 *
84 * @param[in] pE1 First Engine to compare.
85 * @param[in] pE2 Second Engine to compare.
86 *
87 * @retval Return @c true if the two Engine data structures are exactly the
88 * same.
Laurence Lundbladeda319282020-07-06 23:04:58 -070089 */
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070090static bool EngineCompare(const CarEngine *pE1, const CarEngine *pE2)
Laurence Lundbladee6bbf552020-07-05 22:57:57 -070091{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -070092 if(pE1->uNumCylinders != pE2->uNumCylinders) {
93 return false;
94 }
95 if(pE1->bTurboCharged != pE2->bTurboCharged) {
96 return false;
97 }
98 if(pE1->uDisplacement != pE2->uDisplacement) {
99 return false;
100 }
101 if(pE1->uHorsePower != pE2->uHorsePower) {
102 return false;
103 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200104#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700105 if(pE1->dDesignedCompresion != pE2->dDesignedCompresion) {
106 return false;
107 }
108 for(int64_t i = 0; i < pE2->uNumCylinders; i++) {
109 if(pE1->cylinders[i].dMeasuredCompression !=
110 pE2->cylinders[i].dMeasuredCompression) {
111 return false;
112 }
113 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200114#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700115
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700116 if(UsefulBuf_Compare(pE1->Manufacturer, pE2->Manufacturer)) {
117 return false;
118 }
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700119
120 return true;
121}
122
123
Laurence Lundbladeda319282020-07-06 23:04:58 -0700124/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700125 * @brief Encode an initialized CarEngine data structure in CBOR.
126 *
127 * @param[in] pEngine The data structure to encode.
128 * @param[in] Buffer Pointer and length of buffer to output to.
129 *
130 * @return The pointer and length of the encoded CBOR or
131 * @ref NULLUsefulBufC on error.
132 *
133 * This encodes the input structure \c pEngine as a CBOR map of
134 * label-value pairs. An array of float is one of the items in the
135 * map.
136 *
137 * This uses the UsefulBuf convention of passing in a non-const empty
138 * buffer to be filled in and returning a filled in const buffer. The
139 * buffer to write into is given as a pointer and length in a
140 * UsefulBuf. The buffer returned with the encoded CBOR is a
141 * UsefulBufC also a pointer and length. In this implementation the
142 * pointer to the returned data is exactly the same as that of the
143 * empty buffer. The returned length will be smaller than or equal to
144 * that of the empty buffer. This gives correct const-ness for the
145 * buffer passed in and the data returned.
146 *
147 * @c Buffer must be big enough to hold the output. If it is not @ref
148 * NULLUsefulBufC will be returned. @ref NULLUsefulBufC will be
149 * returned for any other encoding errors.
Laurence Lundbladeda319282020-07-06 23:04:58 -0700150 */
Laurence Lundbladec4474172020-10-02 14:52:16 -0700151UsefulBufC EncodeEngineDefiniteLength(const CarEngine *pEngine, UsefulBuf Buffer)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700152{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700153 /* Set up the encoding context with the output buffer */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700154 QCBOREncodeContext EncodeCtx;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700155 QCBOREncode_Init(&EncodeCtx, Buffer);
Laurence Lundblade06c83042020-07-03 23:04:53 -0700156
Laurence Lundbladec4474172020-10-02 14:52:16 -0700157 /* Proceed to output all the items, letting the internal error
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700158 * tracking do its work */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700159 QCBOREncode_OpenMap(&EncodeCtx);
160 QCBOREncode_AddTextToMap(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
Laurence Lundblade06c83042020-07-03 23:04:53 -0700161 QCBOREncode_AddInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
162 QCBOREncode_AddInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
163 QCBOREncode_AddInt64ToMap(&EncodeCtx, "Horsepower", pEngine->uHorsePower);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200164#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700165 QCBOREncode_AddDoubleToMap(&EncodeCtx, "DesignedCompression", pEngine->dDesignedCompresion);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200166#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700167 QCBOREncode_OpenArrayInMap(&EncodeCtx, "Cylinders");
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200168#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade06c83042020-07-03 23:04:53 -0700169 for(int64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700170 QCBOREncode_AddDouble(&EncodeCtx,
171 pEngine->cylinders[i].dMeasuredCompression);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700172 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200173#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700174 QCBOREncode_CloseArray(&EncodeCtx);
Laurence Lundbladeda319282020-07-06 23:04:58 -0700175 QCBOREncode_AddBoolToMap(&EncodeCtx, "Turbo", pEngine->bTurboCharged);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700176 QCBOREncode_CloseMap(&EncodeCtx);
177
Laurence Lundblade06c83042020-07-03 23:04:53 -0700178 /* Get the pointer and length of the encoded output. If there was
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700179 * any encoding error, it will be returned here */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700180 UsefulBufC EncodedCBOR;
181 QCBORError uErr;
182 uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
183 if(uErr != QCBOR_SUCCESS) {
Laurence Lundbladec4474172020-10-02 14:52:16 -0700184 return NULLUsefulBufC;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700185 } else {
186 return EncodedCBOR;
187 }
188}
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700189
190
Laurence Lundbladeda319282020-07-06 23:04:58 -0700191/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700192 * Error results when decoding an Engine data structure.
Laurence Lundbladeda319282020-07-06 23:04:58 -0700193 */
Laurence Lundblade06c83042020-07-03 23:04:53 -0700194typedef enum {
195 EngineSuccess,
196 CBORNotWellFormed,
197 TooManyCylinders,
198 EngineProtocolerror,
199 WrongNumberOfCylinders
200} EngineDecodeErrors;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700201
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700202
Laurence Lundbladeda319282020-07-06 23:04:58 -0700203/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700204 * Convert @ref QCBORError to @ref EngineDecodeErrors.
Laurence Lundbladeda319282020-07-06 23:04:58 -0700205 */
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700206static EngineDecodeErrors ConvertError(QCBORError uErr)
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700207{
Laurence Lundblade06c83042020-07-03 23:04:53 -0700208 EngineDecodeErrors uReturn;
209
210 switch(uErr)
211 {
212 case QCBOR_SUCCESS:
213 uReturn = EngineSuccess;
214 break;
215
216 case QCBOR_ERR_HIT_END:
217 uReturn = CBORNotWellFormed;
218 break;
219
220 default:
221 uReturn = EngineProtocolerror;
222 break;
223 }
224
225 return uReturn;
226}
227
228
Laurence Lundbladeda319282020-07-06 23:04:58 -0700229/**
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700230 * @brief Simplest engine decode using spiffy decode features.
231 *
232 * @param[in] EncodedEngine Pointer and length of CBOR-encoded engine.
233 * @param[out] pE The structure filled in from the decoding.
234 *
235 * @return The decode error or success.
236 *
237 * This decodes the CBOR into the engine structure.
238 *
239 * As QCBOR automatically supports both definite and indefinite maps
240 * and arrays, this will decode either.
241 *
242 * This uses QCBOR's spiffy decode functions, so the implementation is
243 * simple and closely parallels the encode implementation in
244 * EncodeEngineDefiniteLength().
245 *
246 * Another way to decode without using spiffy decode functions is to
247 * use QCBORDecode_GetNext() to traverse the whole tree. This
248 * requires a more complex implementation, but is faster and will pull
249 * in less code from the CBOR library. The speed advantage is likely
250 * of consequence when decoding much much larger CBOR on slow small
251 * CPUs.
252 *
253 * A middle way is to use the spiffy decode
254 * QCBORDecode_GetItemsInMap(). The implementation has middle
255 * complexity and uses less CPU.
Laurence Lundblade06c83042020-07-03 23:04:53 -0700256 */
Laurence Lundblade67257dc2020-07-27 03:33:37 -0700257EngineDecodeErrors DecodeEngineSpiffy(UsefulBufC EncodedEngine, CarEngine *pE)
Laurence Lundblade06c83042020-07-03 23:04:53 -0700258{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700259 QCBORError uErr;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700260 QCBORDecodeContext DecodeCtx;
261
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700262 /* Let QCBORDecode internal error tracking do its work. */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700263 QCBORDecode_Init(&DecodeCtx, EncodedEngine, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade6545d1b2020-10-14 11:13:13 -0700264 QCBORDecode_EnterMap(&DecodeCtx, NULL);
Laurence Lundblade323f8a92020-09-06 19:43:09 -0700265 QCBORDecode_GetTextStringInMapSZ(&DecodeCtx, "Manufacturer", &(pE->Manufacturer));
Laurence Lundblade06c83042020-07-03 23:04:53 -0700266 QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Displacement", &(pE->uDisplacement));
267 QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Horsepower", &(pE->uHorsePower));
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200268#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700269 QCBORDecode_GetDoubleInMapSZ(&DecodeCtx, "DesignedCompression", &(pE->dDesignedCompresion));
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200270#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeda319282020-07-06 23:04:58 -0700271 QCBORDecode_GetBoolInMapSZ(&DecodeCtx, "Turbo", &(pE->bTurboCharged));
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700272
Laurence Lundblade06c83042020-07-03 23:04:53 -0700273 QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "NumCylinders", &(pE->uNumCylinders));
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700274
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700275 /* Check the internal tracked error now before going on to
276 * reference any of the decoded data, particularly
277 * pE->uNumCylinders */
Laurence Lundblade06c83042020-07-03 23:04:53 -0700278 uErr = QCBORDecode_GetError(&DecodeCtx);
279 if(uErr != QCBOR_SUCCESS) {
280 goto Done;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700281 }
282
283 if(pE->uNumCylinders > MAX_CYLINDERS) {
Laurence Lundblade06c83042020-07-03 23:04:53 -0700284 return TooManyCylinders;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700285 }
286
287 QCBORDecode_EnterArrayFromMapSZ(&DecodeCtx, "Cylinders");
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200288#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700289 for(int64_t i = 0; i < pE->uNumCylinders; i++) {
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700290 QCBORDecode_GetDouble(&DecodeCtx,
291 &(pE->cylinders[i].dMeasuredCompression));
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700292 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200293#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700294 QCBORDecode_ExitArray(&DecodeCtx);
295 QCBORDecode_ExitMap(&DecodeCtx);
296
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700297 /* Catch further decoding error here */
Laurence Lundblade06c83042020-07-03 23:04:53 -0700298 uErr = QCBORDecode_Finish(&DecodeCtx);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700299
Laurence Lundblade06c83042020-07-03 23:04:53 -0700300Done:
301 return ConvertError(uErr);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700302}
303
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700304
Laurence Lundblade1818e632020-07-26 04:14:08 -0700305int32_t RunQCborExample()
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700306{
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700307 CarEngine InitialEngine;
308 CarEngine DecodedEngine;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700309
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800310 /* For every buffer used by QCBOR a pointer and a length are always
311 * carried in a UsefulBuf. This is a secure coding and hygene
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700312 * practice to help make sure code never runs off the end of a
313 * buffer.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800314 *
315 * UsefulBuf structures are passed as a stack parameter to make the
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700316 * code prettier. The object code generated isn't much different
317 * from passing a pointer parameter and a length parameter.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800318 *
319 * This macro is equivalent to:
320 * uint8_t __pBufEngineBuffer[300];
321 * UsefulBuf EngineBuffer = {__pBufEngineBuffer, 300};
322 */
323 UsefulBuf_MAKE_STACK_UB( EngineBuffer, 300);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700324
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800325 /* The pointer in UsefulBuf is not const and used for representing
326 * a buffer to be written to. For UsefulbufC, the pointer is const
327 * and is used to represent a buffer that has been written to.
328 */
329 UsefulBufC EncodedEngine;
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800330 EngineDecodeErrors uErr;
Laurence Lundblade1818e632020-07-26 04:14:08 -0700331
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700332 /* Initialize the structure with some values. */
333 EngineInit(&InitialEngine);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700334
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700335 /* Encode the engine structure. */
336 EncodedEngine = EncodeEngineDefiniteLength(&InitialEngine, EngineBuffer);
337 if(UsefulBuf_IsNULLC(EncodedEngine)) {
338 printf("Engine encode failed\n");
339 goto Done;
340 }
341 printf("Example: Definite Length Engine Encoded in %zu bytes\n",
342 EncodedEngine.len);
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700343
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700344 /* Decode the CBOR */
Laurence Lundbladec4474172020-10-02 14:52:16 -0700345 uErr = DecodeEngineSpiffy(EncodedEngine, &DecodedEngine);
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700346 printf("Example: Spiffy Engine Decode Result: %d\n", uErr);
347 if(uErr) {
348 goto Done;
Laurence Lundbladec4474172020-10-02 14:52:16 -0700349 }
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700350
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700351 /* Check the results */
352 if(!EngineCompare(&InitialEngine, &DecodedEngine)) {
353 printf("Example: Spiffy Engine Decode comparison fail\n");
Laurence Lundbladec4474172020-10-02 14:52:16 -0700354 }
Laurence Lundbladee6bbf552020-07-05 22:57:57 -0700355
Laurence Lundblade5c91eb32021-04-03 23:56:54 -0700356Done:
Laurence Lundbladec4474172020-10-02 14:52:16 -0700357 printf("\n");
358
359 return 0;
Laurence Lundbladed4cd7232020-07-03 19:30:48 -0700360}