2#include <winpr/print.h>
3#include <winpr/crypto.h>
4#include <winpr/stream.h>
7static BOOL TestStream_Verify(
wStream* s,
size_t mincap,
size_t len,
size_t pos)
9 if (Stream_Buffer(s) ==
nullptr)
11 printf(
"stream buffer is null\n");
15 if (Stream_ConstPointer(s) ==
nullptr)
17 printf(
"stream pointer is null\n");
21 if (Stream_PointerAs(s, BYTE) < Stream_Buffer(s))
23 printf(
"stream pointer (%p) or buffer (%p) is invalid\n", Stream_ConstPointer(s),
24 (
void*)Stream_Buffer(s));
28 if (Stream_Capacity(s) < mincap)
30 printf(
"stream capacity is %" PRIuz
" but minimum expected value is %" PRIuz
"\n",
31 Stream_Capacity(s), mincap);
35 if (Stream_Length(s) != len)
37 printf(
"stream has unexpected length (%" PRIuz
" instead of %" PRIuz
")\n",
38 Stream_Length(s), len);
42 if (Stream_GetPosition(s) != pos)
44 printf(
"stream has unexpected position (%" PRIuz
" instead of %" PRIuz
")\n",
45 Stream_GetPosition(s), pos);
49 if (Stream_GetPosition(s) > Stream_Length(s))
51 printf(
"stream position (%" PRIuz
") exceeds length (%" PRIuz
")\n", Stream_GetPosition(s),
56 if (Stream_GetPosition(s) > Stream_Capacity(s))
58 printf(
"stream position (%" PRIuz
") exceeds capacity (%" PRIuz
")\n",
59 Stream_GetPosition(s), Stream_Capacity(s));
63 if (Stream_Length(s) > Stream_Capacity(s))
65 printf(
"stream length (%" PRIuz
") exceeds capacity (%" PRIuz
")\n", Stream_Length(s),
70 if (Stream_GetRemainingLength(s) != len - pos)
72 printf(
"stream remaining length (%" PRIuz
" instead of %" PRIuz
")\n",
73 Stream_GetRemainingLength(s), len - pos);
81static BOOL TestStream_New(
void)
84 wStream* s = Stream_New(
nullptr, 0);
94static BOOL TestStream_Static(
void)
96 BYTE buffer[20] = WINPR_C_ARRAY_INIT;
97 wStream staticStream = WINPR_C_ARRAY_INIT;
101 Stream_StaticInit(s, buffer,
sizeof(buffer));
102 Stream_Write_UINT16(s, 0xcab1);
103 Stream_ResetPosition(s);
104 Stream_Read_UINT16(s, v);
109 Stream_ResetPosition(s);
110 Stream_Write_UINT16(s, 1);
112 if (!Stream_EnsureRemainingCapacity(s, 10))
116 if (!Stream_EnsureRemainingCapacity(s, 30) || !s->isOwner)
119 Stream_Write_UINT16(s, 2);
120 Stream_ResetPosition(s);
121 Stream_Read_UINT16(s, v);
126 Stream_Read_UINT16(s, v);
134 WINPR_PRAGMA_DIAG_PUSH
135 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
136 Stream_Free(s, TRUE);
137 WINPR_PRAGMA_DIAG_POP
142static BOOL TestStream_Create(
size_t count, BOOL selfAlloc)
147 void* buffer =
nullptr;
149 for (
size_t i = 0; i < count; i++)
155 if (!(buffer = malloc(cap)))
157 printf(
"%s: failed to allocate buffer of size %" PRIuz
"\n", __func__, cap);
162 if (!(s = Stream_New(selfAlloc ? buffer : nullptr, len)))
164 printf(
"%s: Stream_New failed for stream #%" PRIuz
"\n", __func__, i);
168 if (!TestStream_Verify(s, cap, len, 0))
173 for (
size_t pos = 0; pos < len; pos++)
175 if (!Stream_SetPosition(s, pos))
177 Stream_SealLength(s);
179 if (!TestStream_Verify(s, cap, pos, pos))
187 memset(buffer, (BYTE)(i % 256), cap);
189 if (memcmp(buffer, Stream_Buffer(s), cap) != 0)
191 printf(
"%s: buffer memory corruption\n", __func__);
196 Stream_Free(s, buffer ==
nullptr);
206 Stream_Free(s, buffer ==
nullptr);
213static BOOL TestStream_Extent(UINT32 maxSize)
218 if (!(s = Stream_New(
nullptr, 1)))
220 printf(
"%s: Stream_New failed\n", __func__);
224 for (UINT32 i = 1; i < maxSize; i++)
228 if (!Stream_EnsureRemainingCapacity(s, i))
233 if (!Stream_EnsureCapacity(s, i))
237 if (!Stream_SetPosition(s, i))
239 Stream_SealLength(s);
241 if (!TestStream_Verify(s, i, i, i))
243 printf(
"%s: failed to verify stream in iteration %" PRIu32
"\n", __func__, i);
253 Stream_Free(s, TRUE);
259#define Stream_Peek_UINT8_BE Stream_Peek_UINT8
260#define Stream_Read_UINT8_BE Stream_Read_UINT8
261#define Stream_Peek_Get_UINT8_BE Stream_Peek_Get_UINT8
262#define Stream_Get_UINT8_BE Stream_Get_UINT8
263#define Stream_Peek_INT8_BE Stream_Peek_INT8
264#define Stream_Peek_Get_INT8_BE Stream_Peek_Get_INT8
265#define Stream_Read_INT8_BE Stream_Read_INT8
266#define Stream_Get_INT8_BE Stream_Get_INT8
268#define TestStream_PeekAndRead(_s, _r, _t) \
273 BYTE* _p = Stream_Buffer(_s); \
274 Stream_ResetPosition(_s); \
275 Stream_Peek_##_t(_s, _a); \
276 Stream_Read_##_t(_s, _b); \
279 printf("%s: test1 " #_t "_LE failed\n", __func__); \
282 Stream_Rewind(_s, sizeof(_t)); \
283 const _t _d = Stream_Peek_Get_##_t(_s); \
284 const _t _c = Stream_Get_##_t(_s); \
287 printf("%s: test1 " #_t "_LE failed\n", __func__); \
290 for (size_t _i = 0; _i < sizeof(_t); _i++) \
292 if (((_a >> (_i * 8)) & 0xFF) != _p[_i]) \
294 printf("%s: test2 " #_t "_LE failed\n", __func__); \
300 Stream_ResetPosition(_s); \
301 Stream_Peek_##_t##_BE(_s, _a); \
302 Stream_Read_##_t##_BE(_s, _b); \
305 printf("%s: test1 " #_t "_BE failed\n", __func__); \
308 Stream_Rewind(_s, sizeof(_t)); \
309 const _t _e = Stream_Peek_Get_##_t##_BE(_s); \
310 const _t _f = Stream_Get_##_t##_BE(_s); \
313 printf("%s: test1 " #_t "_BE failed\n", __func__); \
316 for (size_t _i = 0; _i < sizeof(_t); _i++) \
318 if (((_a >> (_i * 8)) & 0xFF) != _p[sizeof(_t) - _i - 1]) \
320 printf("%s: test2 " #_t "_BE failed\n", __func__); \
329static BOOL TestStream_WriteAndRead(UINT64 value)
344 wStream* s = Stream_New(
nullptr, 1024);
350 Stream_Write_UINT8(s, val.u8);
351 Stream_Rewind_UINT8(s);
352 const UINT8 ru8 = Stream_Get_UINT8(s);
353 Stream_Rewind_UINT8(s);
358 Stream_Write_UINT16(s, val.u16);
359 Stream_Rewind_UINT16(s);
360 const UINT16 ru = Stream_Get_UINT16(s);
361 Stream_Rewind_UINT16(s);
366 Stream_Write_UINT16_BE(s, val.u16);
367 Stream_Rewind_UINT16(s);
368 const UINT16 ru = Stream_Get_UINT16_BE(s);
369 Stream_Rewind_UINT16(s);
374 Stream_Write_UINT32(s, val.u32);
375 Stream_Rewind_UINT32(s);
376 const UINT32 ru = Stream_Get_UINT32(s);
377 Stream_Rewind_UINT32(s);
382 Stream_Write_UINT32_BE(s, val.u32);
383 Stream_Rewind_UINT32(s);
384 const UINT32 ru = Stream_Get_UINT32_BE(s);
385 Stream_Rewind_UINT32(s);
390 Stream_Write_UINT64(s, val.u64);
391 Stream_Rewind_UINT64(s);
392 const UINT64 ru = Stream_Get_UINT64(s);
393 Stream_Rewind_UINT64(s);
398 Stream_Write_UINT64_BE(s, val.u64);
399 Stream_Rewind_UINT64(s);
400 const UINT64 ru = Stream_Get_UINT64_BE(s);
401 Stream_Rewind_UINT64(s);
406 Stream_Write_INT8(s, val.i8);
408 const INT8 ru8 = Stream_Get_INT8(s);
414 Stream_Write_INT16(s, val.i16);
416 const INT16 ru = Stream_Get_INT16(s);
422 Stream_Write_INT16_BE(s, val.i16);
424 const INT16 ru = Stream_Get_INT16_BE(s);
430 Stream_Write_INT32(s, val.i32);
432 const INT32 ru = Stream_Get_INT32(s);
438 Stream_Write_INT32_BE(s, val.i32);
440 const INT32 ru = Stream_Get_INT32_BE(s);
446 Stream_Write_INT64(s, val.i64);
448 const INT64 ru = Stream_Get_INT64(s);
454 Stream_Write_INT64_BE(s, val.i64);
456 const INT64 ru = Stream_Get_INT64_BE(s);
464 Stream_Free(s, TRUE);
469static BOOL TestStream_Reading(
void)
471 BYTE src[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
475 if (!(s = Stream_New(src,
sizeof(src))))
477 printf(
"%s: Stream_New failed\n", __func__);
481 TestStream_PeekAndRead(s, result, UINT8);
482 TestStream_PeekAndRead(s, result, INT8);
483 TestStream_PeekAndRead(s, result, UINT16);
484 TestStream_PeekAndRead(s, result, INT16);
485 TestStream_PeekAndRead(s, result, UINT32);
486 TestStream_PeekAndRead(s, result, INT32);
487 TestStream_PeekAndRead(s, result, UINT64);
488 TestStream_PeekAndRead(s, result, INT64);
489 Stream_Free(s, FALSE);
494static BOOL TestStream_Write(
void)
501 const BYTE data[] =
"someteststreamdata";
502 wStream* s = Stream_New(
nullptr, 100);
507 if (s->pointer != s->buffer)
510 Stream_Write(s, data,
sizeof(data));
512 if (memcmp(Stream_Buffer(s), data,
sizeof(data)) == 0)
515 if (s->pointer != s->buffer +
sizeof(data))
518 Stream_ResetPosition(s);
520 if (s->pointer != s->buffer)
523 Stream_Write_UINT8(s, 42);
525 if (s->pointer != s->buffer + 1)
528 Stream_ResetPosition(s);
530 if (s->pointer != s->buffer)
533 Stream_Peek_UINT8(s, u8);
538 Stream_Write_UINT16(s, 0x1234);
540 if (s->pointer != s->buffer + 2)
543 Stream_ResetPosition(s);
545 if (s->pointer != s->buffer)
548 Stream_Peek_UINT16(s, u16);
553 Stream_Write_UINT32(s, 0x12345678UL);
555 if (s->pointer != s->buffer + 4)
558 Stream_ResetPosition(s);
560 if (s->pointer != s->buffer)
563 Stream_Peek_UINT32(s, u32);
565 if (u32 != 0x12345678UL)
568 Stream_Write_UINT64(s, 0x1234567890ABCDEFULL);
570 if (s->pointer != s->buffer + 8)
573 Stream_ResetPosition(s);
575 if (s->pointer != s->buffer)
578 Stream_Peek_UINT64(s, u64);
580 if (u64 != 0x1234567890ABCDEFULL)
584 Stream_Free(s, TRUE);
589static BOOL TestStream_Seek(
void)
592 wStream* s = Stream_New(
nullptr, 100);
597 if (s->pointer != s->buffer)
602 if (s->pointer != s->buffer + 5)
605 Stream_Seek_UINT8(s);
607 if (s->pointer != s->buffer + 6)
610 Stream_Seek_UINT16(s);
612 if (s->pointer != s->buffer + 8)
615 Stream_Seek_UINT32(s);
617 if (s->pointer != s->buffer + 12)
620 Stream_Seek_UINT64(s);
622 if (s->pointer != s->buffer + 20)
627 Stream_Free(s, TRUE);
632static BOOL TestStream_Rewind(
void)
635 wStream* s = Stream_New(
nullptr, 100);
640 if (s->pointer != s->buffer)
645 if (s->pointer != s->buffer + 100)
648 Stream_Rewind(s, 10);
650 if (s->pointer != s->buffer + 90)
653 Stream_Rewind_UINT8(s);
655 if (s->pointer != s->buffer + 89)
658 Stream_Rewind_UINT16(s);
660 if (s->pointer != s->buffer + 87)
663 Stream_Rewind_UINT32(s);
665 if (s->pointer != s->buffer + 83)
668 Stream_Rewind_UINT64(s);
670 if (s->pointer != s->buffer + 75)
675 Stream_Free(s, TRUE);
680static BOOL TestStream_Zero(
void)
683 const BYTE data[] =
"someteststreamdata";
684 wStream* s = Stream_New(
nullptr,
sizeof(data));
689 Stream_Write(s, data,
sizeof(data));
691 if (memcmp(Stream_Buffer(s), data,
sizeof(data)) != 0)
694 Stream_ResetPosition(s);
696 if (s->pointer != s->buffer)
701 if (s->pointer != s->buffer + 5)
704 if (memcmp(Stream_ConstPointer(s), data + 5,
sizeof(data) - 5) != 0)
707 Stream_ResetPosition(s);
709 if (s->pointer != s->buffer)
712 for (UINT32 x = 0; x < 5; x++)
715 Stream_Read_UINT8(s, val);
723 Stream_Free(s, TRUE);
728static BOOL TestStream_Fill(
void)
731 const BYTE fill[7] =
"XXXXXXX";
732 const BYTE data[] =
"someteststreamdata";
733 wStream* s = Stream_New(
nullptr,
sizeof(data));
738 Stream_Write(s, data,
sizeof(data));
740 if (memcmp(Stream_Buffer(s), data,
sizeof(data)) != 0)
743 Stream_ResetPosition(s);
745 if (s->pointer != s->buffer)
748 Stream_Fill(s, fill[0],
sizeof(fill));
750 if (s->pointer != s->buffer +
sizeof(fill))
753 if (memcmp(Stream_ConstPointer(s), data +
sizeof(fill),
sizeof(data) -
sizeof(fill)) != 0)
756 Stream_ResetPosition(s);
758 if (s->pointer != s->buffer)
761 if (memcmp(Stream_ConstPointer(s), fill,
sizeof(fill)) != 0)
766 Stream_Free(s, TRUE);
771static BOOL TestStream_Copy(
void)
774 const BYTE data[] =
"someteststreamdata";
775 wStream* s = Stream_New(
nullptr,
sizeof(data));
776 wStream* d = Stream_New(
nullptr,
sizeof(data));
781 if (s->pointer != s->buffer)
784 Stream_Write(s, data,
sizeof(data));
786 if (memcmp(Stream_Buffer(s), data,
sizeof(data)) != 0)
789 if (s->pointer != s->buffer +
sizeof(data))
792 Stream_ResetPosition(s);
794 if (s->pointer != s->buffer)
797 Stream_Copy(s, d,
sizeof(data));
799 if (s->pointer != s->buffer +
sizeof(data))
802 if (d->pointer != d->buffer +
sizeof(data))
805 if (Stream_GetPosition(s) != Stream_GetPosition(d))
808 if (memcmp(Stream_Buffer(s), data,
sizeof(data)) != 0)
811 if (memcmp(Stream_Buffer(d), data,
sizeof(data)) != 0)
816 Stream_Free(s, TRUE);
817 Stream_Free(d, TRUE);
822static BOOL TestStream_WriteUTF16(
void)
824 const char name[] =
"UVC Camera (046d:0825)";
825 const char channel[] =
"usb-0000:00:07.0-3";
826 const size_t length = strnlen(name,
sizeof(name));
827 BOOL success = FALSE;
828 wStream* s = Stream_New(
nullptr, 256);
833 for (
size_t offset = 1; offset <= 2; offset++)
835 for (
size_t fill = 0; fill <= 1; fill++)
837 memset(Stream_Buffer(s), 0xAA, Stream_Capacity(s));
838 Stream_SetPosition(s, offset);
840 Stream_Write_UTF16_String_From_UTF8(s, length + 1, name, length, (BOOL)fill);
841 const size_t end = offset + (length + fill) *
sizeof(WCHAR);
842 if ((rc != (SSIZE_T)length) || (Stream_GetPosition(s) != end))
844 Stream_Write(s, channel, strnlen(channel,
sizeof(channel)) + 1);
845 for (
size_t i = 0; i < length; i++)
847 const BYTE* ptr = Stream_Buffer(s) + offset + i *
sizeof(WCHAR);
848 if ((ptr[0] != (BYTE)name[i]) || (ptr[1] != 0))
851 if (fill && ((Stream_Buffer(s)[end - 2] != 0) || (Stream_Buffer(s)[end - 1] != 0)))
853 if (strncmp((
const char*)Stream_Buffer(s) + end, channel,
sizeof(channel)) != 0)
859 Stream_ResetPosition(s);
860 if (Stream_Write_UTF16_String_From_UTF8(s, 2, name, length, TRUE) != 2)
863 const size_t pos = Stream_GetPosition(s);
864 if (pos != 2 *
sizeof(WCHAR))
870 printf(
"UTF-16 stream serialization failed\n");
871 Stream_Free(s, TRUE);
875int TestStream(
int argc,
char* argv[])
879 if (!TestStream_WriteUTF16())
882 if (!TestStream_Create(200, FALSE))
885 if (!TestStream_Create(200, TRUE))
888 if (!TestStream_Extent(4096))
891 if (!TestStream_Reading())
894 if (!TestStream_New())
897 if (!TestStream_Write())
900 if (!TestStream_Seek())
903 if (!TestStream_Rewind())
906 if (!TestStream_Zero())
909 if (!TestStream_Fill())
912 if (!TestStream_Copy())
915 if (!TestStream_Static())
918 if (!TestStream_WriteAndRead(0x1234567890abcdef))
921 for (
size_t x = 0; x < 10; x++)
924 if (winpr_RAND(&val,
sizeof(val)) < 0)
926 if (!TestStream_WriteAndRead(val))