diff options
Diffstat (limited to '')
-rw-r--r-- | winpr/libwinpr/utils/test/TestStream.c | 682 |
1 files changed, 682 insertions, 0 deletions
diff --git a/winpr/libwinpr/utils/test/TestStream.c b/winpr/libwinpr/utils/test/TestStream.c new file mode 100644 index 0000000..00130ae --- /dev/null +++ b/winpr/libwinpr/utils/test/TestStream.c @@ -0,0 +1,682 @@ +#include <winpr/crt.h> +#include <winpr/print.h> +#include <winpr/stream.h> + +static BOOL TestStream_Verify(wStream* s, size_t mincap, size_t len, size_t pos) +{ + if (Stream_Buffer(s) == NULL) + { + printf("stream buffer is null\n"); + return FALSE; + } + + if (Stream_ConstPointer(s) == NULL) + { + printf("stream pointer is null\n"); + return FALSE; + } + + if (Stream_PointerAs(s, BYTE) < Stream_Buffer(s)) + { + printf("stream pointer (%p) or buffer (%p) is invalid\n", Stream_ConstPointer(s), + (void*)Stream_Buffer(s)); + return FALSE; + } + + if (Stream_Capacity(s) < mincap) + { + printf("stream capacity is %" PRIuz " but minimum expected value is %" PRIuz "\n", + Stream_Capacity(s), mincap); + return FALSE; + } + + if (Stream_Length(s) != len) + { + printf("stream has unexpected length (%" PRIuz " instead of %" PRIuz ")\n", + Stream_Length(s), len); + return FALSE; + } + + if (Stream_GetPosition(s) != pos) + { + printf("stream has unexpected position (%" PRIuz " instead of %" PRIuz ")\n", + Stream_GetPosition(s), pos); + return FALSE; + } + + if (Stream_GetPosition(s) > Stream_Length(s)) + { + printf("stream position (%" PRIuz ") exceeds length (%" PRIuz ")\n", Stream_GetPosition(s), + Stream_Length(s)); + return FALSE; + } + + if (Stream_GetPosition(s) > Stream_Capacity(s)) + { + printf("stream position (%" PRIuz ") exceeds capacity (%" PRIuz ")\n", + Stream_GetPosition(s), Stream_Capacity(s)); + return FALSE; + } + + if (Stream_Length(s) > Stream_Capacity(s)) + { + printf("stream length (%" PRIuz ") exceeds capacity (%" PRIuz ")\n", Stream_Length(s), + Stream_Capacity(s)); + return FALSE; + } + + if (Stream_GetRemainingLength(s) != len - pos) + { + printf("stream remaining length (%" PRIuz " instead of %" PRIuz ")\n", + Stream_GetRemainingLength(s), len - pos); + return FALSE; + } + + return TRUE; +} + +static BOOL TestStream_New(void) +{ + wStream* s = NULL; + /* Test creation of a 0-size stream with no buffer */ + s = Stream_New(NULL, 0); + + if (s) + return FALSE; + + return TRUE; +} + +static BOOL TestStream_Static(void) +{ + BYTE buffer[20]; + wStream staticStream; + wStream* s = &staticStream; + UINT16 v = 0; + /* Test creation of a static stream */ + Stream_StaticInit(s, buffer, sizeof(buffer)); + Stream_Write_UINT16(s, 0xcab1); + Stream_SetPosition(s, 0); + Stream_Read_UINT16(s, v); + + if (v != 0xcab1) + return FALSE; + + Stream_SetPosition(s, 0); + Stream_Write_UINT16(s, 1); + + if (!Stream_EnsureRemainingCapacity(s, 10)) /* we can ask for 10 bytes */ + return FALSE; + + /* 30 is bigger than the buffer, it will be reallocated on the heap */ + if (!Stream_EnsureRemainingCapacity(s, 30) || !s->isOwner) + return FALSE; + + Stream_Write_UINT16(s, 2); + Stream_SetPosition(s, 0); + Stream_Read_UINT16(s, v); + + if (v != 1) + return FALSE; + + Stream_Read_UINT16(s, v); + + if (v != 2) + return FALSE; + + Stream_Free(s, TRUE); + return TRUE; +} + +static BOOL TestStream_Create(size_t count, BOOL selfAlloc) +{ + size_t len = 0; + size_t cap = 0; + wStream* s = NULL; + void* buffer = NULL; + + for (size_t i = 0; i < count; i++) + { + len = cap = i + 1; + + if (selfAlloc) + { + if (!(buffer = malloc(cap))) + { + printf("%s: failed to allocate buffer of size %" PRIuz "\n", __func__, cap); + goto fail; + } + } + + if (!(s = Stream_New(selfAlloc ? buffer : NULL, len))) + { + printf("%s: Stream_New failed for stream #%" PRIuz "\n", __func__, i); + goto fail; + } + + if (!TestStream_Verify(s, cap, len, 0)) + { + goto fail; + } + + for (size_t pos = 0; pos < len; pos++) + { + Stream_SetPosition(s, pos); + Stream_SealLength(s); + + if (!TestStream_Verify(s, cap, pos, pos)) + { + goto fail; + } + } + + if (selfAlloc) + { + memset(buffer, i % 256, cap); + + if (memcmp(buffer, Stream_Buffer(s), cap)) + { + printf("%s: buffer memory corruption\n", __func__); + goto fail; + } + } + + Stream_Free(s, buffer ? FALSE : TRUE); + free(buffer); + } + + return TRUE; +fail: + free(buffer); + + if (s) + { + Stream_Free(s, buffer ? FALSE : TRUE); + } + + return FALSE; +} + +static BOOL TestStream_Extent(UINT32 maxSize) +{ + wStream* s = NULL; + BOOL result = FALSE; + + if (!(s = Stream_New(NULL, 1))) + { + printf("%s: Stream_New failed\n", __func__); + return FALSE; + } + + for (UINT32 i = 1; i < maxSize; i++) + { + if (i % 2) + { + if (!Stream_EnsureRemainingCapacity(s, i)) + goto fail; + } + else + { + if (!Stream_EnsureCapacity(s, i)) + goto fail; + } + + Stream_SetPosition(s, i); + Stream_SealLength(s); + + if (!TestStream_Verify(s, i, i, i)) + { + printf("%s: failed to verify stream in iteration %" PRIu32 "\n", __func__, i); + goto fail; + } + } + + result = TRUE; +fail: + + if (s) + { + Stream_Free(s, TRUE); + } + + return result; +} + +#define Stream_Peek_UINT8_BE Stream_Peek_UINT8 +#define Stream_Read_UINT8_BE Stream_Read_UINT8 +#define Stream_Peek_INT8_BE Stream_Peek_INT8 +#define Stream_Read_INT8_BE Stream_Read_INT8 + +#define TestStream_PeekAndRead(_s, _r, _t) \ + do \ + { \ + _t _a; \ + _t _b; \ + BYTE* _p = Stream_Buffer(_s); \ + Stream_SetPosition(_s, 0); \ + Stream_Peek_##_t(_s, _a); \ + Stream_Read_##_t(_s, _b); \ + if (_a != _b) \ + { \ + printf("%s: test1 " #_t "_LE failed\n", __func__); \ + _r = FALSE; \ + } \ + for (size_t _i = 0; _i < sizeof(_t); _i++) \ + { \ + if (((_a >> (_i * 8)) & 0xFF) != _p[_i]) \ + { \ + printf("%s: test2 " #_t "_LE failed\n", __func__); \ + _r = FALSE; \ + break; \ + } \ + } \ + /* printf("a: 0x%016llX\n", a); */ \ + Stream_SetPosition(_s, 0); \ + Stream_Peek_##_t##_BE(_s, _a); \ + Stream_Read_##_t##_BE(_s, _b); \ + if (_a != _b) \ + { \ + printf("%s: test1 " #_t "_BE failed\n", __func__); \ + _r = FALSE; \ + } \ + for (size_t _i = 0; _i < sizeof(_t); _i++) \ + { \ + if (((_a >> (_i * 8)) & 0xFF) != _p[sizeof(_t) - _i - 1]) \ + { \ + printf("%s: test2 " #_t "_BE failed\n", __func__); \ + _r = FALSE; \ + break; \ + } \ + } \ + /* printf("a: 0x%016llX\n", a); */ \ + } while (0) + +static BOOL TestStream_Reading(void) +{ + BYTE src[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + wStream* s = NULL; + BOOL result = TRUE; + + if (!(s = Stream_New(src, sizeof(src)))) + { + printf("%s: Stream_New failed\n", __func__); + return FALSE; + } + + TestStream_PeekAndRead(s, result, UINT8); + TestStream_PeekAndRead(s, result, INT8); + TestStream_PeekAndRead(s, result, UINT16); + TestStream_PeekAndRead(s, result, INT16); + TestStream_PeekAndRead(s, result, UINT32); + TestStream_PeekAndRead(s, result, INT32); + TestStream_PeekAndRead(s, result, UINT64); + TestStream_PeekAndRead(s, result, INT64); + Stream_Free(s, FALSE); + return result; +} + +static BOOL TestStream_Write(void) +{ + BOOL rc = FALSE; + UINT8 u8 = 0; + UINT16 u16 = 0; + UINT32 u32 = 0; + UINT64 u64 = 0; + const BYTE data[] = "someteststreamdata"; + wStream* s = Stream_New(NULL, 100); + + if (!s) + goto out; + + if (s->pointer != s->buffer) + goto out; + + Stream_Write(s, data, sizeof(data)); + + if (memcmp(Stream_Buffer(s), data, sizeof(data)) == 0) + rc = TRUE; + + if (s->pointer != s->buffer + sizeof(data)) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Write_UINT8(s, 42); + + if (s->pointer != s->buffer + 1) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Peek_UINT8(s, u8); + + if (u8 != 42) + goto out; + + Stream_Write_UINT16(s, 0x1234); + + if (s->pointer != s->buffer + 2) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Peek_UINT16(s, u16); + + if (u16 != 0x1234) + goto out; + + Stream_Write_UINT32(s, 0x12345678UL); + + if (s->pointer != s->buffer + 4) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Peek_UINT32(s, u32); + + if (u32 != 0x12345678UL) + goto out; + + Stream_Write_UINT64(s, 0x1234567890ABCDEFULL); + + if (s->pointer != s->buffer + 8) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Peek_UINT64(s, u64); + + if (u64 != 0x1234567890ABCDEFULL) + goto out; + +out: + Stream_Free(s, TRUE); + return rc; +} + +static BOOL TestStream_Seek(void) +{ + BOOL rc = FALSE; + wStream* s = Stream_New(NULL, 100); + + if (!s) + goto out; + + if (s->pointer != s->buffer) + goto out; + + Stream_Seek(s, 5); + + if (s->pointer != s->buffer + 5) + goto out; + + Stream_Seek_UINT8(s); + + if (s->pointer != s->buffer + 6) + goto out; + + Stream_Seek_UINT16(s); + + if (s->pointer != s->buffer + 8) + goto out; + + Stream_Seek_UINT32(s); + + if (s->pointer != s->buffer + 12) + goto out; + + Stream_Seek_UINT64(s); + + if (s->pointer != s->buffer + 20) + goto out; + + rc = TRUE; +out: + Stream_Free(s, TRUE); + return rc; +} + +static BOOL TestStream_Rewind(void) +{ + BOOL rc = FALSE; + wStream* s = Stream_New(NULL, 100); + + if (!s) + goto out; + + if (s->pointer != s->buffer) + goto out; + + Stream_Seek(s, 100); + + if (s->pointer != s->buffer + 100) + goto out; + + Stream_Rewind(s, 10); + + if (s->pointer != s->buffer + 90) + goto out; + + Stream_Rewind_UINT8(s); + + if (s->pointer != s->buffer + 89) + goto out; + + Stream_Rewind_UINT16(s); + + if (s->pointer != s->buffer + 87) + goto out; + + Stream_Rewind_UINT32(s); + + if (s->pointer != s->buffer + 83) + goto out; + + Stream_Rewind_UINT64(s); + + if (s->pointer != s->buffer + 75) + goto out; + + rc = TRUE; +out: + Stream_Free(s, TRUE); + return rc; +} + +static BOOL TestStream_Zero(void) +{ + BOOL rc = FALSE; + const BYTE data[] = "someteststreamdata"; + wStream* s = Stream_New(NULL, sizeof(data)); + + if (!s) + goto out; + + Stream_Write(s, data, sizeof(data)); + + if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Zero(s, 5); + + if (s->pointer != s->buffer + 5) + goto out; + + if (memcmp(Stream_ConstPointer(s), data + 5, sizeof(data) - 5) != 0) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + for (UINT32 x = 0; x < 5; x++) + { + UINT8 val = 0; + Stream_Read_UINT8(s, val); + + if (val != 0) + goto out; + } + + rc = TRUE; +out: + Stream_Free(s, TRUE); + return rc; +} + +static BOOL TestStream_Fill(void) +{ + BOOL rc = FALSE; + const BYTE fill[7] = "XXXXXXX"; + const BYTE data[] = "someteststreamdata"; + wStream* s = Stream_New(NULL, sizeof(data)); + + if (!s) + goto out; + + Stream_Write(s, data, sizeof(data)); + + if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Fill(s, fill[0], sizeof(fill)); + + if (s->pointer != s->buffer + sizeof(fill)) + goto out; + + if (memcmp(Stream_ConstPointer(s), data + sizeof(fill), sizeof(data) - sizeof(fill)) != 0) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + if (memcmp(Stream_ConstPointer(s), fill, sizeof(fill)) != 0) + goto out; + + rc = TRUE; +out: + Stream_Free(s, TRUE); + return rc; +} + +static BOOL TestStream_Copy(void) +{ + BOOL rc = FALSE; + const BYTE data[] = "someteststreamdata"; + wStream* s = Stream_New(NULL, sizeof(data)); + wStream* d = Stream_New(NULL, sizeof(data)); + + if (!s || !d) + goto out; + + if (s->pointer != s->buffer) + goto out; + + Stream_Write(s, data, sizeof(data)); + + if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0) + goto out; + + if (s->pointer != s->buffer + sizeof(data)) + goto out; + + Stream_SetPosition(s, 0); + + if (s->pointer != s->buffer) + goto out; + + Stream_Copy(s, d, sizeof(data)); + + if (s->pointer != s->buffer + sizeof(data)) + goto out; + + if (d->pointer != d->buffer + sizeof(data)) + goto out; + + if (Stream_GetPosition(s) != Stream_GetPosition(d)) + goto out; + + if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0) + goto out; + + if (memcmp(Stream_Buffer(d), data, sizeof(data)) != 0) + goto out; + + rc = TRUE; +out: + Stream_Free(s, TRUE); + Stream_Free(d, TRUE); + return rc; +} + +int TestStream(int argc, char* argv[]) +{ + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!TestStream_Create(200, FALSE)) + return 1; + + if (!TestStream_Create(200, TRUE)) + return 2; + + if (!TestStream_Extent(4096)) + return 3; + + if (!TestStream_Reading()) + return 4; + + if (!TestStream_New()) + return 5; + + if (!TestStream_Write()) + return 6; + + if (!TestStream_Seek()) + return 7; + + if (!TestStream_Rewind()) + return 8; + + if (!TestStream_Zero()) + return 9; + + if (!TestStream_Fill()) + return 10; + + if (!TestStream_Copy()) + return 11; + + if (!TestStream_Static()) + return 12; + + return 0; +} |