blob: 13e87e32b738452ecb663b5463c2a9ab8e920bd3 [file] [log] [blame]
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001/*==============================================================================
Laurence Lundbladed92a6162018-11-01 11:38:35 +07002 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladea691a612024-02-27 02:29:01 -07003 Copyright (c) 2018-2024, Laurence Lundblade.
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02004 Copyright (c) 2021, Arm Limited.
Laurence Lundbladed92a6162018-11-01 11:38:35 +07005 All rights reserved.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -08006
Laurence Lundblade0dbc9172018-11-01 14:17:21 +07007Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are
9met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following
14 disclaimer in the documentation and/or other materials provided
15 with the distribution.
16 * Neither the name of The Linux Foundation nor the names of its
17 contributors, nor the name "Laurence Lundblade" may be used to
18 endorse or promote products derived from this software without
19 specific prior written permission.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080020
Laurence Lundblade0dbc9172018-11-01 14:17:21 +070021THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Laurence Lundbladeee851742020-01-08 08:37:05 -080032 =============================================================================*/
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053033
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080034#include "UsefulBuf.h"
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080035
36
Laurence Lundblade8ece3732021-09-21 21:47:23 -070037/* This calls the main methods to add stuff to a UsefulOutBuf.
Paul Liétarc6cfa332022-07-26 19:24:01 +010038 * The result in the UsefulOutBuf is "heffalump unbounce bluster hunny bear"
Laurence Lundblade8ece3732021-09-21 21:47:23 -070039 */
40const char *AddStuffToUOB(UsefulOutBuf *pUOB)
41{
42 const char *szReturn = NULL;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080043
Laurence Lundblade8ece3732021-09-21 21:47:23 -070044 if(!UsefulOutBuf_AtStart(pUOB)) {
45 szReturn = "Not at start";
46 goto Done;
47 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080048
Laurence Lundblade8ece3732021-09-21 21:47:23 -070049 /* Put 7 bytes at beginning of buf */
50 UsefulOutBuf_AppendData(pUOB, "bluster", 7);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080051
Laurence Lundblade8ece3732021-09-21 21:47:23 -070052 if(UsefulOutBuf_AtStart(pUOB)) {
53 szReturn = "At start";
54 goto Done;
55 }
56
57 /* add a space to end */
58 UsefulOutBuf_AppendByte(pUOB, ' ');
59
Laurence Lundblade5a6fec52022-12-25 11:28:43 -070060 /* Add an empty string */
61 UsefulOutBuf_AppendUsefulBuf(pUOB, NULLUsefulBufC);
62
63 /* Add a zero length string (valid pointer, 0 length) */
64 UsefulOutBuf_AppendData(pUOB, "xxx", 0);
65
Paul Liétarc6cfa332022-07-26 19:24:01 +010066 /* Add 6 bytes to the end */
67 UsefulBufC UBC = {"hunny ", 6};
Laurence Lundblade8ece3732021-09-21 21:47:23 -070068 UsefulOutBuf_AppendUsefulBuf(pUOB, UBC);
69
70 /* Insert 9 bytes at the beginning, slide the previous stuff right */
71 UsefulOutBuf_InsertData(pUOB, "heffalump", 9, 0);
72 UsefulOutBuf_InsertByte(pUOB, ' ', 9);
73
74 /* Put 9 bytes in at position 10 -- just after "heffalump " */
75 UsefulBufC UBC2 = {"unbounce ", 9};
76 UsefulOutBuf_InsertUsefulBuf(pUOB, UBC2, 10);
77
Paul Liétarc6cfa332022-07-26 19:24:01 +010078 /* Add 4 bytes to the end, by accessing the buffer directly and then advancing it */
79 UsefulBuf UB = UsefulOutBuf_GetOutPlace(pUOB);
80 if (!UsefulBuf_IsNULL(UB)) {
81 memcpy(UB.ptr, "bear", UB.len < 4 ? UB.len : 4);
82 }
83 UsefulOutBuf_Advance(pUOB, 4);
84
Laurence Lundblade8ece3732021-09-21 21:47:23 -070085Done:
86 return szReturn;
87}
88
89
90/* Basic exercise of a UsefulOutBuf
91 *
92 * Call all the main public functions.
93 *
94 * Binary compare the result to the expected.
95 *
96 * There is nothing adversarial in this test
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080097 */
Laurence Lundbladeb9702452021-03-08 21:02:57 -080098const char * UOBTest_NonAdversarial(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080099{
100 const char *szReturn = NULL;
101
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700102 UsefulBuf_MAKE_STACK_UB(outbuf, 50);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800103
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800104 UsefulOutBuf UOB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800105
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530106 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800107
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700108 szReturn = AddStuffToUOB(&UOB);
109 if(szReturn) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800110 goto Done;
111 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800112
Paul Liétarc6cfa332022-07-26 19:24:01 +0100113 const UsefulBufC Expected = UsefulBuf_FROM_SZ_LITERAL("heffalump unbounce bluster hunny bear");
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800114
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530115 UsefulBufC U = UsefulOutBuf_OutUBuf(&UOB);
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700116 if(UsefulBuf_IsNULLC(U) ||
117 UsefulBuf_Compare(Expected, U) ||
118 UsefulOutBuf_GetError(&UOB)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800119 szReturn = "OutUBuf";
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700120 goto Done;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800121 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800122
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530123 UsefulBuf_MAKE_STACK_UB(buf, 50);
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700124 UsefulBufC Out = UsefulOutBuf_CopyOut(&UOB, buf);
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800125 if(UsefulBuf_IsNULLC(Out) || UsefulBuf_Compare(Expected, Out)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800126 szReturn = "CopyOut";
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700127 goto Done;
128 }
129
130 /* Now test the size calculation mode */
131 UsefulOutBuf_Init(&UOB, SizeCalculateUsefulBuf);
132
133 szReturn = AddStuffToUOB(&UOB);
134 if(szReturn) {
135 goto Done;
136 }
137
138 U = UsefulOutBuf_OutUBuf(&UOB);
139 if(U.len != Expected.len || U.ptr != NULL) {
140 szReturn = "size calculation failed";
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800141 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800142
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800143Done:
144 return szReturn;
145}
146
147
148/*
149 Append test utility.
150 pUOB is the buffer to append too
151 num is the amount to append
152 expected is the expected return code, 0 or 1
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800153
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800154 returns 0 if test passed
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800155
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800156 */
157static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected)
158{
159 //reset
160 UsefulOutBuf_Reset(pUOB);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800161
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800162 // check status first
163 if(UsefulOutBuf_GetError(pUOB))
164 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800165
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800166 // append the bytes
167 UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800168
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800169 // check error status after
170 if(UsefulOutBuf_GetError(pUOB) != expected)
171 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800172
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800173 return 0;
174}
175
176
177/*
178 Same as append, but takes a position param too
179 */
180static int InsertTest(UsefulOutBuf *pUOB, size_t num, size_t pos, int expected)
181{
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530182 // reset
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800183 UsefulOutBuf_Reset(pUOB);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800184
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800185 // check
186 if(UsefulOutBuf_GetError(pUOB))
187 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800188
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800189 UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800190
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800191 if(UsefulOutBuf_GetError(pUOB) != expected)
192 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800193
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800194 return 0;
195}
196
197
198/*
199 Boundary conditions to test
200 - around 0
201 - around the buffer size
202 - around MAX size_t
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800203
204
Laurence Lundbladeee851742020-01-08 08:37:05 -0800205 Test these for the buffer size and the cursor, the insert amount, the
206 append amount and the insert position
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800207
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800208 */
209
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800210const char *UOBTest_BoundaryConditionsTest(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800211{
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700212 UsefulBuf_MAKE_STACK_UB(outbuf, 2);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800213
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800214 UsefulOutBuf UOB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800215
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530216 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800217
218 // append 0 byte to a 2 byte buffer --> success
219 if(AppendTest(&UOB, 0, 0))
220 return "Append 0 bytes failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800221
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800222 // append 1 byte to a 2 byte buffer --> success
223 if(AppendTest(&UOB, 1, 0))
224 return "Append of 1 byte failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800225
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800226 // append 2 byte to a 2 byte buffer --> success
227 if(AppendTest(&UOB, 2, 0))
228 return "Append to fill buffer failed";
229
230 // append 3 bytes to a 2 byte buffer --> failure
231 if(AppendTest(&UOB, 3, 1))
232 return "Overflow of buffer not caught";
233
234 // append max size_t to a 2 byte buffer --> failure
235 if(AppendTest(&UOB, SIZE_MAX, 1))
236 return "Append of SIZE_MAX error not caught";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800237
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800238 if(InsertTest(&UOB, 1, 0, 0))
239 return "Insert 1 byte at start failed";
240
241 if(InsertTest(&UOB, 2, 0, 0))
242 return "Insert 2 bytes at start failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800243
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800244 if(InsertTest(&UOB, 3, 0, 1))
245 return "Insert overflow not caught";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800246
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800247 if(InsertTest(&UOB, 1, 1, 1))
248 return "Bad insertion point not caught";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800249
250
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530251 UsefulBuf_MAKE_STACK_UB(outBuf2,10);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800252
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530253 UsefulOutBuf_Init(&UOB, outBuf2);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800254
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800255 UsefulOutBuf_Reset(&UOB);
256 // put data in the buffer
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800257 UsefulOutBuf_AppendString(&UOB, "abc123");
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800258
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800259 UsefulOutBuf_InsertString(&UOB, "xyz*&^", 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800260
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800261 if(!UsefulOutBuf_GetError(&UOB)) {
262 return "insert with data should have failed";
263 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800264
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800265
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530266 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800267 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
268 if(UsefulOutBuf_GetError(&UOB)) {
269 return "insert in huge should have succeeded";
270 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800271
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530272 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800273 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5);
274 if(UsefulOutBuf_GetError(&UOB)) {
275 return "insert in huge should have succeeded";
276 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800277
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530278 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800279 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4);
280 if(!UsefulOutBuf_GetError(&UOB)) {
281 return "lengths near max size";
282 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800283
Laurence Lundblade30dd0ba2019-05-26 23:37:30 +0300284 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, 100});
285 if(!UsefulOutBuf_IsBufferNULL(&UOB)) {
286 return "NULL check failed";
287 }
288
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800289 return NULL;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800290}
291
292
293
294
295
296// Test function to get size and magic number check
297
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800298const char *TestBasicSanity(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800299{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530300 UsefulBuf_MAKE_STACK_UB(outbuf,10);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800301
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800302 UsefulOutBuf UOB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800303
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800304 // First -- make sure that the room left function returns the right amount
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530305 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800306
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530307 if(UsefulOutBuf_RoomLeft(&UOB) != 10)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800308 return "room left failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800309
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800310 if(!UsefulOutBuf_WillItFit(&UOB, 9)) {
311 return "it did not fit";
312 }
313
314 if(UsefulOutBuf_WillItFit(&UOB, 11)) {
315 return "it should have not fit";
316 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800317
318
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800319 // Next -- make sure that the magic number checking is working right
320 UOB.magic = 8888; // make magic bogus
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800321
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800322 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800323
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700324 if(!UsefulOutBuf_GetError(&UOB)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800325 return "magic corruption check failed";
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700326 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800327
328
329
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800330 // Next make sure that the valid data length check is working right
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530331 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800332
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530333 UOB.data_len = UOB.UB.len+1; // make size bogus
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800334
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800335 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
336 if(!UsefulOutBuf_GetError(&UOB))
337 return "valid data check failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800338
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800339 return NULL;
340}
341
342
343
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800344const char *UBMacroConversionsTest(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800345{
346 char *szFoo = "foo";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800347
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530348 UsefulBufC Foo = UsefulBuf_FromSZ(szFoo);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800349 if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
350 return "SZToUsefulBufC failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800351
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530352 UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo");
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800353 if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530354 return "UsefulBuf_FROM_SZ_LITERAL failed";
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800355
356 uint8_t pB[] = {0x42, 0x6f, 0x6f};
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530357 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800358 if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530359 return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800360
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800361 char *String = "string"; // Intentionally not const
362 UsefulBuf B = (UsefulBuf){(void *)String, strlen(String)};
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530363 UsefulBufC BC = UsefulBuf_Const(B);
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800364 if(BC.len != strlen(String) || BC.ptr != String)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800365 return "UsefulBufConst failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800366
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800367 return NULL;
368}
369
370
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800371const char *UBUtilTests(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800372{
373 UsefulBuf UB = NULLUsefulBuf;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800374
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800375 if(!UsefulBuf_IsNULL(UB)){
376 return "IsNull failed";
377 }
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530378
379 if(!UsefulBuf_IsEmpty(UB)){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800380 return "IsEmpty failed";
381 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800382
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530383 if(!UsefulBuf_IsNULLOrEmpty(UB)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800384 return "IsNULLOrEmpty failed";
385 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800386
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800387 const UsefulBufC UBC = UsefulBuf_Const(UB);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800388
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530389 if(!UsefulBuf_IsNULLC(UBC)){
390 return "IsNull const failed";
391 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800392
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530393 if(!UsefulBuf_IsEmptyC(UBC)){
394 return "IsEmptyC failed";
395 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800396
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530397 if(!UsefulBuf_IsNULLOrEmptyC(UBC)){
398 return "IsNULLOrEmptyC failed";
399 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800400
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800401 const UsefulBuf UB2 = UsefulBuf_Unconst(UBC);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530402 if(!UsefulBuf_IsEmpty(UB2)) {
403 return "Back to UB is Empty failed";
404 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800405
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800406 UB.ptr = "x"; // just some valid pointer
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800407
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800408 if(UsefulBuf_IsNULL(UB)){
409 return "IsNull failed";
410 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800411
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530412 if(!UsefulBuf_IsEmptyC(UBC)){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800413 return "IsEmpty failed";
414 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800415
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800416 // test the Unconst.
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530417 if(UsefulBuf_Unconst(UBC).ptr != NULL) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800418 return "Unconst failed";
419 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800420
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800421 // Set 100 bytes of '+'; validated a few tests later
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530422 UsefulBuf_MAKE_STACK_UB(Temp, 100);
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800423 const UsefulBufC TempC = UsefulBuf_Set(Temp, '+');
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800424
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800425 // Try to copy into a buf that is too small and see failure
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530426 UsefulBuf_MAKE_STACK_UB(Temp2, 99);
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530427 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp2, TempC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800428 return "Copy should have failed";
429 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800430
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800431 if(UsefulBuf_IsNULLC(UsefulBuf_CopyPtr(Temp2, "xx", 2))) {
432 return "CopyPtr failed";
433 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800434
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530435 UsefulBufC xxyy = UsefulBuf_CopyOffset(Temp2, 2, UsefulBuf_FROM_SZ_LITERAL("yy"));
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800436 if(UsefulBuf_IsNULLC(xxyy)) {
437 return "CopyOffset Failed";
438 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800439
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530440 if(UsefulBuf_Compare(UsefulBuf_Head(xxyy, 3), UsefulBuf_FROM_SZ_LITERAL("xxy"))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800441 return "head failed";
442 }
443
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530444 if(UsefulBuf_Compare(UsefulBuf_Tail(xxyy, 1), UsefulBuf_FROM_SZ_LITERAL("xyy"))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800445 return "tail failed";
446 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800447
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800448 if(!UsefulBuf_IsNULLC(UsefulBuf_Head(xxyy, 5))) {
449 return "head should have failed";
450 }
451
452 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(xxyy, 5))) {
453 return "tail should have failed";
454 }
Laurence Lundbladedf1c1cf2019-01-17 11:55:05 -0800455
Laurence Lundblade7412f812019-01-01 18:49:36 -0800456 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(NULLUsefulBufC, 0))) {
457 return "tail of NULLUsefulBufC is not NULLUsefulBufC";
458 }
Laurence Lundbladedf1c1cf2019-01-17 11:55:05 -0800459
Laurence Lundblade7412f812019-01-01 18:49:36 -0800460 const UsefulBufC TailResult = UsefulBuf_Tail((UsefulBufC){NULL, 100}, 99);
461 if(TailResult.ptr != NULL || TailResult.len != 1) {
462 return "tail of NULL and length incorrect";
463 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800464
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530465 if(!UsefulBuf_IsNULLC(UsefulBuf_CopyOffset(Temp2, 100, UsefulBuf_FROM_SZ_LITERAL("yy")))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800466 return "Copy Offset should have failed";
467 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800468
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800469 // Try to copy into a NULL/empty buf and see failure
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800470 const UsefulBuf UBNull = NULLUsefulBuf;
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530471 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(UBNull, TempC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800472 return "Copy to NULL should have failed";
473 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800474
475
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800476 // Try to set a NULL/empty buf; nothing should happen
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530477 UsefulBuf_Set(UBNull, '+'); // This will crash on failure
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800478
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800479 // Copy successfully to a buffer
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530480 UsefulBuf_MAKE_STACK_UB(Temp3, 101);
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530481 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp3, TempC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800482 return "Copy should not have failed";
483 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800484
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800485 static const uint8_t pExpected[] = {
486 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
487 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
488 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
489 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
490 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
491 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
492 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
493 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
494 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
495 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
496 };
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530497 UsefulBufC Expected = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpected);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800498 // This validates comparison for equality and the UsefulBuf_Set
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530499 if(UsefulBuf_Compare(Expected, TempC)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800500 return "Set / Copy / Compare failed";
501 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800502
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800503 // Compare two empties and expect success
504 if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){
505 return "Compare Empties failed";
506 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800507
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800508 // Compare with empty and expect the first to be larger
509 if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){
510 return "Compare with empty failed";
511 }
512
513
514 static const uint8_t pExpectedBigger[] = {
515 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
516 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
517 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
518 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
519 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
520 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
521 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
522 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
523 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
524 '+', '+', '+', '+', '+', '+', '+', '+', '+', ',',
525 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800526 const UsefulBufC ExpectedBigger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedBigger);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800527
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530528 // Expect -1 when the first arg is smaller
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800529 if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){
530 return "Compare with bigger";
531 }
532
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800533
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800534 static const uint8_t pExpectedSmaller[] = {
535 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
536 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
537 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
538 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
539 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
540 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
541 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
542 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
543 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
544 '+', '+', '+', '+', '+', '+', '+', '+', '+', '*',
545 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800546 const UsefulBufC ExpectedSmaller = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedSmaller);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530547 // Expect +1 when the first arg is larger
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800548 if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){
549 return "Compare with smaller";
550 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800551
552
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800553 static const uint8_t pExpectedLonger[] = {
554 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
555 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
556 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
557 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
558 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
559 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
560 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
561 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
562 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
563 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+'
564 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800565 const UsefulBufC ExpectedLonger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedLonger);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800566
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530567 // Expect -1 when the first arg is smaller
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800568 if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){
569 return "Compare with longer";
570 }
571
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800572
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800573 static const uint8_t pExpectedShorter[] = {
574 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
575 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
576 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
577 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
578 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
579 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
580 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
581 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
582 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
583 '+', '+', '+', '+', '+', '+', '+', '+', '+',
584 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800585 const UsefulBufC ExpectedShorter = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedShorter);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800586 // Expect +1 with the first arg is larger
587 if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){
588 return "Compare with shorter";
589 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800590
591
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530592 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp, NULLUsefulBufC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800593 return "Copy null/empty failed";
594 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800595
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800596 if(UsefulBuf_IsValue(ExpectedShorter, '+') != SIZE_MAX) {
597 return "IsValue failed to match all";
598 }
599
600 if(UsefulBuf_IsValue(ExpectedShorter, '-') != 0) {
601 return "IsValue should have failed right away";
602 }
603
604 if(UsefulBuf_IsValue(NULLUsefulBufC, 0x00) != 0) {
605 return "IsValue failed on NULLUsefulBufC";
606 }
607
608 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x00) != SIZE_MAX) {
609 return "IsValue failed finding 0 in one byte of 0";
610 }
611
612 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x01) != 0) {
613 return "IsValue failed not finding 1 in one byte of 0";
614 }
615
616 if(UsefulBuf_IsValue(ExpectedSmaller, '+') != ExpectedSmaller.len -1) {
617 return "IsValue failed to find final *";
618 }
619
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800620 // Look for +++++... in +++++... and find it at the beginning
621 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
622 return "Failed to find";
623 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800624
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800625 // look for ++* in ....++* and find it at the end
626 static const uint8_t pToFind[] = {'+', '+', '*'};
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800627 const UsefulBufC ToBeFound = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pToFind);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800628
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800629 if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){
630 return "Failed to find 2";
631 }
632
633 // look for ++* in ....++, and find it near the end
634 if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){
635 return "Failed to not find";
636 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800637
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800638 // Look for the whole buffer in itself and succeed.
639 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){
640 return "Failed to find 3";
641 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800642
Laurence Lundbladecf41c522021-02-20 10:19:07 -0700643
644 const uint8_t pB[] = {0x01, 0x02, 0x03};
645 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
646 // Try to map a pointer before
647 if(UsefulBuf_PointerToOffset(Boo, pB-1) != SIZE_MAX) {
648 return "Didn't error on pointer before";
649 }
650
651 // Try to map a pointer after
652 if(UsefulBuf_PointerToOffset(Boo, pB+sizeof(pB)) != SIZE_MAX) {
653 return "Didn't error on pointer after";
654 }
655
656 // Try to map a pointer inside
657 if(UsefulBuf_PointerToOffset(Boo, pB+1) != 1) {
658 return "Incorrect pointer offset";
659 }
660
661 // Try to map a pointer at the start
662 if(UsefulBuf_PointerToOffset(Boo, pB) != 0) {
663 return "Incorrect pointer offset for start";
664 }
665
666 // Try to map a pointer at the end
667 if(UsefulBuf_PointerToOffset(Boo, pB + sizeof(pB)-1) != 2) {
668 return "Incorrect pointer offset for end";
669 }
670
671 // Try to map a pointer on a NULL UB
672 if(UsefulBuf_PointerToOffset(NULLUsefulBufC, pB ) != SIZE_MAX) {
673 return "Incorrect pointer offset for start";
674 }
675
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800676 return NULL;
677}
678
679
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800680const char * UIBTest_IntegerFormat(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800681{
Laurence Lundbladecf41c522021-02-20 10:19:07 -0700682 UsefulOutBuf_MakeOnStack(UOB, 100);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800683
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800684 const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
685 const uint64_t u64 = 1984738472938472;
686 const uint16_t u16 = 40000;
687 const uint8_t u8 = 9;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200688#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800689 const float f = (float)314.15;
690 const double d = 2.1e10;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200691#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800692
693
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530694 UsefulOutBuf_AppendUint32(&UOB, u32); // Also tests UsefulOutBuf_InsertUint64 and UsefulOutBuf_GetEndPosition
695 UsefulOutBuf_AppendUint64(&UOB, u64); // Also tests UsefulOutBuf_InsertUint32
696 UsefulOutBuf_AppendUint16(&UOB, u16); // Also tests UsefulOutBuf_InsertUint16
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800697 UsefulOutBuf_AppendByte(&UOB, u8);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200698#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530699 UsefulOutBuf_AppendFloat(&UOB, f); // Also tests UsefulOutBuf_InsertFloat
700 UsefulOutBuf_AppendDouble(&UOB, d); // Also tests UsefulOutBuf_InsertDouble
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200701#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800702
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800703 const UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530704 if(UsefulBuf_IsNULLC(O))
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800705 return "Couldn't output integers";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800706
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800707 // from https://en.wikipedia.org/wiki/Endianness
708 const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D};
709 if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) {
710 return "not in network order";
711 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800712
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800713 UsefulInputBuf UIB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800714
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530715 UsefulInputBuf_Init(&UIB, O);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800716
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530717 if(UsefulInputBuf_Tell(&UIB) != 0) {
718 return "UsefulInputBuf_Tell failed";
719 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800720
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800721 if(UsefulInputBuf_GetUint32(&UIB) != u32) {
722 return "u32 out then in failed";
723 }
724 if(UsefulInputBuf_GetUint64(&UIB) != u64) {
725 return "u64 out then in failed";
726 }
727 if(UsefulInputBuf_GetUint16(&UIB) != u16) {
728 return "u16 out then in failed";
729 }
730 if(UsefulInputBuf_GetByte(&UIB) != u8) {
731 return "u8 out then in failed";
732 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200733#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800734 if(UsefulInputBuf_GetFloat(&UIB) != f) {
735 return "float out then in failed";
736 }
737 if(UsefulInputBuf_GetDouble(&UIB) != d) {
738 return "double out then in failed";
739 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200740#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800741
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800742 // Reset and go again for a few more tests
743 UsefulInputBuf_Init(&UIB, O);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800744
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800745 const UsefulBufC Four = UsefulInputBuf_GetUsefulBuf(&UIB, 4);
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800746 if(UsefulBuf_IsNULLC(Four)) {
747 return "Four is NULL";
748 }
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530749 if(UsefulBuf_Compare(Four, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedNetworkOrder))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800750 return "Four compare failed";
751 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800752
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200753#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800754 if(UsefulInputBuf_BytesUnconsumed(&UIB) != 23){
755 return "Wrong number of unconsumed bytes";
756 }
757
758 if(!UsefulInputBuf_BytesAvailable(&UIB, 23)){
759 return "Wrong number of bytes available I";
760 }
761
762 if(UsefulInputBuf_BytesAvailable(&UIB, 24)){
763 return "Wrong number of bytes available II";
764 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200765#else /* USEFULBUF_DISABLE_ALL_FLOAT */
766 if(UsefulInputBuf_BytesUnconsumed(&UIB) != 11){
767 return "Wrong number of unconsumed bytes";
768 }
769 if(!UsefulInputBuf_BytesAvailable(&UIB, 11)){
770 return "Wrong number of bytes available I";
771 }
772
773 if(UsefulInputBuf_BytesAvailable(&UIB, 12)){
774 return "Wrong number of bytes available II";
775 }
776#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800777
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800778 UsefulInputBuf_Seek(&UIB, 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800779
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800780 if(UsefulInputBuf_GetError(&UIB)) {
781 return "unexpected error after seek";
782 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800783
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800784 const uint8_t *pGetBytes = (const uint8_t *)UsefulInputBuf_GetBytes(&UIB, 4);
785 if(pGetBytes == NULL) {
786 return "GetBytes returns NULL";
787 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800788
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800789 if(memcmp(pGetBytes, pExpectedNetworkOrder, 4)) {
790 return "Got wrong bytes";
791 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800792
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800793 UsefulInputBuf_Seek(&UIB, 28);
794
795 if(!UsefulInputBuf_GetError(&UIB)) {
796 return "expected error after seek";
797 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800798
Laurence Lundbladecf41c522021-02-20 10:19:07 -0700799 if(UsefulInputBuf_PointerToOffset(&UIB, O.ptr) != 0) {
800 return "PointerToOffset not working";
801 }
802
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530803 return NULL;
804}
805
806
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200807#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800808const char *UBUTest_CopyUtil(void)
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530809{
810 if(UsefulBufUtil_CopyFloatToUint32(65536.0F) != 0x47800000) {
811 return "CopyFloatToUint32 failed";
812 }
813
814 if(UsefulBufUtil_CopyDoubleToUint64(4e-40F) != 0X37C16C2800000000ULL) {
815 return "CopyDoubleToUint64 failed";
816 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800817
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530818 if(UsefulBufUtil_CopyUint64ToDouble(0X37C16C2800000000ULL) != 4e-40F) {
819 return "CopyUint64ToDouble failed";
820 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800821
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530822 if(UsefulBufUtil_CopyUint32ToFloat(0x47800000) != 65536.0F) {
823 return "CopyUint32ToFloat failed";
824 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800825
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800826 return NULL;
827}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200828#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800829
830
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600831const char *UBAdvanceTest(void)
832{
833 #define ADVANCE_TEST_SIZE 10
834 UsefulOutBuf_MakeOnStack(UOB, ADVANCE_TEST_SIZE);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800835
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600836 UsefulBuf Place = UsefulOutBuf_GetOutPlace(&UOB);
837 if(Place.len != 10) {
838 return "GetOutPlace wrong size";
839 }
840
841 memset(Place.ptr, 'x', Place.len/2);
842
843 UsefulOutBuf_Advance(&UOB, Place.len/2);
844
845 UsefulOutBuf_AppendByte(&UOB, 'y');
846
847 Place = UsefulOutBuf_GetOutPlace(&UOB);
848 if(Place.len != ADVANCE_TEST_SIZE/2 -1 ) {
849 return "GetOutPlace wrong size 2";
850 }
851
852 memset(Place.ptr, 'z', Place.len);
853
854 UsefulOutBuf_Advance(&UOB, Place.len);
855
856 UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
857
858 UsefulBuf_Compare(O, UsefulBuf_FROM_SZ_LITERAL("xxxxxyzzzz"));
859
860 Place = UsefulOutBuf_GetOutPlace(&UOB);
861 if(Place.len != 0 || Place.ptr != NULL) {
862 return "GetOutPlace not null";
863 }
864
865 if(UsefulOutBuf_GetError(&UOB)) {
866 return "GetOutPlace error set";
867 }
868
869 UsefulOutBuf_Advance(&UOB, 1);
870 if(!UsefulOutBuf_GetError(&UOB)) {
871 return "Advance off end didn't set error";
872 }
873
874 return NULL;
875}
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700876
877
878const char * UOBExtraTests(void)
879{
880 #define COMPARE_TEST_SIZE 10
881 UsefulOutBuf_MakeOnStack( UOB, COMPARE_TEST_SIZE);
882 int nCompare;
883 UsefulBufC Out;
884
885 /* Test UsefulOutBuf_Compare() */
886 UsefulOutBuf_AppendString(&UOB, "abcabdefab");
887
Laurence Lundbladea691a612024-02-27 02:29:01 -0700888 nCompare = UsefulOutBuf_Compare(&UOB, 0, 2, 8, 2);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700889 if(nCompare != 0) {
890 return "ab should compare equal";
891 }
892
Laurence Lundbladea691a612024-02-27 02:29:01 -0700893 nCompare = UsefulOutBuf_Compare(&UOB, 0, 3, 3, 3);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700894 if(nCompare != 'd' - 'c') {
895 return "abc should not equal abd";
896 }
897
Laurence Lundbladea691a612024-02-27 02:29:01 -0700898 nCompare = UsefulOutBuf_Compare(&UOB, 3, 2, 8, 2);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700899 if(nCompare != 0) {
900 return "ab should compare equal";
901 }
902
Laurence Lundbladea691a612024-02-27 02:29:01 -0700903 nCompare = UsefulOutBuf_Compare(&UOB, 2, 4, 5, 4);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700904 if(nCompare != 'd' - 'c') {
905 return "ca should not equal de";
906 }
907
Laurence Lundbladea691a612024-02-27 02:29:01 -0700908 nCompare = UsefulOutBuf_Compare(&UOB, 5, 1, 2, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700909 if(nCompare != 'c' - 'd') {
910 return "de should not equal ca";
911 }
912
Laurence Lundbladea691a612024-02-27 02:29:01 -0700913 nCompare = UsefulOutBuf_Compare(&UOB, 7, 2, 8, 2);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700914 if(nCompare != 'a' - 'f') {
915 return "fa should not equal ab";
916 }
917
Laurence Lundbladea691a612024-02-27 02:29:01 -0700918 nCompare = UsefulOutBuf_Compare(&UOB, 0, 10, 0, 10);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700919 if(nCompare != 0) {
920 return "comparison to self failed";
921 }
922
Laurence Lundbladea691a612024-02-27 02:29:01 -0700923 nCompare = UsefulOutBuf_Compare(&UOB, 9, 1, 9, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700924 if(nCompare != 0) {
925 return "b should compare equal to b";
926 }
927
Laurence Lundbladea691a612024-02-27 02:29:01 -0700928 nCompare = UsefulOutBuf_Compare(&UOB, 10, 1, 10, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700929 if(nCompare != 0) {
930 return "Comparison off the end is equal";
931 }
932
Laurence Lundbladea691a612024-02-27 02:29:01 -0700933 nCompare = UsefulOutBuf_Compare(&UOB, 0, 1, 100, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700934 if(nCompare != 0) {
935 return "Comparison off the end is equal";
936 }
937
Laurence Lundbladea691a612024-02-27 02:29:01 -0700938 nCompare = UsefulOutBuf_Compare(&UOB, 100, 1, 0, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700939 if(nCompare != 0) {
940 return "Comparison off the end is equal";
941 }
942
Laurence Lundbladeda84ed72024-02-27 22:24:07 -0700943 nCompare = UsefulOutBuf_Compare(&UOB, 0, 3, 3, 2);
944 if(nCompare > 0) {
945 return "Comparison of unequal lengths incorrect";
946 }
947
948 nCompare = UsefulOutBuf_Compare(&UOB, 8, 2, 0, 3);
949 if(nCompare < 0) {
950 return "Comparison of unequal lengths incorrect 2";
951 }
952
953 nCompare = UsefulOutBuf_Compare(&UOB, 0, 2, 2, 3);
954 if(nCompare != 'c' - 'a') {
955 return "Inequal lengths, but inequal strings";
956 }
957
958 nCompare = UsefulOutBuf_Compare(&UOB, 1, 3, 4, 2);
959 if(nCompare != 'd' - 'c') {
960 return "Inequal lengths, but inequal strings";
961 }
Laurence Lundbladea691a612024-02-27 02:29:01 -0700962
Laurence Lundbladed6e13022023-11-26 10:14:02 -0700963 /* Test UsefulOutBuf_Swap() */
964
965 UsefulOutBuf_Reset(&UOB);
966 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
967 UsefulOutBuf_Swap(&UOB, 0, 4, 8);
968 Out = UsefulOutBuf_OutUBuf(&UOB);
969 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("efghabcd"))) {
970 return "swap fail 1";
971 }
972
973 UsefulOutBuf_Reset(&UOB);
974 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
975 UsefulOutBuf_Swap(&UOB, 0, 1, 2);
976 Out = UsefulOutBuf_OutUBuf(&UOB);
977 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("bacdefgh"))) {
978 return "swap fail 2";
979 }
980
981 UsefulOutBuf_Reset(&UOB);
982 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
983 UsefulOutBuf_Swap(&UOB, 0, 1, 8);
984 Out = UsefulOutBuf_OutUBuf(&UOB);
985 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("bcdefgha"))) {
986 return "swap fail 3";
987 }
988
989 UsefulOutBuf_Reset(&UOB);
990 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
991 UsefulOutBuf_Swap(&UOB, 0, 3, 4);
992 Out = UsefulOutBuf_OutUBuf(&UOB);
993 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("dabcefgh"))) {
994 return "swap fail 4";
995 }
996
997 UsefulOutBuf_Reset(&UOB);
998 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
999 UsefulOutBuf_Swap(&UOB, 9, 10, 11);
1000 Out = UsefulOutBuf_OutUBuf(&UOB);
1001 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1002 return "swap fail 5";
1003 }
1004
1005 UsefulOutBuf_Reset(&UOB);
1006 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1007 UsefulOutBuf_Swap(&UOB, 0, 4, 11);
1008 Out = UsefulOutBuf_OutUBuf(&UOB);
1009 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1010 return "swap fail 6";
1011 }
1012
1013 UsefulOutBuf_Reset(&UOB);
1014 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1015 UsefulOutBuf_Swap(&UOB, 9, 0, 0);
1016 Out = UsefulOutBuf_OutUBuf(&UOB);
1017 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1018 return "swap fail 7";
1019 }
1020
1021 UsefulOutBuf_Reset(&UOB);
1022 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1023 UsefulOutBuf_Swap(&UOB, 0, 0, 0);
1024 Out = UsefulOutBuf_OutUBuf(&UOB);
1025 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1026 return "swap fail 8";
1027 }
1028
1029 UsefulOutBuf_Reset(&UOB);
1030 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1031 UsefulOutBuf_Swap(&UOB, 8, 4, 0);
1032 Out = UsefulOutBuf_OutUBuf(&UOB);
1033 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1034 return "swap fail 9";
1035 }
1036
1037 UsefulOutBuf_Reset(&UOB);
1038 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1039 UsefulOutBuf_Swap(&UOB, 0, 8, 4);
1040 Out = UsefulOutBuf_OutUBuf(&UOB);
1041 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1042 return "swap fail 10";
1043 }
1044
1045
1046 /* Test for UsefulOutBuf_GetOutput() */
1047 UsefulOutBuf_Reset(&UOB);
1048 UsefulOutBuf_AppendString(&UOB, "abc");
1049 UsefulOutBuf_AppendString(&UOB, "xyz");
1050
1051 Out = UsefulOutBuf_OutUBufOffset(&UOB, 0);
1052 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcxyz"))) {
1053 return "GetOutput fail 1";
1054 }
1055
1056 Out = UsefulOutBuf_OutUBufOffset(&UOB, 5);
1057 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("z"))) {
1058 return "GetOutput fail 2";
1059 }
1060
1061 Out = UsefulOutBuf_OutUBufOffset(&UOB, 1);
1062 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("bcxyz"))) {
1063 return "GetOutput fail 3";
1064 }
1065
1066 Out = UsefulOutBuf_OutUBufOffset(&UOB, 6);
1067 if(!UsefulBuf_IsNULLC(Out)) {
1068 return "GetOutput fail 4";
1069 }
1070
1071 Out = UsefulOutBuf_OutUBufOffset(&UOB, 7);
1072 if(!UsefulBuf_IsNULLC(Out)) {
1073 return "GetOutput fail 5";
1074 }
1075
1076 return NULL;
1077}