blob: ae3862c53606f8e7a5feb0533871bfa5076e46ec [file] [log] [blame]
Laurence Lundblade52aefa62024-06-13 13:23:17 -07001/* ==========================================================================
2 * Copyright (c) 2016-2018, The Linux Foundation.
3 * Copyright (c) 2018-2024, Laurence Lundblade.
4 * Copyright (c) 2021, Arm Limited.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
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.
20 *
21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ========================================================================= */
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
Laurence Lundbladee2226742024-08-16 10:50:23 -0700130 Out = UsefulOutBuf_SubString(&UOB, 10, 8);
131 if(UsefulBuf_IsNULLC(Out) ||
132 UsefulBuf_Compare(UsefulBuf_FROM_SZ_LITERAL("unbounce"), Out) ||
133 UsefulOutBuf_GetError(&UOB)) {
134 szReturn = "SubString substring";
135 goto Done;
136 }
137
138 Out = UsefulOutBuf_SubString(&UOB, 0, Expected.len);
139 if(UsefulBuf_IsNULLC(Out) ||
140 UsefulBuf_Compare(Expected, Out) ||
141 UsefulOutBuf_GetError(&UOB)) {
142 szReturn = "SubString all";
143 goto Done;
144 }
145
146 Out = UsefulOutBuf_SubString(&UOB, Expected.len, 0);
147 if(UsefulBuf_IsNULLC(Out) ||
148 UsefulBuf_Compare(UsefulBuf_FROM_SZ_LITERAL(""), Out) ||
149 UsefulOutBuf_GetError(&UOB)) {
150 szReturn = "SubString empty";
151 goto Done;
152 }
153
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700154 /* Now test the size calculation mode */
155 UsefulOutBuf_Init(&UOB, SizeCalculateUsefulBuf);
156
157 szReturn = AddStuffToUOB(&UOB);
158 if(szReturn) {
159 goto Done;
160 }
161
162 U = UsefulOutBuf_OutUBuf(&UOB);
163 if(U.len != Expected.len || U.ptr != NULL) {
164 szReturn = "size calculation failed";
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800165 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800166
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800167Done:
168 return szReturn;
169}
170
171
172/*
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700173 * Append test utility.
174 * pUOB is the buffer to append too
175 * num is the amount to append
176 * expected is the expected return code, 0 or 1
177 *
178 * returns 0 if test passed
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800179 */
180static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected)
181{
182 //reset
183 UsefulOutBuf_Reset(pUOB);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800184
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800185 // check status first
186 if(UsefulOutBuf_GetError(pUOB))
187 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800188
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800189 // append the bytes
190 UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800191
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800192 // check error status after
193 if(UsefulOutBuf_GetError(pUOB) != expected)
194 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800195
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800196 return 0;
197}
198
199
200/*
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700201 * Same as append, but takes a position param too
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800202 */
203static int InsertTest(UsefulOutBuf *pUOB, size_t num, size_t pos, int expected)
204{
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530205 // reset
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800206 UsefulOutBuf_Reset(pUOB);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800207
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800208 // check
209 if(UsefulOutBuf_GetError(pUOB))
210 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800211
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800212 UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800213
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800214 if(UsefulOutBuf_GetError(pUOB) != expected)
215 return 1;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800216
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800217 return 0;
218}
219
220
221/*
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700222 * Boundary conditions to test
223 * - around 0
224 * - around the buffer size
225 * - around MAX size_t
226 *
227 *
228 * Test these for the buffer size and the cursor, the insert amount, the
229 * append amount and the insert position
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800230 */
231
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800232const char *UOBTest_BoundaryConditionsTest(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800233{
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700234 UsefulBuf_MAKE_STACK_UB(outbuf, 2);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800235
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800236 UsefulOutBuf UOB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800237
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530238 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800239
240 // append 0 byte to a 2 byte buffer --> success
241 if(AppendTest(&UOB, 0, 0))
242 return "Append 0 bytes failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800243
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800244 // append 1 byte to a 2 byte buffer --> success
245 if(AppendTest(&UOB, 1, 0))
246 return "Append of 1 byte failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800247
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800248 // append 2 byte to a 2 byte buffer --> success
249 if(AppendTest(&UOB, 2, 0))
250 return "Append to fill buffer failed";
251
252 // append 3 bytes to a 2 byte buffer --> failure
253 if(AppendTest(&UOB, 3, 1))
254 return "Overflow of buffer not caught";
255
256 // append max size_t to a 2 byte buffer --> failure
257 if(AppendTest(&UOB, SIZE_MAX, 1))
258 return "Append of SIZE_MAX error not caught";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800259
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800260 if(InsertTest(&UOB, 1, 0, 0))
261 return "Insert 1 byte at start failed";
262
263 if(InsertTest(&UOB, 2, 0, 0))
264 return "Insert 2 bytes at start failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800265
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800266 if(InsertTest(&UOB, 3, 0, 1))
267 return "Insert overflow not caught";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800268
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800269 if(InsertTest(&UOB, 1, 1, 1))
270 return "Bad insertion point not caught";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800271
272
Laurence Lundbladee2226742024-08-16 10:50:23 -0700273 UsefulBuf_MAKE_STACK_UB(outBuf2, 10);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800274
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530275 UsefulOutBuf_Init(&UOB, outBuf2);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800276
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800277 UsefulOutBuf_Reset(&UOB);
278 // put data in the buffer
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800279 UsefulOutBuf_AppendString(&UOB, "abc123");
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800280
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800281 UsefulOutBuf_InsertString(&UOB, "xyz*&^", 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800282
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800283 if(!UsefulOutBuf_GetError(&UOB)) {
284 return "insert with data should have failed";
285 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800286
Laurence Lundbladee2226742024-08-16 10:50:23 -0700287 UsefulOutBuf_Init(&UOB, outBuf2);
288 UsefulOutBuf_AppendString(&UOB, "abc123");
289
290 UsefulBufC Out = UsefulOutBuf_SubString(&UOB, 7, 1);
291 if(!UsefulBuf_IsNULLC(Out)) {
292 return "SubString start should fail off end 1";
293 }
294 Out = UsefulOutBuf_SubString(&UOB, 5, 3);
295 if(!UsefulBuf_IsNULLC(Out)) {
296 return "SubString len should fail off end 2";
297 }
298 Out = UsefulOutBuf_SubString(&UOB, 0, 7);
299 if(!UsefulBuf_IsNULLC(Out)) {
300 return "SubString len should fail off end 3";
301 }
302 Out = UsefulOutBuf_SubString(&UOB, 7, 0);
303 if(!UsefulBuf_IsNULLC(Out)) {
304 return "SubString len should fail off end 4";
305 }
306 Out = UsefulOutBuf_SubString(&UOB, 6, 1);
307 if(!UsefulBuf_IsNULLC(Out)) {
308 return "SubString len should fail off end 5";
309 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800310
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530311 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800312 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
313 if(UsefulOutBuf_GetError(&UOB)) {
314 return "insert in huge should have succeeded";
315 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800316
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530317 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800318 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5);
319 if(UsefulOutBuf_GetError(&UOB)) {
320 return "insert in huge should have succeeded";
321 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800322
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530323 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800324 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4);
325 if(!UsefulOutBuf_GetError(&UOB)) {
326 return "lengths near max size";
327 }
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700328 UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
329 if(!UsefulBuf_IsNULLC(O)) {
330 return "OutUBuf in error should have returned NULL";
331 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800332
Laurence Lundblade30dd0ba2019-05-26 23:37:30 +0300333 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, 100});
334 if(!UsefulOutBuf_IsBufferNULL(&UOB)) {
335 return "NULL check failed";
336 }
337
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700338 UsefulOutBuf_Init(&UOB, outbuf);
339 UOB.magic = 99; // corrupt the UOB
340 O = UsefulOutBuf_OutUBuf(&UOB);
341 if(!UsefulBuf_IsNULLC(O)) {
342 return "OutUBuf on corrupted should have returned NULL";
343 }
344
345 MakeUsefulBufOnStack(Tmp, 20);
346 O = UsefulOutBuf_CopyOut(&UOB, Tmp);
347 if(!UsefulBuf_IsNULLC(O)) {
348 return "CopyOut on corrupted should have returned NULL";
349 }
350
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800351 return NULL;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800352}
353
354
355
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800356// Test function to get size and magic number check
357
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800358const char *TestBasicSanity(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800359{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530360 UsefulBuf_MAKE_STACK_UB(outbuf,10);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800361
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800362 UsefulOutBuf UOB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800363
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800364 // First -- make sure that the room left function returns the right amount
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530365 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800366
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530367 if(UsefulOutBuf_RoomLeft(&UOB) != 10)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800368 return "room left failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800369
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800370 if(!UsefulOutBuf_WillItFit(&UOB, 9)) {
371 return "it did not fit";
372 }
373
374 if(UsefulOutBuf_WillItFit(&UOB, 11)) {
375 return "it should have not fit";
376 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800377
378
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800379 // Next -- make sure that the magic number checking is working right
380 UOB.magic = 8888; // make magic bogus
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800381
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800382 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800383
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700384 if(!UsefulOutBuf_GetError(&UOB)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800385 return "magic corruption check failed";
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700386 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800387
388
389
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800390 // Next make sure that the valid data length check is working right
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530391 UsefulOutBuf_Init(&UOB, outbuf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800392
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530393 UOB.data_len = UOB.UB.len+1; // make size bogus
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800394
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800395 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
396 if(!UsefulOutBuf_GetError(&UOB))
397 return "valid data check failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800398
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800399 return NULL;
400}
401
402
403
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800404const char *UBMacroConversionsTest(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800405{
406 char *szFoo = "foo";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800407
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530408 UsefulBufC Foo = UsefulBuf_FromSZ(szFoo);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800409 if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
410 return "SZToUsefulBufC failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800411
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530412 UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo");
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800413 if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530414 return "UsefulBuf_FROM_SZ_LITERAL failed";
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800415
416 uint8_t pB[] = {0x42, 0x6f, 0x6f};
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530417 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800418 if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530419 return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800420
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800421 char *String = "string"; // Intentionally not const
422 UsefulBuf B = (UsefulBuf){(void *)String, strlen(String)};
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530423 UsefulBufC BC = UsefulBuf_Const(B);
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800424 if(BC.len != strlen(String) || BC.ptr != String)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800425 return "UsefulBufConst failed";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800426
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800427 return NULL;
428}
429
430
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800431const char *UBUtilTests(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800432{
433 UsefulBuf UB = NULLUsefulBuf;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800434
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800435 if(!UsefulBuf_IsNULL(UB)){
436 return "IsNull failed";
437 }
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530438
439 if(!UsefulBuf_IsEmpty(UB)){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800440 return "IsEmpty failed";
441 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800442
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530443 if(!UsefulBuf_IsNULLOrEmpty(UB)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800444 return "IsNULLOrEmpty failed";
445 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800446
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800447 const UsefulBufC UBC = UsefulBuf_Const(UB);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800448
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530449 if(!UsefulBuf_IsNULLC(UBC)){
450 return "IsNull const failed";
451 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800452
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530453 if(!UsefulBuf_IsEmptyC(UBC)){
454 return "IsEmptyC failed";
455 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800456
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530457 if(!UsefulBuf_IsNULLOrEmptyC(UBC)){
458 return "IsNULLOrEmptyC failed";
459 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800460
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800461 const UsefulBuf UB2 = UsefulBuf_Unconst(UBC);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530462 if(!UsefulBuf_IsEmpty(UB2)) {
463 return "Back to UB is Empty failed";
464 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800465
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800466 UB.ptr = "x"; // just some valid pointer
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800467
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800468 if(UsefulBuf_IsNULL(UB)){
469 return "IsNull failed";
470 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800471
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530472 if(!UsefulBuf_IsEmptyC(UBC)){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800473 return "IsEmpty failed";
474 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800475
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800476 // test the Unconst.
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530477 if(UsefulBuf_Unconst(UBC).ptr != NULL) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800478 return "Unconst failed";
479 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800480
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800481 // Set 100 bytes of '+'; validated a few tests later
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530482 UsefulBuf_MAKE_STACK_UB(Temp, 100);
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800483 const UsefulBufC TempC = UsefulBuf_Set(Temp, '+');
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800484
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800485 // Try to copy into a buf that is too small and see failure
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530486 UsefulBuf_MAKE_STACK_UB(Temp2, 99);
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530487 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp2, TempC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800488 return "Copy should have failed";
489 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800490
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800491 if(UsefulBuf_IsNULLC(UsefulBuf_CopyPtr(Temp2, "xx", 2))) {
492 return "CopyPtr failed";
493 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800494
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530495 UsefulBufC xxyy = UsefulBuf_CopyOffset(Temp2, 2, UsefulBuf_FROM_SZ_LITERAL("yy"));
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800496 if(UsefulBuf_IsNULLC(xxyy)) {
497 return "CopyOffset Failed";
498 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800499
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530500 if(UsefulBuf_Compare(UsefulBuf_Head(xxyy, 3), UsefulBuf_FROM_SZ_LITERAL("xxy"))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800501 return "head failed";
502 }
503
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530504 if(UsefulBuf_Compare(UsefulBuf_Tail(xxyy, 1), UsefulBuf_FROM_SZ_LITERAL("xyy"))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800505 return "tail failed";
506 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800507
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800508 if(!UsefulBuf_IsNULLC(UsefulBuf_Head(xxyy, 5))) {
509 return "head should have failed";
510 }
511
512 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(xxyy, 5))) {
513 return "tail should have failed";
514 }
Laurence Lundbladedf1c1cf2019-01-17 11:55:05 -0800515
Laurence Lundblade7412f812019-01-01 18:49:36 -0800516 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(NULLUsefulBufC, 0))) {
517 return "tail of NULLUsefulBufC is not NULLUsefulBufC";
518 }
Laurence Lundbladedf1c1cf2019-01-17 11:55:05 -0800519
Laurence Lundblade7412f812019-01-01 18:49:36 -0800520 const UsefulBufC TailResult = UsefulBuf_Tail((UsefulBufC){NULL, 100}, 99);
521 if(TailResult.ptr != NULL || TailResult.len != 1) {
522 return "tail of NULL and length incorrect";
523 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800524
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530525 if(!UsefulBuf_IsNULLC(UsefulBuf_CopyOffset(Temp2, 100, UsefulBuf_FROM_SZ_LITERAL("yy")))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800526 return "Copy Offset should have failed";
527 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800528
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800529 // Try to copy into a NULL/empty buf and see failure
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800530 const UsefulBuf UBNull = NULLUsefulBuf;
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530531 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(UBNull, TempC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800532 return "Copy to NULL should have failed";
533 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800534
535
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800536 // Try to set a NULL/empty buf; nothing should happen
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530537 UsefulBuf_Set(UBNull, '+'); // This will crash on failure
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800538
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800539 // Copy successfully to a buffer
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530540 UsefulBuf_MAKE_STACK_UB(Temp3, 101);
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530541 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp3, TempC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800542 return "Copy should not have failed";
543 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800544
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800545 static const uint8_t pExpected[] = {
546 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
547 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
548 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
549 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
550 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
551 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
552 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
553 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
554 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
555 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
556 };
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530557 UsefulBufC Expected = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpected);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800558 // This validates comparison for equality and the UsefulBuf_Set
Laurence Lundblade05ec57b2018-10-21 01:50:03 +0530559 if(UsefulBuf_Compare(Expected, TempC)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800560 return "Set / Copy / Compare failed";
561 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800562
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800563 // Compare two empties and expect success
564 if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){
565 return "Compare Empties failed";
566 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800567
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800568 // Compare with empty and expect the first to be larger
569 if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){
570 return "Compare with empty failed";
571 }
572
573
574 static const uint8_t pExpectedBigger[] = {
575 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
576 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
577 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
578 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
579 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
580 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
581 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
582 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
583 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
584 '+', '+', '+', '+', '+', '+', '+', '+', '+', ',',
585 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800586 const UsefulBufC ExpectedBigger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedBigger);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800587
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530588 // Expect -1 when the first arg is smaller
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800589 if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){
590 return "Compare with bigger";
591 }
592
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800593
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800594 static const uint8_t pExpectedSmaller[] = {
595 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
596 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
597 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
598 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
599 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
600 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
601 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
602 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
603 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
604 '+', '+', '+', '+', '+', '+', '+', '+', '+', '*',
605 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800606 const UsefulBufC ExpectedSmaller = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedSmaller);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530607 // Expect +1 when the first arg is larger
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800608 if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){
609 return "Compare with smaller";
610 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800611
612
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800613 static const uint8_t pExpectedLonger[] = {
614 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
615 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
616 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
617 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
618 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
619 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
620 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
621 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
622 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
623 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+'
624 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800625 const UsefulBufC ExpectedLonger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedLonger);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800626
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530627 // Expect -1 when the first arg is smaller
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800628 if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){
629 return "Compare with longer";
630 }
631
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800632
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800633 static const uint8_t pExpectedShorter[] = {
634 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
635 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
636 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
637 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
638 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
639 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
640 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
641 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
642 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
643 '+', '+', '+', '+', '+', '+', '+', '+', '+',
644 };
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800645 const UsefulBufC ExpectedShorter = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedShorter);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800646 // Expect +1 with the first arg is larger
647 if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){
648 return "Compare with shorter";
649 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800650
651
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530652 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp, NULLUsefulBufC))) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800653 return "Copy null/empty failed";
654 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800655
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800656 if(UsefulBuf_IsValue(ExpectedShorter, '+') != SIZE_MAX) {
657 return "IsValue failed to match all";
658 }
659
660 if(UsefulBuf_IsValue(ExpectedShorter, '-') != 0) {
661 return "IsValue should have failed right away";
662 }
663
664 if(UsefulBuf_IsValue(NULLUsefulBufC, 0x00) != 0) {
665 return "IsValue failed on NULLUsefulBufC";
666 }
667
668 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x00) != SIZE_MAX) {
669 return "IsValue failed finding 0 in one byte of 0";
670 }
671
672 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x01) != 0) {
673 return "IsValue failed not finding 1 in one byte of 0";
674 }
675
676 if(UsefulBuf_IsValue(ExpectedSmaller, '+') != ExpectedSmaller.len -1) {
677 return "IsValue failed to find final *";
678 }
679
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800680 // Look for +++++... in +++++... and find it at the beginning
681 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
682 return "Failed to find";
683 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800684
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800685 // look for ++* in ....++* and find it at the end
686 static const uint8_t pToFind[] = {'+', '+', '*'};
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800687 const UsefulBufC ToBeFound = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pToFind);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800688
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800689 if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){
690 return "Failed to find 2";
691 }
692
693 // look for ++* in ....++, and find it near the end
694 if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){
695 return "Failed to not find";
696 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800697
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800698 // Look for the whole buffer in itself and succeed.
699 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){
700 return "Failed to find 3";
701 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800702
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700703 if(SIZE_MAX != UsefulBuf_FindBytes(Expected, ExpectedLonger)) {
704 return "Failed to find 4";
705 }
706
Laurence Lundblade68769332024-11-03 13:09:20 -0800707 UsefulBufC Substring;
708 Substring = UsefulBuf_SkipLeading(UsefulBuf_FromSZ("xxyyzz"), 'x');
709 if(UsefulBuf_Compare(Substring, UsefulBuf_FromSZ("yyzz"))) {
710 return "SkipLeading didn't skip";
711 }
712
713 Substring = UsefulBuf_SkipLeading(UsefulBuf_FromSZ("xxyyzz"), 'y');
714 if(UsefulBuf_Compare(Substring, UsefulBuf_FromSZ("xxyyzz"))) {
715 return "SkipLeading skipped";
716 }
717
718 Substring = UsefulBuf_SkipLeading(UsefulBuf_FromSZ("qqq"), 'q');
719 if(UsefulBuf_Compare(Substring, UsefulBuf_FromSZ(""))) {
720 return "SkipLeading didn't return empty";
721 }
722
723 Substring = UsefulBuf_SkipLeading(UsefulBuf_FromSZ("x"), 'x');
724 if(UsefulBuf_Compare(Substring, UsefulBuf_FromSZ(""))) {
725 return "SkipLeading didn't return empty";
726 }
727
728 Substring = UsefulBuf_SkipLeading(UsefulBuf_FromSZ("xxxxxxxxxxxx"), 'x');
729 if(UsefulBuf_Compare(Substring, UsefulBuf_FromSZ(""))) {
730 return "SkipLeading didn't return empty";
731 }
Laurence Lundbladecf41c522021-02-20 10:19:07 -0700732
733 const uint8_t pB[] = {0x01, 0x02, 0x03};
734 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
735 // Try to map a pointer before
736 if(UsefulBuf_PointerToOffset(Boo, pB-1) != SIZE_MAX) {
737 return "Didn't error on pointer before";
738 }
739
740 // Try to map a pointer after
741 if(UsefulBuf_PointerToOffset(Boo, pB+sizeof(pB)) != SIZE_MAX) {
742 return "Didn't error on pointer after";
743 }
744
745 // Try to map a pointer inside
746 if(UsefulBuf_PointerToOffset(Boo, pB+1) != 1) {
747 return "Incorrect pointer offset";
748 }
749
750 // Try to map a pointer at the start
751 if(UsefulBuf_PointerToOffset(Boo, pB) != 0) {
752 return "Incorrect pointer offset for start";
753 }
754
755 // Try to map a pointer at the end
756 if(UsefulBuf_PointerToOffset(Boo, pB + sizeof(pB)-1) != 2) {
757 return "Incorrect pointer offset for end";
758 }
759
760 // Try to map a pointer on a NULL UB
761 if(UsefulBuf_PointerToOffset(NULLUsefulBufC, pB ) != SIZE_MAX) {
762 return "Incorrect pointer offset for start";
763 }
764
Laurence Lundbladea29f45a2024-05-14 15:55:19 -0700765 if(UsefulBuf_OffsetToPointer(Boo, 0) != &pB[0]) {
766 return "Wrong OffsetToPointer";
767 }
768
769 if(UsefulBuf_OffsetToPointer(Boo, 3) != NULL) {
770 return "Didn't validate offset correctly";
771 }
772
773 if(UsefulBuf_OffsetToPointer(Boo, 2) != &pB[2]) {
774 return "Wrong OffsetToPointer 2";
775 }
776
777 if(UsefulBuf_OffsetToPointer(NULLUsefulBufC, 2) != NULL) {
778 return "Failed OffsetToPtr on NULLUsefulBufC";
779 }
780
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800781 return NULL;
782}
783
784
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800785const char * UIBTest_IntegerFormat(void)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800786{
Laurence Lundbladecf41c522021-02-20 10:19:07 -0700787 UsefulOutBuf_MakeOnStack(UOB, 100);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800788
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800789 const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
790 const uint64_t u64 = 1984738472938472;
791 const uint16_t u16 = 40000;
792 const uint8_t u8 = 9;
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200793#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800794 const float f = (float)314.15;
795 const double d = 2.1e10;
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700796#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800797
798
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530799 UsefulOutBuf_AppendUint32(&UOB, u32); // Also tests UsefulOutBuf_InsertUint64 and UsefulOutBuf_GetEndPosition
800 UsefulOutBuf_AppendUint64(&UOB, u64); // Also tests UsefulOutBuf_InsertUint32
801 UsefulOutBuf_AppendUint16(&UOB, u16); // Also tests UsefulOutBuf_InsertUint16
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800802 UsefulOutBuf_AppendByte(&UOB, u8);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200803#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530804 UsefulOutBuf_AppendFloat(&UOB, f); // Also tests UsefulOutBuf_InsertFloat
805 UsefulOutBuf_AppendDouble(&UOB, d); // Also tests UsefulOutBuf_InsertDouble
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700806#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800807
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800808 const UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530809 if(UsefulBuf_IsNULLC(O))
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800810 return "Couldn't output integers";
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800811
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800812 // from https://en.wikipedia.org/wiki/Endianness
813 const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D};
814 if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) {
815 return "not in network order";
816 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800817
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800818 UsefulInputBuf UIB;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800819
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530820 UsefulInputBuf_Init(&UIB, O);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800821
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530822 if(UsefulInputBuf_Tell(&UIB) != 0) {
823 return "UsefulInputBuf_Tell failed";
824 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800825
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800826 if(UsefulInputBuf_GetUint32(&UIB) != u32) {
827 return "u32 out then in failed";
828 }
829 if(UsefulInputBuf_GetUint64(&UIB) != u64) {
830 return "u64 out then in failed";
831 }
832 if(UsefulInputBuf_GetUint16(&UIB) != u16) {
833 return "u16 out then in failed";
834 }
835 if(UsefulInputBuf_GetByte(&UIB) != u8) {
836 return "u8 out then in failed";
837 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200838#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800839 if(UsefulInputBuf_GetFloat(&UIB) != f) {
840 return "float out then in failed";
841 }
842 if(UsefulInputBuf_GetDouble(&UIB) != d) {
843 return "double out then in failed";
844 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200845#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800846
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700847 if(UsefulInputBuf_GetUint16(&UIB) != 0) {
848 return "Didn't catch off end with GetUint16";
849 }
850 if(UsefulInputBuf_GetUint32(&UIB) !=0 ) {
851 return "Didn't catch off end with GetUint32";
852 }
853 if(UsefulInputBuf_GetUint64(&UIB) !=0 ) {
854 return "Didn't catch off end with GetUint64";
855 }
856
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800857 // Reset and go again for a few more tests
858 UsefulInputBuf_Init(&UIB, O);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800859
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800860 const UsefulBufC Four = UsefulInputBuf_GetUsefulBuf(&UIB, 4);
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800861 if(UsefulBuf_IsNULLC(Four)) {
862 return "Four is NULL";
863 }
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530864 if(UsefulBuf_Compare(Four, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedNetworkOrder))) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800865 return "Four compare failed";
866 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800867
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200868#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800869 if(UsefulInputBuf_BytesUnconsumed(&UIB) != 23){
870 return "Wrong number of unconsumed bytes";
871 }
872
873 if(!UsefulInputBuf_BytesAvailable(&UIB, 23)){
874 return "Wrong number of bytes available I";
875 }
876
877 if(UsefulInputBuf_BytesAvailable(&UIB, 24)){
878 return "Wrong number of bytes available II";
879 }
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200880#else /* USEFULBUF_DISABLE_ALL_FLOAT */
881 if(UsefulInputBuf_BytesUnconsumed(&UIB) != 11){
882 return "Wrong number of unconsumed bytes";
883 }
884 if(!UsefulInputBuf_BytesAvailable(&UIB, 11)){
885 return "Wrong number of bytes available I";
886 }
887
888 if(UsefulInputBuf_BytesAvailable(&UIB, 12)){
889 return "Wrong number of bytes available II";
890 }
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700891#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800892
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800893 UsefulInputBuf_Seek(&UIB, 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800894
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800895 if(UsefulInputBuf_GetError(&UIB)) {
896 return "unexpected error after seek";
897 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800898
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800899 const uint8_t *pGetBytes = (const uint8_t *)UsefulInputBuf_GetBytes(&UIB, 4);
900 if(pGetBytes == NULL) {
901 return "GetBytes returns NULL";
902 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800903
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800904 if(memcmp(pGetBytes, pExpectedNetworkOrder, 4)) {
905 return "Got wrong bytes";
906 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800907
Laurence Lundblade7566b9f2018-10-12 09:13:32 +0800908 UsefulInputBuf_Seek(&UIB, 28);
909
910 if(!UsefulInputBuf_GetError(&UIB)) {
911 return "expected error after seek";
912 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800913
Laurence Lundbladecf41c522021-02-20 10:19:07 -0700914 if(UsefulInputBuf_PointerToOffset(&UIB, O.ptr) != 0) {
915 return "PointerToOffset not working";
916 }
917
Laurence Lundbladea29f45a2024-05-14 15:55:19 -0700918
919 const uint8_t pB[] = {0x01, 0x02, 0x03};
920 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
921
922 UsefulInputBuf_Init(&UIB, Boo);
923
924 if(UsefulInputBuf_OffsetToPointer(&UIB, 0) != &pB[0]) {
925 return "OffsetToPointer fail";
926 }
927
928 if(UsefulInputBuf_OffsetToPointer(&UIB, SIZE_MAX) != NULL) {
929 return "OffsetToPointer SIZE_MAX fail";
930 }
931
Laurence Lundblade52aefa62024-06-13 13:23:17 -0700932 UsefulInputBuf_Init(&UIB, Boo);
933 UIB.magic = 88;
934 size_t uUnc = UsefulInputBuf_BytesUnconsumed(&UIB);
935 if(uUnc != 0) {
936 return "Didn't detect corrupted UsefulInputBuf";
937 }
938
939 UsefulInputBuf_Init(&UIB, Boo);
940 UIB.cursor = 500;
941 uUnc = UsefulInputBuf_BytesUnconsumed(&UIB);
942 if(uUnc != 0) {
943 return "Didn't detect bad UsefulInputBuf cursor";
944 }
945
946 if(!UsefulBuf_IsNULLC(UsefulInputBuf_GetUsefulBuf(&UIB, 5000))) {
947 return "Didn't detect off-end request of UsefulInputBuf";
948 }
949
950 if(!UsefulInputBuf_GetError(&UIB)) {
951 return "UIB Error state not reported";
952 }
953
954 UsefulInputBuf_Init(&UIB, Boo);
955 if(UsefulInputBuf_GetBufferLength(&UIB) != Boo.len) {
956 return "UIB length wrong";
957 }
958 UsefulInputBuf_SetBufferLength(&UIB, 1);
959 if(UsefulInputBuf_GetBufferLength(&UIB) != 1) {
960 return "UIB SetBufferLength failed";
961 }
962
Laurence Lundblade9b2ae8a2024-07-12 11:00:20 -0700963 UsefulBufC CompCheck = UsefulBuf_FROM_SZ_LITERAL("abcd");
964 UsefulInputBuf_Init(&UIB, CompCheck);
965
966 if(UsefulInputBuf_Compare(&UIB, 0, 2, 2, 2) >= 0) {
967 return "UB 1 compared greater than UB2";
968 }
969 if(UsefulInputBuf_Compare(&UIB, 0, 2, 0, 2) != 0) {
970 return "UB1 and UB2 didn't compare equally";
971 }
972 if(UsefulInputBuf_Compare(&UIB, 2, 2, 0, 2) <= 0) {
973 return "UB2 compared less than UB1";
974 }
975 if(UsefulInputBuf_Compare(&UIB, 4, 1, 2, 2) <= 0) {
976 return "Off-the-end UB1 compared as less than UB2";
977 }
978 if(UsefulInputBuf_Compare(&UIB, 0, 5, 2, 2) <= 0) {
979 return "Off-the-end UB1 compared as less than UB2 (second)";
980 }
981 if(UsefulInputBuf_Compare(&UIB, 0, 2, 5, 1) >= 0) {
982 return "Off-the-end UB2 compared as less than UB2";
983 }
984 if(UsefulInputBuf_Compare(&UIB, 0, 2, 2, 3) >= 0) {
985 return "Off-the-end UB2 compared as less than UB2 (second)";
986 }
987
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530988 return NULL;
989}
990
991
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200992#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800993const char *UBUTest_CopyUtil(void)
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530994{
995 if(UsefulBufUtil_CopyFloatToUint32(65536.0F) != 0x47800000) {
996 return "CopyFloatToUint32 failed";
997 }
998
999 if(UsefulBufUtil_CopyDoubleToUint64(4e-40F) != 0X37C16C2800000000ULL) {
1000 return "CopyDoubleToUint64 failed";
1001 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -08001002
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +05301003 if(UsefulBufUtil_CopyUint64ToDouble(0X37C16C2800000000ULL) != 4e-40F) {
1004 return "CopyUint64ToDouble failed";
1005 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -08001006
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +05301007 if(UsefulBufUtil_CopyUint32ToFloat(0x47800000) != 65536.0F) {
1008 return "CopyUint32ToFloat failed";
1009 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -08001010
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001011 return NULL;
1012}
Laurence Lundblade52aefa62024-06-13 13:23:17 -07001013#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001014
1015
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001016const char *UBAdvanceTest(void)
1017{
1018 #define ADVANCE_TEST_SIZE 10
1019 UsefulOutBuf_MakeOnStack(UOB, ADVANCE_TEST_SIZE);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001020
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001021 UsefulBuf Place = UsefulOutBuf_GetOutPlace(&UOB);
1022 if(Place.len != 10) {
1023 return "GetOutPlace wrong size";
1024 }
1025
1026 memset(Place.ptr, 'x', Place.len/2);
1027
1028 UsefulOutBuf_Advance(&UOB, Place.len/2);
1029
1030 UsefulOutBuf_AppendByte(&UOB, 'y');
1031
1032 Place = UsefulOutBuf_GetOutPlace(&UOB);
1033 if(Place.len != ADVANCE_TEST_SIZE/2 -1 ) {
1034 return "GetOutPlace wrong size 2";
1035 }
1036
1037 memset(Place.ptr, 'z', Place.len);
1038
1039 UsefulOutBuf_Advance(&UOB, Place.len);
1040
1041 UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
1042
1043 UsefulBuf_Compare(O, UsefulBuf_FROM_SZ_LITERAL("xxxxxyzzzz"));
1044
1045 Place = UsefulOutBuf_GetOutPlace(&UOB);
1046 if(Place.len != 0 || Place.ptr != NULL) {
1047 return "GetOutPlace not null";
1048 }
1049
1050 if(UsefulOutBuf_GetError(&UOB)) {
1051 return "GetOutPlace error set";
1052 }
1053
1054 UsefulOutBuf_Advance(&UOB, 1);
1055 if(!UsefulOutBuf_GetError(&UOB)) {
1056 return "Advance off end didn't set error";
1057 }
1058
Laurence Lundblade52aefa62024-06-13 13:23:17 -07001059 // Try to advance in error state
1060 UsefulOutBuf_Reset(&UOB);
1061 UsefulOutBuf_Advance(&UOB, 1);
1062 Place = UsefulOutBuf_GetOutPlace(&UOB);
1063 UsefulOutBuf_Advance(&UOB, 1000);
1064 UsefulOutBuf_Advance(&UOB, 1);
1065 UsefulBuf Place2;
1066 Place2 = UsefulOutBuf_GetOutPlace(&UOB);
1067 if(memcmp(&Place, &Place2, sizeof(Place))) {
1068 return "Advance didn't noop in error state";
1069 }
1070
1071 UsefulOutBuf_Reset(&UOB);
1072 UOB.data_len = UOB.UB.len + 1; // React in and corrupt
1073 UsefulOutBuf_Advance(&UOB, 1);
1074 if(!UsefulOutBuf_GetError(&UOB)) {
1075 return "didn't detect corrupted UOB";
1076 }
1077
1078 UsefulOutBuf BadUOB;
1079 memset(&BadUOB, 'x', sizeof(BadUOB));
1080 BadUOB.err = 0;
1081 UsefulOutBuf_Advance(&BadUOB, 1);
1082 if(!UsefulOutBuf_GetError(&BadUOB)) {
1083 return "didn't detect bad UOB";
1084 }
1085
1086
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001087 return NULL;
1088}
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001089
1090
1091const char * UOBExtraTests(void)
1092{
1093 #define COMPARE_TEST_SIZE 10
1094 UsefulOutBuf_MakeOnStack( UOB, COMPARE_TEST_SIZE);
1095 int nCompare;
1096 UsefulBufC Out;
1097
1098 /* Test UsefulOutBuf_Compare() */
1099 UsefulOutBuf_AppendString(&UOB, "abcabdefab");
1100
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001101 nCompare = UsefulOutBuf_Compare(&UOB, 0, 2, 8, 2);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001102 if(nCompare != 0) {
1103 return "ab should compare equal";
1104 }
1105
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001106 nCompare = UsefulOutBuf_Compare(&UOB, 0, 3, 3, 3);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001107 if(nCompare != 'd' - 'c') {
1108 return "abc should not equal abd";
1109 }
1110
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001111 nCompare = UsefulOutBuf_Compare(&UOB, 3, 2, 8, 2);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001112 if(nCompare != 0) {
1113 return "ab should compare equal";
1114 }
1115
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001116 nCompare = UsefulOutBuf_Compare(&UOB, 2, 4, 5, 4);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001117 if(nCompare != 'd' - 'c') {
1118 return "ca should not equal de";
1119 }
1120
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001121 nCompare = UsefulOutBuf_Compare(&UOB, 5, 1, 2, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001122 if(nCompare != 'c' - 'd') {
1123 return "de should not equal ca";
1124 }
1125
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001126 nCompare = UsefulOutBuf_Compare(&UOB, 7, 2, 8, 2);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001127 if(nCompare != 'a' - 'f') {
1128 return "fa should not equal ab";
1129 }
1130
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001131 nCompare = UsefulOutBuf_Compare(&UOB, 0, 10, 0, 10);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001132 if(nCompare != 0) {
1133 return "comparison to self failed";
1134 }
1135
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001136 nCompare = UsefulOutBuf_Compare(&UOB, 9, 1, 9, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001137 if(nCompare != 0) {
1138 return "b should compare equal to b";
1139 }
1140
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001141 nCompare = UsefulOutBuf_Compare(&UOB, 10, 1, 10, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001142 if(nCompare != 0) {
1143 return "Comparison off the end is equal";
1144 }
1145
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001146 nCompare = UsefulOutBuf_Compare(&UOB, 0, 1, 100, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001147 if(nCompare != 0) {
1148 return "Comparison off the end is equal";
1149 }
1150
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001151 nCompare = UsefulOutBuf_Compare(&UOB, 100, 1, 0, 1);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001152 if(nCompare != 0) {
1153 return "Comparison off the end is equal";
1154 }
1155
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07001156 nCompare = UsefulOutBuf_Compare(&UOB, 0, 3, 3, 2);
1157 if(nCompare > 0) {
1158 return "Comparison of unequal lengths incorrect";
1159 }
1160
1161 nCompare = UsefulOutBuf_Compare(&UOB, 8, 2, 0, 3);
1162 if(nCompare < 0) {
1163 return "Comparison of unequal lengths incorrect 2";
1164 }
1165
1166 nCompare = UsefulOutBuf_Compare(&UOB, 0, 2, 2, 3);
1167 if(nCompare != 'c' - 'a') {
1168 return "Inequal lengths, but inequal strings";
1169 }
1170
1171 nCompare = UsefulOutBuf_Compare(&UOB, 1, 3, 4, 2);
1172 if(nCompare != 'd' - 'c') {
1173 return "Inequal lengths, but inequal strings";
1174 }
1175
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001176 /* Test UsefulOutBuf_Swap() */
1177
1178 UsefulOutBuf_Reset(&UOB);
1179 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1180 UsefulOutBuf_Swap(&UOB, 0, 4, 8);
1181 Out = UsefulOutBuf_OutUBuf(&UOB);
1182 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("efghabcd"))) {
1183 return "swap fail 1";
1184 }
1185
1186 UsefulOutBuf_Reset(&UOB);
1187 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1188 UsefulOutBuf_Swap(&UOB, 0, 1, 2);
1189 Out = UsefulOutBuf_OutUBuf(&UOB);
1190 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("bacdefgh"))) {
1191 return "swap fail 2";
1192 }
1193
1194 UsefulOutBuf_Reset(&UOB);
1195 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1196 UsefulOutBuf_Swap(&UOB, 0, 1, 8);
1197 Out = UsefulOutBuf_OutUBuf(&UOB);
1198 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("bcdefgha"))) {
1199 return "swap fail 3";
1200 }
1201
1202 UsefulOutBuf_Reset(&UOB);
1203 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1204 UsefulOutBuf_Swap(&UOB, 0, 3, 4);
1205 Out = UsefulOutBuf_OutUBuf(&UOB);
1206 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("dabcefgh"))) {
1207 return "swap fail 4";
1208 }
1209
1210 UsefulOutBuf_Reset(&UOB);
1211 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1212 UsefulOutBuf_Swap(&UOB, 9, 10, 11);
1213 Out = UsefulOutBuf_OutUBuf(&UOB);
1214 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1215 return "swap fail 5";
1216 }
1217
1218 UsefulOutBuf_Reset(&UOB);
1219 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1220 UsefulOutBuf_Swap(&UOB, 0, 4, 11);
1221 Out = UsefulOutBuf_OutUBuf(&UOB);
1222 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1223 return "swap fail 6";
1224 }
1225
1226 UsefulOutBuf_Reset(&UOB);
1227 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1228 UsefulOutBuf_Swap(&UOB, 9, 0, 0);
1229 Out = UsefulOutBuf_OutUBuf(&UOB);
1230 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1231 return "swap fail 7";
1232 }
1233
1234 UsefulOutBuf_Reset(&UOB);
1235 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1236 UsefulOutBuf_Swap(&UOB, 0, 0, 0);
1237 Out = UsefulOutBuf_OutUBuf(&UOB);
1238 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1239 return "swap fail 8";
1240 }
1241
1242 UsefulOutBuf_Reset(&UOB);
1243 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1244 UsefulOutBuf_Swap(&UOB, 8, 4, 0);
1245 Out = UsefulOutBuf_OutUBuf(&UOB);
1246 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1247 return "swap fail 9";
1248 }
1249
1250 UsefulOutBuf_Reset(&UOB);
1251 UsefulOutBuf_AppendString(&UOB, "abcdefgh");
1252 UsefulOutBuf_Swap(&UOB, 0, 8, 4);
1253 Out = UsefulOutBuf_OutUBuf(&UOB);
1254 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcdefgh"))) {
1255 return "swap fail 10";
1256 }
1257
1258
1259 /* Test for UsefulOutBuf_GetOutput() */
1260 UsefulOutBuf_Reset(&UOB);
1261 UsefulOutBuf_AppendString(&UOB, "abc");
1262 UsefulOutBuf_AppendString(&UOB, "xyz");
1263
1264 Out = UsefulOutBuf_OutUBufOffset(&UOB, 0);
1265 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("abcxyz"))) {
1266 return "GetOutput fail 1";
1267 }
1268
1269 Out = UsefulOutBuf_OutUBufOffset(&UOB, 5);
1270 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("z"))) {
1271 return "GetOutput fail 2";
1272 }
1273
1274 Out = UsefulOutBuf_OutUBufOffset(&UOB, 1);
1275 if(UsefulBuf_Compare(Out, UsefulBuf_FROM_SZ_LITERAL("bcxyz"))) {
1276 return "GetOutput fail 3";
1277 }
1278
1279 Out = UsefulOutBuf_OutUBufOffset(&UOB, 6);
1280 if(!UsefulBuf_IsNULLC(Out)) {
1281 return "GetOutput fail 4";
1282 }
1283
1284 Out = UsefulOutBuf_OutUBufOffset(&UOB, 7);
1285 if(!UsefulBuf_IsNULLC(Out)) {
1286 return "GetOutput fail 5";
1287 }
1288
1289 return NULL;
1290}