blob: 388f8cfd7e6edc30ab5849b31bc3db66cbecac7a [file] [log] [blame]
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018-2019, Laurence Lundblade.
4 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.
31 ==============================================================================*/
32
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
82 // Make it a null terminated string (because all the appends and inserts above not strcpy !)
83 UsefulOutBuf_AppendByte(&UOB, '\0');
84
85
86 UsefulBufC U = UsefulOutBuf_OutUBuf(&UOB);
87
88 const char *expected = "heffalump unbounce bluster hunny";
89
90 if(UsefulBuf_IsNULLC(U) || U.len-1 != strlen(expected) || strcmp(expected, U.ptr) || UsefulOutBuf_GetError(&UOB)) {
91 szReturn = "OutUBuf";
92 }
93
94 UsefulBuf_MAKE_STACK_UB(buf, 50);
95 UsefulBufC Out = UsefulOutBuf_CopyOut(&UOB, buf);
96
97 if(UsefulBuf_IsNULLC(Out) || Out.len-1 != strlen(expected) || strcmp(expected, Out.ptr)) {
98 szReturn = "CopyOut";
99 }
100
101Done:
102 return szReturn;
103}
104
105
106/*
107 Append test utility.
108 pUOB is the buffer to append too
109 num is the amount to append
110 expected is the expected return code, 0 or 1
111
112 returns 0 if test passed
113
114 */
115static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected)
116{
117 //reset
118 UsefulOutBuf_Reset(pUOB);
119
120 // check status first
121 if(UsefulOutBuf_GetError(pUOB))
122 return 1;
123
124 // append the bytes
125 UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num);
126
127 // check error status after
128 if(UsefulOutBuf_GetError(pUOB) != expected)
129 return 1;
130
131 return 0;
132}
133
134
135/*
136 Same as append, but takes a position param too
137 */
138static int InsertTest(UsefulOutBuf *pUOB, size_t num, size_t pos, int expected)
139{
140 // reset
141 UsefulOutBuf_Reset(pUOB);
142
143 // check
144 if(UsefulOutBuf_GetError(pUOB))
145 return 1;
146
147 UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos);
148
149 if(UsefulOutBuf_GetError(pUOB) != expected)
150 return 1;
151
152 return 0;
153}
154
155
156/*
157 Boundary conditions to test
158 - around 0
159 - around the buffer size
160 - around MAX size_t
161
162
163 Test these for the buffer size and the cursor, the insert amount, the append amount and the insert position
164
165 */
166
167const char *UOBTest_BoundaryConditionsTest()
168{
169 UsefulBuf_MAKE_STACK_UB(outbuf,2);
170
171 UsefulOutBuf UOB;
172
173 UsefulOutBuf_Init(&UOB, outbuf);
174
175 // append 0 byte to a 2 byte buffer --> success
176 if(AppendTest(&UOB, 0, 0))
177 return "Append 0 bytes failed";
178
179 // append 1 byte to a 2 byte buffer --> success
180 if(AppendTest(&UOB, 1, 0))
181 return "Append of 1 byte failed";
182
183 // append 2 byte to a 2 byte buffer --> success
184 if(AppendTest(&UOB, 2, 0))
185 return "Append to fill buffer failed";
186
187 // append 3 bytes to a 2 byte buffer --> failure
188 if(AppendTest(&UOB, 3, 1))
189 return "Overflow of buffer not caught";
190
191 // append max size_t to a 2 byte buffer --> failure
192 if(AppendTest(&UOB, SIZE_MAX, 1))
193 return "Append of SIZE_MAX error not caught";
194
195 if(InsertTest(&UOB, 1, 0, 0))
196 return "Insert 1 byte at start failed";
197
198 if(InsertTest(&UOB, 2, 0, 0))
199 return "Insert 2 bytes at start failed";
200
201 if(InsertTest(&UOB, 3, 0, 1))
202 return "Insert overflow not caught";
203
204 if(InsertTest(&UOB, 1, 1, 1))
205 return "Bad insertion point not caught";
206
207
208 UsefulBuf_MAKE_STACK_UB(outBuf2,10);
209
210 UsefulOutBuf_Init(&UOB, outBuf2);
211
212 UsefulOutBuf_Reset(&UOB);
213 // put data in the buffer
214 UsefulOutBuf_AppendString(&UOB, "abc123");
215
216 UsefulOutBuf_InsertString(&UOB, "xyz*&^", 0);
217
218 if(!UsefulOutBuf_GetError(&UOB)) {
219 return "insert with data should have failed";
220 }
221
222
223 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
224 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
225 if(UsefulOutBuf_GetError(&UOB)) {
226 return "insert in huge should have succeeded";
227 }
228
229 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
230 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5);
231 if(UsefulOutBuf_GetError(&UOB)) {
232 return "insert in huge should have succeeded";
233 }
234
235 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
236 UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4);
237 if(!UsefulOutBuf_GetError(&UOB)) {
238 return "lengths near max size";
239 }
240
241 return NULL;
242}
243
244
245
246
247
248// Test function to get size and magic number check
249
250const char *TestBasicSanity()
251{
252 UsefulBuf_MAKE_STACK_UB(outbuf,10);
253
254 UsefulOutBuf UOB;
255
256 // First -- make sure that the room left function returns the right amount
257 UsefulOutBuf_Init(&UOB, outbuf);
258
259 if(UsefulOutBuf_RoomLeft(&UOB) != 10)
260 return "room left failed";
261
262 if(!UsefulOutBuf_WillItFit(&UOB, 9)) {
263 return "it did not fit";
264 }
265
266 if(UsefulOutBuf_WillItFit(&UOB, 11)) {
267 return "it should have not fit";
268 }
269
270
271 // Next -- make sure that the magic number checking is working right
272 UOB.magic = 8888; // make magic bogus
273
274 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
275
276 if(!UsefulOutBuf_GetError(&UOB))
277 return "magic corruption check failed";
278
279
280
281 // Next make sure that the valid data length check is working right
282 UsefulOutBuf_Init(&UOB, outbuf);
283
284 UOB.data_len = UOB.UB.len+1; // make size bogus
285
286 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
287 if(!UsefulOutBuf_GetError(&UOB))
288 return "valid data check failed";
289
290 return NULL;
291}
292
293
294
295const char *UBMacroConversionsTest()
296{
297 char *szFoo = "foo";
298
299 UsefulBufC Foo = UsefulBuf_FromSZ(szFoo);
300 if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
301 return "SZToUsefulBufC failed";
302
303 UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo");
304 if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
305 return "UsefulBuf_FROM_SZ_LITERAL failed";
306
307 uint8_t pB[] = {0x42, 0x6f, 0x6f};
308 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
309 if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
310 return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
311
312 char *sz = "not const"; // some data for the test
313 UsefulBuf B = (UsefulBuf){sz, sizeof(sz)};
314 UsefulBufC BC = UsefulBuf_Const(B);
315 if(BC.len != sizeof(sz) || BC.ptr != sz)
316 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