blob: f53693a1b8863be80406fef903135719ff5aad10 [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
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700241 UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, 100});
242 if(!UsefulOutBuf_IsBufferNULL(&UOB)) {
243 return "NULL check failed";
244 }
245
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800246 return NULL;
247}
248
249
250
251
252
253// Test function to get size and magic number check
254
255const char *TestBasicSanity()
256{
257 UsefulBuf_MAKE_STACK_UB(outbuf,10);
258
259 UsefulOutBuf UOB;
260
261 // First -- make sure that the room left function returns the right amount
262 UsefulOutBuf_Init(&UOB, outbuf);
263
264 if(UsefulOutBuf_RoomLeft(&UOB) != 10)
265 return "room left failed";
266
267 if(!UsefulOutBuf_WillItFit(&UOB, 9)) {
268 return "it did not fit";
269 }
270
271 if(UsefulOutBuf_WillItFit(&UOB, 11)) {
272 return "it should have not fit";
273 }
274
275
276 // Next -- make sure that the magic number checking is working right
277 UOB.magic = 8888; // make magic bogus
278
279 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
280
281 if(!UsefulOutBuf_GetError(&UOB))
282 return "magic corruption check failed";
283
284
285
286 // Next make sure that the valid data length check is working right
287 UsefulOutBuf_Init(&UOB, outbuf);
288
289 UOB.data_len = UOB.UB.len+1; // make size bogus
290
291 UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
292 if(!UsefulOutBuf_GetError(&UOB))
293 return "valid data check failed";
294
295 return NULL;
296}
297
298
299
300const char *UBMacroConversionsTest()
301{
302 char *szFoo = "foo";
303
304 UsefulBufC Foo = UsefulBuf_FromSZ(szFoo);
305 if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
306 return "SZToUsefulBufC failed";
307
308 UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo");
309 if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
310 return "UsefulBuf_FROM_SZ_LITERAL failed";
311
312 uint8_t pB[] = {0x42, 0x6f, 0x6f};
313 UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
314 if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
315 return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
316
317 char *sz = "not const"; // some data for the test
318 UsefulBuf B = (UsefulBuf){sz, sizeof(sz)};
319 UsefulBufC BC = UsefulBuf_Const(B);
320 if(BC.len != sizeof(sz) || BC.ptr != sz)
321 return "UsefulBufConst failed";
322
323 return NULL;
324}
325
326
327const char *UBUtilTests()
328{
329 UsefulBuf UB = NULLUsefulBuf;
330
331 if(!UsefulBuf_IsNULL(UB)){
332 return "IsNull failed";
333 }
334
335 if(!UsefulBuf_IsEmpty(UB)){
336 return "IsEmpty failed";
337 }
338
339 if(!UsefulBuf_IsNULLOrEmpty(UB)) {
340 return "IsNULLOrEmpty failed";
341 }
342
343 const UsefulBufC UBC = UsefulBuf_Const(UB);
344
345 if(!UsefulBuf_IsNULLC(UBC)){
346 return "IsNull const failed";
347 }
348
349 if(!UsefulBuf_IsEmptyC(UBC)){
350 return "IsEmptyC failed";
351 }
352
353 if(!UsefulBuf_IsNULLOrEmptyC(UBC)){
354 return "IsNULLOrEmptyC failed";
355 }
356
357 const UsefulBuf UB2 = UsefulBuf_Unconst(UBC);
358 if(!UsefulBuf_IsEmpty(UB2)) {
359 return "Back to UB is Empty failed";
360 }
361
362 UB.ptr = "x"; // just some valid pointer
363
364 if(UsefulBuf_IsNULL(UB)){
365 return "IsNull failed";
366 }
367
368 if(!UsefulBuf_IsEmptyC(UBC)){
369 return "IsEmpty failed";
370 }
371
372 // test the Unconst.
373 if(UsefulBuf_Unconst(UBC).ptr != NULL) {
374 return "Unconst failed";
375 }
376
377 // Set 100 bytes of '+'; validated a few tests later
378 UsefulBuf_MAKE_STACK_UB(Temp, 100);
379 const UsefulBufC TempC = UsefulBuf_Set(Temp, '+');
380
381 // Try to copy into a buf that is too small and see failure
382 UsefulBuf_MAKE_STACK_UB(Temp2, 99);
383 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp2, TempC))) {
384 return "Copy should have failed";
385 }
386
387 if(UsefulBuf_IsNULLC(UsefulBuf_CopyPtr(Temp2, "xx", 2))) {
388 return "CopyPtr failed";
389 }
390
391 UsefulBufC xxyy = UsefulBuf_CopyOffset(Temp2, 2, UsefulBuf_FROM_SZ_LITERAL("yy"));
392 if(UsefulBuf_IsNULLC(xxyy)) {
393 return "CopyOffset Failed";
394 }
395
396 if(UsefulBuf_Compare(UsefulBuf_Head(xxyy, 3), UsefulBuf_FROM_SZ_LITERAL("xxy"))) {
397 return "head failed";
398 }
399
400 if(UsefulBuf_Compare(UsefulBuf_Tail(xxyy, 1), UsefulBuf_FROM_SZ_LITERAL("xyy"))) {
401 return "tail failed";
402 }
403
404 if(!UsefulBuf_IsNULLC(UsefulBuf_Head(xxyy, 5))) {
405 return "head should have failed";
406 }
407
408 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(xxyy, 5))) {
409 return "tail should have failed";
410 }
411
412 if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(NULLUsefulBufC, 0))) {
413 return "tail of NULLUsefulBufC is not NULLUsefulBufC";
414 }
415
416 const UsefulBufC TailResult = UsefulBuf_Tail((UsefulBufC){NULL, 100}, 99);
417 if(TailResult.ptr != NULL || TailResult.len != 1) {
418 return "tail of NULL and length incorrect";
419 }
420
421 if(!UsefulBuf_IsNULLC(UsefulBuf_CopyOffset(Temp2, 100, UsefulBuf_FROM_SZ_LITERAL("yy")))) {
422 return "Copy Offset should have failed";
423 }
424
425 // Try to copy into a NULL/empty buf and see failure
426 const UsefulBuf UBNull = NULLUsefulBuf;
427 if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(UBNull, TempC))) {
428 return "Copy to NULL should have failed";
429 }
430
431
432 // Try to set a NULL/empty buf; nothing should happen
433 UsefulBuf_Set(UBNull, '+'); // This will crash on failure
434
435 // Copy successfully to a buffer
436 UsefulBuf_MAKE_STACK_UB(Temp3, 101);
437 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp3, TempC))) {
438 return "Copy should not have failed";
439 }
440
441 static const uint8_t pExpected[] = {
442 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
443 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
444 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
445 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
446 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
447 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
448 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
449 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
450 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
451 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
452 };
453 UsefulBufC Expected = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpected);
454 // This validates comparison for equality and the UsefulBuf_Set
455 if(UsefulBuf_Compare(Expected, TempC)) {
456 return "Set / Copy / Compare failed";
457 }
458
459 // Compare two empties and expect success
460 if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){
461 return "Compare Empties failed";
462 }
463
464 // Compare with empty and expect the first to be larger
465 if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){
466 return "Compare with empty failed";
467 }
468
469
470 static const uint8_t pExpectedBigger[] = {
471 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
472 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
473 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
474 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
475 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
476 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
477 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
478 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
479 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
480 '+', '+', '+', '+', '+', '+', '+', '+', '+', ',',
481 };
482 const UsefulBufC ExpectedBigger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedBigger);
483
484 // Expect -1 when the first arg is smaller
485 if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){
486 return "Compare with bigger";
487 }
488
489
490 static const uint8_t pExpectedSmaller[] = {
491 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
492 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
493 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
494 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
495 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
496 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
497 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
498 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
499 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
500 '+', '+', '+', '+', '+', '+', '+', '+', '+', '*',
501 };
502 const UsefulBufC ExpectedSmaller = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedSmaller);
503 // Expect +1 when the first arg is larger
504 if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){
505 return "Compare with smaller";
506 }
507
508
509 static const uint8_t pExpectedLonger[] = {
510 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
511 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
512 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
513 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
514 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
515 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
516 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
517 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
518 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
519 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+'
520 };
521 const UsefulBufC ExpectedLonger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedLonger);
522
523 // Expect -1 when the first arg is smaller
524 if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){
525 return "Compare with longer";
526 }
527
528
529 static const uint8_t pExpectedShorter[] = {
530 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
531 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
532 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
533 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
534 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
535 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
536 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
537 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
538 '+', '+', '+', '+', '+', '+', '+', '+', '+', '+',
539 '+', '+', '+', '+', '+', '+', '+', '+', '+',
540 };
541 const UsefulBufC ExpectedShorter = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedShorter);
542 // Expect +1 with the first arg is larger
543 if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){
544 return "Compare with shorter";
545 }
546
547
548 if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp, NULLUsefulBufC))) {
549 return "Copy null/empty failed";
550 }
551
Laurence Lundbladed85dbb72019-03-07 18:27:18 -0800552 if(UsefulBuf_IsValue(ExpectedShorter, '+') != SIZE_MAX) {
553 return "IsValue failed to match all";
554 }
555
556 if(UsefulBuf_IsValue(ExpectedShorter, '-') != 0) {
557 return "IsValue should have failed right away";
558 }
559
560 if(UsefulBuf_IsValue(NULLUsefulBufC, 0x00) != 0) {
561 return "IsValue failed on NULLUsefulBufC";
562 }
563
564 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x00) != SIZE_MAX) {
565 return "IsValue failed finding 0 in one byte of 0";
566 }
567
568 if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x01) != 0) {
569 return "IsValue failed not finding 1 in one byte of 0";
570 }
571
572 if(UsefulBuf_IsValue(ExpectedSmaller, '+') != ExpectedSmaller.len -1) {
573 return "IsValue failed to find final *";
574 }
575
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800576 // Look for +++++... in +++++... and find it at the beginning
577 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
578 return "Failed to find";
579 }
580
581 // look for ++* in ....++* and find it at the end
582 static const uint8_t pToFind[] = {'+', '+', '*'};
583 const UsefulBufC ToBeFound = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pToFind);
584
585 if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){
586 return "Failed to find 2";
587 }
588
589 // look for ++* in ....++, and find it near the end
590 if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){
591 return "Failed to not find";
592 }
593
594 // Look for the whole buffer in itself and succeed.
595 if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){
596 return "Failed to find 3";
597 }
598
599 return NULL;
600}
601
602
603const char * UIBTest_IntegerFormat()
604{
605 UsefulOutBuf_MakeOnStack(UOB,100);
606
607 const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
608 const uint64_t u64 = 1984738472938472;
609 const uint16_t u16 = 40000;
610 const uint8_t u8 = 9;
611 const float f = (float)314.15;
612 const double d = 2.1e10;
613
614
615 UsefulOutBuf_AppendUint32(&UOB, u32); // Also tests UsefulOutBuf_InsertUint64 and UsefulOutBuf_GetEndPosition
616 UsefulOutBuf_AppendUint64(&UOB, u64); // Also tests UsefulOutBuf_InsertUint32
617 UsefulOutBuf_AppendUint16(&UOB, u16); // Also tests UsefulOutBuf_InsertUint16
618 UsefulOutBuf_AppendByte(&UOB, u8);
619 UsefulOutBuf_AppendFloat(&UOB, f); // Also tests UsefulOutBuf_InsertFloat
620 UsefulOutBuf_AppendDouble(&UOB, d); // Also tests UsefulOutBuf_InsertDouble
621
622 const UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
623 if(UsefulBuf_IsNULLC(O))
624 return "Couldn't output integers";
625
626 // from https://en.wikipedia.org/wiki/Endianness
627 const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D};
628 if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) {
629 return "not in network order";
630 }
631
632 UsefulInputBuf UIB;
633
634 UsefulInputBuf_Init(&UIB, O);
635
636 if(UsefulInputBuf_Tell(&UIB) != 0) {
637 return "UsefulInputBuf_Tell failed";
638 }
639
640 if(UsefulInputBuf_GetUint32(&UIB) != u32) {
641 return "u32 out then in failed";
642 }
643 if(UsefulInputBuf_GetUint64(&UIB) != u64) {
644 return "u64 out then in failed";
645 }
646 if(UsefulInputBuf_GetUint16(&UIB) != u16) {
647 return "u16 out then in failed";
648 }
649 if(UsefulInputBuf_GetByte(&UIB) != u8) {
650 return "u8 out then in failed";
651 }
652 if(UsefulInputBuf_GetFloat(&UIB) != f) {
653 return "float out then in failed";
654 }
655 if(UsefulInputBuf_GetDouble(&UIB) != d) {
656 return "double out then in failed";
657 }
658
659 // Reset and go again for a few more tests
660 UsefulInputBuf_Init(&UIB, O);
661
662 const UsefulBufC Four = UsefulInputBuf_GetUsefulBuf(&UIB, 4);
663 if(UsefulBuf_IsNULLC(Four)) {
664 return "Four is NULL";
665 }
666 if(UsefulBuf_Compare(Four, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedNetworkOrder))) {
667 return "Four compare failed";
668 }
669
670 if(UsefulInputBuf_BytesUnconsumed(&UIB) != 23){
671 return "Wrong number of unconsumed bytes";
672 }
673
674 if(!UsefulInputBuf_BytesAvailable(&UIB, 23)){
675 return "Wrong number of bytes available I";
676 }
677
678 if(UsefulInputBuf_BytesAvailable(&UIB, 24)){
679 return "Wrong number of bytes available II";
680 }
681
682 UsefulInputBuf_Seek(&UIB, 0);
683
684 if(UsefulInputBuf_GetError(&UIB)) {
685 return "unexpected error after seek";
686 }
687
688 const uint8_t *pGetBytes = (const uint8_t *)UsefulInputBuf_GetBytes(&UIB, 4);
689 if(pGetBytes == NULL) {
690 return "GetBytes returns NULL";
691 }
692
693 if(memcmp(pGetBytes, pExpectedNetworkOrder, 4)) {
694 return "Got wrong bytes";
695 }
696
697 UsefulInputBuf_Seek(&UIB, 28);
698
699 if(!UsefulInputBuf_GetError(&UIB)) {
700 return "expected error after seek";
701 }
702
703 return NULL;
704}
705
706
707const char *UBUTest_CopyUtil()
708{
709 if(UsefulBufUtil_CopyFloatToUint32(65536.0F) != 0x47800000) {
710 return "CopyFloatToUint32 failed";
711 }
712
713 if(UsefulBufUtil_CopyDoubleToUint64(4e-40F) != 0X37C16C2800000000ULL) {
714 return "CopyDoubleToUint64 failed";
715 }
716
717 if(UsefulBufUtil_CopyUint64ToDouble(0X37C16C2800000000ULL) != 4e-40F) {
718 return "CopyUint64ToDouble failed";
719 }
720
721 if(UsefulBufUtil_CopyUint32ToFloat(0x47800000) != 65536.0F) {
722 return "CopyUint32ToFloat failed";
723 }
724
725 return NULL;
726}
727
728
729