blob: 1c2634e3db332f4daa87717efe5c8823e47e4996 [file] [log] [blame]
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladeac515e52020-01-30 10:44:06 -08003 Copyright (c) 2018-2020, Laurence Lundblade.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08004 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Laurence Lundbladeac515e52020-01-30 10:44:06 -080031 =============================================================================*/
Laurence Lundblade6ed34222018-12-18 09:46:23 -080032
33#include "UsefulBuf.h"
34
35
36/* Basic exercise...
37
38 Call all the main public functions.
39
40 Binary compare the result to the expected.
41
42 There is nothing adversarial in this test
43 */
44const char * UOBTest_NonAdversarial()
45{
46 const char *szReturn = NULL;
47
48 UsefulBuf_MAKE_STACK_UB(outbuf,50);
49
50 UsefulOutBuf UOB;
51
52 UsefulOutBuf_Init(&UOB, outbuf);
53
54 if(!UsefulOutBuf_AtStart(&UOB)) {
55 szReturn = "Not at start";
56 goto Done;
57 }
58
59 // Put 7 bytes at beginning of buf
60 UsefulOutBuf_AppendData(&UOB, "bluster", 7);
61
62 if(UsefulOutBuf_AtStart(&UOB)) {
63 szReturn = "At start";
64 goto Done;
65 }
66
67 // add a space to end
68 UsefulOutBuf_AppendByte(&UOB, ' ');
69
70 // Add 5 bytes to the end
71 UsefulBufC UBC = {"hunny", 5};
72 UsefulOutBuf_AppendUsefulBuf(&UOB, UBC);
73
74 // Insert 9 bytes at the beginning, slide the previous stuff right
75 UsefulOutBuf_InsertData(&UOB, "heffalump", 9, 0);
76 UsefulOutBuf_InsertByte(&UOB, ' ', 9);
77
78 // Put 9 bytes in at position 10 -- just after "heffalump "
79 UsefulBufC UBC2 = {"unbounce ", 9};
80 UsefulOutBuf_InsertUsefulBuf(&UOB, UBC2, 10);
81
Laurence Lundblade6ed34222018-12-18 09:46:23 -080082
Laurence Lundbladeac515e52020-01-30 10:44:06 -080083 const UsefulBufC Expected = UsefulBuf_FROM_SZ_LITERAL("heffalump unbounce bluster hunny");
Laurence Lundblade6ed34222018-12-18 09:46:23 -080084
85 UsefulBufC U = UsefulOutBuf_OutUBuf(&UOB);
Laurence Lundbladeac515e52020-01-30 10:44:06 -080086 if(UsefulBuf_IsNULLC(U) || UsefulBuf_Compare(Expected, U) || UsefulOutBuf_GetError(&UOB)) {
Laurence Lundblade6ed34222018-12-18 09:46:23 -080087 szReturn = "OutUBuf";
88 }
89
90 UsefulBuf_MAKE_STACK_UB(buf, 50);
91 UsefulBufC Out = UsefulOutBuf_CopyOut(&UOB, buf);
Laurence Lundbladeac515e52020-01-30 10:44:06 -080092 if(UsefulBuf_IsNULLC(Out) || UsefulBuf_Compare(Expected, Out)) {
Laurence Lundblade6ed34222018-12-18 09:46:23 -080093 szReturn = "CopyOut";
94 }
95
96Done:
97 return szReturn;
98}
99
100
101/*
102 Append test utility.
103 pUOB is the buffer to append too
104 num is the amount to append
105 expected is the expected return code, 0 or 1
106
107 returns 0 if test passed
108
109 */
110static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected)
111{
112 //reset
113 UsefulOutBuf_Reset(pUOB);
114
115 // check status first
116 if(UsefulOutBuf_GetError(pUOB))
117 return 1;
118
119 // append the bytes
120 UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num);
121
122 // check error status after
123 if(UsefulOutBuf_GetError(pUOB) != expected)
124 return 1;
125
126 return 0;
127}
128
129
130/*
131 Same as append, but takes a position param too
132 */
133static int InsertTest(UsefulOutBuf *pUOB, size_t num, size_t pos, int expected)
134{
135 // reset
136 UsefulOutBuf_Reset(pUOB);
137
138 // check
139 if(UsefulOutBuf_GetError(pUOB))
140 return 1;
141
142 UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos);
143
144 if(UsefulOutBuf_GetError(pUOB) != expected)
145 return 1;
146
147 return 0;
148}
149
150
151/*
152 Boundary conditions to test
153 - around 0
154 - around the buffer size
155 - around MAX size_t
156
157
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800158 Test these for the buffer size and the cursor, the insert amount, the
159 append amount and the insert position
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800160
161 */
162
163const char *UOBTest_BoundaryConditionsTest()
164{
165 UsefulBuf_MAKE_STACK_UB(outbuf,2);
166
167 UsefulOutBuf UOB;
168
169 UsefulOutBuf_Init(&UOB, outbuf);
170
171 // append 0 byte to a 2 byte buffer --> success
172 if(AppendTest(&UOB, 0, 0))
173 return "Append 0 bytes failed";
174
175 // append 1 byte to a 2 byte buffer --> success
176 if(AppendTest(&UOB, 1, 0))
177 return "Append of 1 byte failed";
178
179 // append 2 byte to a 2 byte buffer --> success
180 if(AppendTest(&UOB, 2, 0))
181 return "Append to fill buffer failed";
182
183 // append 3 bytes to a 2 byte buffer --> failure
184 if(AppendTest(&UOB, 3, 1))
185 return "Overflow of buffer not caught";
186
187 // append max size_t to a 2 byte buffer --> failure
188 if(AppendTest(&UOB, SIZE_MAX, 1))
189 return "Append of SIZE_MAX error not caught";
190
191 if(InsertTest(&UOB, 1, 0, 0))
192 return "Insert 1 byte at start failed";
193
194 if(InsertTest(&UOB, 2, 0, 0))
195 return "Insert 2 bytes at start failed";
196
197 if(InsertTest(&UOB, 3, 0, 1))
198 return "Insert overflow not caught";
199
200 if(InsertTest(&UOB, 1, 1, 1))
201 return "Bad insertion point not caught";
202
203
204 UsefulBuf_MAKE_STACK_UB(outBuf2,10);
205
206 UsefulOutBuf_Init(&UOB, outBuf2);
207
208 UsefulOutBuf_Reset(&UOB);
209 // put data in the buffer
210 UsefulOutBuf_AppendString(&UOB, "abc123");
211
212 UsefulOutBuf_InsertString(&UOB, "xyz*&^", 0);
213
214 if(!UsefulOutBuf_GetError(&UOB)) {
215 return "insert with data should have failed";
216 }
217
218
219 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
220 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
221 if(UsefulOutBuf_GetError(&UOB)) {
222 return "insert in huge should have succeeded";
223 }
224
225 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
226 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5);
227 if(UsefulOutBuf_GetError(&UOB)) {
228 return "insert in huge should have succeeded";
229 }
230
231 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
232 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4);
233 if(!UsefulOutBuf_GetError(&UOB)) {
234 return "lengths near max size";
235 }
236
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700237 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, 100});
238 if(!UsefulOutBuf_IsBufferNULL(&UOB)) {
239 return "NULL check failed";
240 }
241
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800242 return NULL;
243}
244
245
246
247
248
249// Test function to get size and magic number check
250
251const char *TestBasicSanity()
252{
253 UsefulBuf_MAKE_STACK_UB(outbuf,10);
254
255 UsefulOutBuf UOB;
256
257 // First -- make sure that the room left function returns the right amount
258 UsefulOutBuf_Init(&UOB, outbuf);
259
260 if(UsefulOutBuf_RoomLeft(&UOB) != 10)
261 return "room left failed";
262
263 if(!UsefulOutBuf_WillItFit(&UOB, 9)) {
264 return "it did not fit";
265 }
266
267 if(UsefulOutBuf_WillItFit(&UOB, 11)) {
268 return "it should have not fit";
269 }
270
271
272 // Next -- make sure that the magic number checking is working right
273 UOB.magic = 8888; // make magic bogus
274
275 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
276
277 if(!UsefulOutBuf_GetError(&UOB))
278 return "magic corruption check failed";
279
280
281
282 // Next make sure that the valid data length check is working right
283 UsefulOutBuf_Init(&UOB, outbuf);
284
285 UOB.data_len = UOB.UB.len+1; // make size bogus
286
287 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
288 if(!UsefulOutBuf_GetError(&UOB))
289 return "valid data check failed";
290
291 return NULL;
292}
293
294
295
296const char *UBMacroConversionsTest()
297{
298 char *szFoo = "foo";
299
300 UsefulBufC Foo = UsefulBuf_FromSZ(szFoo);
301 if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
302 return "SZToUsefulBufC failed";
303
304 UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo");
305 if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
306 return "UsefulBuf_FROM_SZ_LITERAL failed";
307
308 uint8_t pB[] = {0x42, 0x6f, 0x6f};
309 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
310 if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
311 return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
312
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800313 UsefulBuf B = (UsefulBuf){(void *)Too.ptr, Too.len};
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800314 UsefulBufC BC = UsefulBuf_Const(B);
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800315 if(BC.len != Too.len || BC.ptr != Too.ptr)
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800316 return "UsefulBufConst failed";
317
318 return NULL;
319}
320
321
322const char *UBUtilTests()
323{
324 UsefulBuf UB = NULLUsefulBuf;
325
326 if(!UsefulBuf_IsNULL(UB)){
327 return "IsNull failed";
328 }
329
330 if(!UsefulBuf_IsEmpty(UB)){
331 return "IsEmpty failed";
332 }
333
334 if(!UsefulBuf_IsNULLOrEmpty(UB)) {
335 return "IsNULLOrEmpty failed";
336 }
337
338 const UsefulBufC UBC = UsefulBuf_Const(UB);
339
340 if(!UsefulBuf_IsNULLC(UBC)){
341 return "IsNull const failed";
342 }
343
344 if(!UsefulBuf_IsEmptyC(UBC)){
345 return "IsEmptyC failed";
346 }
347
348 if(!UsefulBuf_IsNULLOrEmptyC(UBC)){
349 return "IsNULLOrEmptyC failed";
350 }
351
352 const UsefulBuf UB2 = UsefulBuf_Unconst(UBC);
353 if(!UsefulBuf_IsEmpty(UB2)) {
354 return "Back to UB is Empty failed";
355 }
356
357 UB.ptr = "x"; // just some valid pointer
358
359 if(UsefulBuf_IsNULL(UB)){
360 return "IsNull failed";
361 }
362
363 if(!UsefulBuf_IsEmptyC(UBC)){
364 return "IsEmpty failed";
365 }
366
367 // test the Unconst.
368 if(UsefulBuf_Unconst(UBC).ptr != NULL) {
369 return "Unconst failed";
370 }
371
372 // Set 100 bytes of '+'; validated a few tests later
373 UsefulBuf_MAKE_STACK_UB(Temp, 100);
374 const UsefulBufC TempC = UsefulBuf_Set(Temp, '+');
375
376 // Try to copy into a buf that is too small and see failure
377 UsefulBuf_MAKE_STACK_UB(Temp2, 99);
378 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp2, TempC))) {
379 return "Copy should have failed";
380 }
381
382 if(UsefulBuf_IsNULLC(UsefulBuf_CopyPtr(Temp2, "xx", 2))) {
383 return "CopyPtr failed";
384 }
385
386 UsefulBufC xxyy = UsefulBuf_CopyOffset(Temp2, 2, UsefulBuf_FROM_SZ_LITERAL("yy"));
387 if(UsefulBuf_IsNULLC(xxyy)) {
388 return "CopyOffset Failed";
389 }
390
391 if(UsefulBuf_Compare(UsefulBuf_Head(xxyy, 3), UsefulBuf_FROM_SZ_LITERAL("xxy"))) {
392 return "head failed";
393 }
394
395 if(UsefulBuf_Compare(UsefulBuf_Tail(xxyy, 1), UsefulBuf_FROM_SZ_LITERAL("xyy"))) {
396 return "tail failed";
397 }
398
399 if(!UsefulBuf_IsNULLC(UsefulBuf_Head(xxyy, 5))) {
400 return "head should have failed";
401 }
402
403 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(xxyy, 5))) {
404 return "tail should have failed";
405 }
406
407 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(NULLUsefulBufC, 0))) {
408 return "tail of NULLUsefulBufC is not NULLUsefulBufC";
409 }
410
411 const UsefulBufC TailResult = UsefulBuf_Tail((UsefulBufC){NULL, 100}, 99);
412 if(TailResult.ptr != NULL || TailResult.len != 1) {
413 return "tail of NULL and length incorrect";
414 }
415
416 if(!UsefulBuf_IsNULLC(UsefulBuf_CopyOffset(Temp2, 100, UsefulBuf_FROM_SZ_LITERAL("yy")))) {
417 return "Copy Offset should have failed";
418 }
419
420 // Try to copy into a NULL/empty buf and see failure
421 const UsefulBuf UBNull = NULLUsefulBuf;
422 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(UBNull, TempC))) {
423 return "Copy to NULL should have failed";
424 }
425
426
427 // Try to set a NULL/empty buf; nothing should happen
428 UsefulBuf_Set(UBNull, '+'); // This will crash on failure
429
430 // Copy successfully to a buffer
431 UsefulBuf_MAKE_STACK_UB(Temp3, 101);
432 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp3, TempC))) {
433 return "Copy should not have failed";
434 }
435
436 static const uint8_t pExpected[] = {
437 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
438 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
439 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
440 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
441 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
442 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
443 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
444 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
445 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
446 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
447 };
448 UsefulBufC Expected = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpected);
449 // This validates comparison for equality and the UsefulBuf_Set
450 if(UsefulBuf_Compare(Expected, TempC)) {
451 return "Set / Copy / Compare failed";
452 }
453
454 // Compare two empties and expect success
455 if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){
456 return "Compare Empties failed";
457 }
458
459 // Compare with empty and expect the first to be larger
460 if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){
461 return "Compare with empty failed";
462 }
463
464
465 static const uint8_t pExpectedBigger[] = {
466 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
467 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
468 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
469 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
470 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
471 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
472 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
473 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
474 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
475 '+', '+', '+', '+', '+', '+', '+', '+', '+', ',',
476 };
477 const UsefulBufC ExpectedBigger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedBigger);
478
479 // Expect -1 when the first arg is smaller
480 if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){
481 return "Compare with bigger";
482 }
483
484
485 static const uint8_t pExpectedSmaller[] = {
486 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
487 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
488 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
489 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
490 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
491 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
492 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
493 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
494 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
495 '+', '+', '+', '+', '+', '+', '+', '+', '+', '*',
496 };
497 const UsefulBufC ExpectedSmaller = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedSmaller);
498 // Expect +1 when the first arg is larger
499 if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){
500 return "Compare with smaller";
501 }
502
503
504 static const uint8_t pExpectedLonger[] = {
505 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
506 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
507 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
508 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
509 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
510 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
511 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
512 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
513 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
514 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+'
515 };
516 const UsefulBufC ExpectedLonger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedLonger);
517
518 // Expect -1 when the first arg is smaller
519 if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){
520 return "Compare with longer";
521 }
522
523
524 static const uint8_t pExpectedShorter[] = {
525 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
526 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
527 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
528 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
529 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
530 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
531 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
532 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
533 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
534 '+', '+', '+', '+', '+', '+', '+', '+', '+',
535 };
536 const UsefulBufC ExpectedShorter = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedShorter);
537 // Expect +1 with the first arg is larger
538 if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){
539 return "Compare with shorter";
540 }
541
542
543 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp, NULLUsefulBufC))) {
544 return "Copy null/empty failed";
545 }
546
Laurence Lundbladed85dbb72019-03-07 18:27:18 -0800547 if(UsefulBuf_IsValue(ExpectedShorter, '+') != SIZE_MAX) {
548 return "IsValue failed to match all";
549 }
550
551 if(UsefulBuf_IsValue(ExpectedShorter, '-') != 0) {
552 return "IsValue should have failed right away";
553 }
554
555 if(UsefulBuf_IsValue(NULLUsefulBufC, 0x00) != 0) {
556 return "IsValue failed on NULLUsefulBufC";
557 }
558
559 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x00) != SIZE_MAX) {
560 return "IsValue failed finding 0 in one byte of 0";
561 }
562
563 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x01) != 0) {
564 return "IsValue failed not finding 1 in one byte of 0";
565 }
566
567 if(UsefulBuf_IsValue(ExpectedSmaller, '+') != ExpectedSmaller.len -1) {
568 return "IsValue failed to find final *";
569 }
570
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800571 // Look for +++++... in +++++... and find it at the beginning
572 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
573 return "Failed to find";
574 }
575
576 // look for ++* in ....++* and find it at the end
577 static const uint8_t pToFind[] = {'+', '+', '*'};
578 const UsefulBufC ToBeFound = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pToFind);
579
580 if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){
581 return "Failed to find 2";
582 }
583
584 // look for ++* in ....++, and find it near the end
585 if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){
586 return "Failed to not find";
587 }
588
589 // Look for the whole buffer in itself and succeed.
590 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){
591 return "Failed to find 3";
592 }
593
594 return NULL;
595}
596
597
598const char * UIBTest_IntegerFormat()
599{
600 UsefulOutBuf_MakeOnStack(UOB,100);
601
602 const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
603 const uint64_t u64 = 1984738472938472;
604 const uint16_t u16 = 40000;
605 const uint8_t u8 = 9;
606 const float f = (float)314.15;
607 const double d = 2.1e10;
608
609
610 UsefulOutBuf_AppendUint32(&UOB, u32); // Also tests UsefulOutBuf_InsertUint64 and UsefulOutBuf_GetEndPosition
611 UsefulOutBuf_AppendUint64(&UOB, u64); // Also tests UsefulOutBuf_InsertUint32
612 UsefulOutBuf_AppendUint16(&UOB, u16); // Also tests UsefulOutBuf_InsertUint16
613 UsefulOutBuf_AppendByte(&UOB, u8);
614 UsefulOutBuf_AppendFloat(&UOB, f); // Also tests UsefulOutBuf_InsertFloat
615 UsefulOutBuf_AppendDouble(&UOB, d); // Also tests UsefulOutBuf_InsertDouble
616
617 const UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
618 if(UsefulBuf_IsNULLC(O))
619 return "Couldn't output integers";
620
621 // from https://en.wikipedia.org/wiki/Endianness
622 const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D};
623 if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) {
624 return "not in network order";
625 }
626
627 UsefulInputBuf UIB;
628
629 UsefulInputBuf_Init(&UIB, O);
630
631 if(UsefulInputBuf_Tell(&UIB) != 0) {
632 return "UsefulInputBuf_Tell failed";
633 }
634
635 if(UsefulInputBuf_GetUint32(&UIB) != u32) {
636 return "u32 out then in failed";
637 }
638 if(UsefulInputBuf_GetUint64(&UIB) != u64) {
639 return "u64 out then in failed";
640 }
641 if(UsefulInputBuf_GetUint16(&UIB) != u16) {
642 return "u16 out then in failed";
643 }
644 if(UsefulInputBuf_GetByte(&UIB) != u8) {
645 return "u8 out then in failed";
646 }
647 if(UsefulInputBuf_GetFloat(&UIB) != f) {
648 return "float out then in failed";
649 }
650 if(UsefulInputBuf_GetDouble(&UIB) != d) {
651 return "double out then in failed";
652 }
653
654 // Reset and go again for a few more tests
655 UsefulInputBuf_Init(&UIB, O);
656
657 const UsefulBufC Four = UsefulInputBuf_GetUsefulBuf(&UIB, 4);
658 if(UsefulBuf_IsNULLC(Four)) {
659 return "Four is NULL";
660 }
661 if(UsefulBuf_Compare(Four, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedNetworkOrder))) {
662 return "Four compare failed";
663 }
664
665 if(UsefulInputBuf_BytesUnconsumed(&UIB) != 23){
666 return "Wrong number of unconsumed bytes";
667 }
668
669 if(!UsefulInputBuf_BytesAvailable(&UIB, 23)){
670 return "Wrong number of bytes available I";
671 }
672
673 if(UsefulInputBuf_BytesAvailable(&UIB, 24)){
674 return "Wrong number of bytes available II";
675 }
676
677 UsefulInputBuf_Seek(&UIB, 0);
678
679 if(UsefulInputBuf_GetError(&UIB)) {
680 return "unexpected error after seek";
681 }
682
683 const uint8_t *pGetBytes = (const uint8_t *)UsefulInputBuf_GetBytes(&UIB, 4);
684 if(pGetBytes == NULL) {
685 return "GetBytes returns NULL";
686 }
687
688 if(memcmp(pGetBytes, pExpectedNetworkOrder, 4)) {
689 return "Got wrong bytes";
690 }
691
692 UsefulInputBuf_Seek(&UIB, 28);
693
694 if(!UsefulInputBuf_GetError(&UIB)) {
695 return "expected error after seek";
696 }
697
698 return NULL;
699}
700
701
702const char *UBUTest_CopyUtil()
703{
704 if(UsefulBufUtil_CopyFloatToUint32(65536.0F) != 0x47800000) {
705 return "CopyFloatToUint32 failed";
706 }
707
708 if(UsefulBufUtil_CopyDoubleToUint64(4e-40F) != 0X37C16C2800000000ULL) {
709 return "CopyDoubleToUint64 failed";
710 }
711
712 if(UsefulBufUtil_CopyUint64ToDouble(0X37C16C2800000000ULL) != 4e-40F) {
713 return "CopyUint64ToDouble failed";
714 }
715
716 if(UsefulBufUtil_CopyUint32ToFloat(0x47800000) != 65536.0F) {
717 return "CopyUint32ToFloat failed";
718 }
719
720 return NULL;
721}
722
723
724