From a9bcc81f821d7c66f623779fa5147e728eb3c388 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 03:24:41 +0200 Subject: Adding upstream version 3.3.0+dfsg1. Signed-off-by: Daniel Baumann --- winpr/libwinpr/utils/test/CMakeLists.txt | 55 ++ winpr/libwinpr/utils/test/TestASN1.c | 335 ++++++++++++ winpr/libwinpr/utils/test/TestArrayList.c | 82 +++ winpr/libwinpr/utils/test/TestBacktrace.c | 34 ++ winpr/libwinpr/utils/test/TestBitStream.c | 86 ++++ winpr/libwinpr/utils/test/TestBufferPool.c | 68 +++ winpr/libwinpr/utils/test/TestCmdLine.c | 352 +++++++++++++ winpr/libwinpr/utils/test/TestHashTable.c | 448 ++++++++++++++++ winpr/libwinpr/utils/test/TestImage.c | 232 +++++++++ winpr/libwinpr/utils/test/TestIni.c | 160 ++++++ winpr/libwinpr/utils/test/TestLinkedList.c | 135 +++++ winpr/libwinpr/utils/test/TestListDictionary.c | 178 +++++++ winpr/libwinpr/utils/test/TestMessagePipe.c | 105 ++++ winpr/libwinpr/utils/test/TestMessageQueue.c | 56 ++ winpr/libwinpr/utils/test/TestPrint.c | 401 +++++++++++++++ winpr/libwinpr/utils/test/TestPubSub.c | 73 +++ winpr/libwinpr/utils/test/TestQueue.c | 58 +++ winpr/libwinpr/utils/test/TestStream.c | 682 +++++++++++++++++++++++++ winpr/libwinpr/utils/test/TestStreamPool.c | 78 +++ winpr/libwinpr/utils/test/TestVersion.c | 47 ++ winpr/libwinpr/utils/test/TestWLog.c | 69 +++ winpr/libwinpr/utils/test/TestWLogCallback.c | 128 +++++ winpr/libwinpr/utils/test/lodepng_32bit.bmp | Bin 0 -> 16522 bytes winpr/libwinpr/utils/test/lodepng_32bit.png | Bin 0 -> 3968 bytes winpr/libwinpr/utils/test/rgb.16.bmp | Bin 0 -> 1966218 bytes winpr/libwinpr/utils/test/rgb.16.nocolor.bmp | Bin 0 -> 1966150 bytes winpr/libwinpr/utils/test/rgb.16a.bmp | Bin 0 -> 1966218 bytes winpr/libwinpr/utils/test/rgb.16a.nocolor.bmp | Bin 0 -> 1966150 bytes winpr/libwinpr/utils/test/rgb.16x.bmp | Bin 0 -> 1966218 bytes winpr/libwinpr/utils/test/rgb.16x.nocolor.bmp | Bin 0 -> 1966150 bytes winpr/libwinpr/utils/test/rgb.24.bmp | Bin 0 -> 2949258 bytes winpr/libwinpr/utils/test/rgb.24.nocolor.bmp | Bin 0 -> 2949174 bytes winpr/libwinpr/utils/test/rgb.32.bmp | Bin 0 -> 3932298 bytes winpr/libwinpr/utils/test/rgb.32.nocolor.bmp | Bin 0 -> 3932230 bytes winpr/libwinpr/utils/test/rgb.32x.bmp | Bin 0 -> 3932298 bytes winpr/libwinpr/utils/test/rgb.32x.nocolor.bmp | Bin 0 -> 3932230 bytes winpr/libwinpr/utils/test/rgb.bmp | Bin 0 -> 2949258 bytes winpr/libwinpr/utils/test/rgb.jpg | Bin 0 -> 280142 bytes winpr/libwinpr/utils/test/rgb.png | Bin 0 -> 70251 bytes winpr/libwinpr/utils/test/rgb.webp | Bin 0 -> 20912 bytes 40 files changed, 3862 insertions(+) create mode 100644 winpr/libwinpr/utils/test/CMakeLists.txt create mode 100644 winpr/libwinpr/utils/test/TestASN1.c create mode 100644 winpr/libwinpr/utils/test/TestArrayList.c create mode 100644 winpr/libwinpr/utils/test/TestBacktrace.c create mode 100644 winpr/libwinpr/utils/test/TestBitStream.c create mode 100644 winpr/libwinpr/utils/test/TestBufferPool.c create mode 100644 winpr/libwinpr/utils/test/TestCmdLine.c create mode 100644 winpr/libwinpr/utils/test/TestHashTable.c create mode 100644 winpr/libwinpr/utils/test/TestImage.c create mode 100644 winpr/libwinpr/utils/test/TestIni.c create mode 100644 winpr/libwinpr/utils/test/TestLinkedList.c create mode 100644 winpr/libwinpr/utils/test/TestListDictionary.c create mode 100644 winpr/libwinpr/utils/test/TestMessagePipe.c create mode 100644 winpr/libwinpr/utils/test/TestMessageQueue.c create mode 100644 winpr/libwinpr/utils/test/TestPrint.c create mode 100644 winpr/libwinpr/utils/test/TestPubSub.c create mode 100644 winpr/libwinpr/utils/test/TestQueue.c create mode 100644 winpr/libwinpr/utils/test/TestStream.c create mode 100644 winpr/libwinpr/utils/test/TestStreamPool.c create mode 100644 winpr/libwinpr/utils/test/TestVersion.c create mode 100644 winpr/libwinpr/utils/test/TestWLog.c create mode 100644 winpr/libwinpr/utils/test/TestWLogCallback.c create mode 100644 winpr/libwinpr/utils/test/lodepng_32bit.bmp create mode 100644 winpr/libwinpr/utils/test/lodepng_32bit.png create mode 100644 winpr/libwinpr/utils/test/rgb.16.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.16.nocolor.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.16a.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.16a.nocolor.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.16x.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.16x.nocolor.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.24.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.24.nocolor.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.32.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.32.nocolor.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.32x.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.32x.nocolor.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.bmp create mode 100644 winpr/libwinpr/utils/test/rgb.jpg create mode 100644 winpr/libwinpr/utils/test/rgb.png create mode 100644 winpr/libwinpr/utils/test/rgb.webp (limited to 'winpr/libwinpr/utils/test') diff --git a/winpr/libwinpr/utils/test/CMakeLists.txt b/winpr/libwinpr/utils/test/CMakeLists.txt new file mode 100644 index 0000000..ad22f20 --- /dev/null +++ b/winpr/libwinpr/utils/test/CMakeLists.txt @@ -0,0 +1,55 @@ + +set(MODULE_NAME "TestWinPRUtils") +set(MODULE_PREFIX "TEST_WINPR_UTILS") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestIni.c + TestVersion.c + TestImage.c + TestBacktrace.c + TestQueue.c + TestPrint.c + TestPubSub.c + TestStream.c + TestBitStream.c + TestArrayList.c + TestLinkedList.c + TestListDictionary.c + TestCmdLine.c + TestASN1.c + TestWLog.c + TestWLogCallback.c + TestHashTable.c + TestBufferPool.c + TestStreamPool.c + TestMessageQueue.c + TestMessagePipe.c) + +if (WITH_LODEPNG) + list(APPEND ${MODULES_PREFIX}_TESTS + TestImage.c + ) +endif() + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_definitions(-DTEST_SOURCE_PATH="${CMAKE_CURRENT_SOURCE_DIR}") +add_definitions(-DTEST_BINARY_PATH="${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} winpr) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/utils/test/TestASN1.c b/winpr/libwinpr/utils/test/TestASN1.c new file mode 100644 index 0000000..d54bdbc --- /dev/null +++ b/winpr/libwinpr/utils/test/TestASN1.c @@ -0,0 +1,335 @@ +#include +#include + +static const BYTE boolContent[] = { 0x01, 0x01, 0xFF }; +static const BYTE badBoolContent[] = { 0x01, 0x04, 0xFF }; + +static const BYTE integerContent[] = { 0x02, 0x01, 0x02 }; +static const BYTE badIntegerContent[] = { 0x02, 0x04, 0x02 }; + +static const BYTE seqContent[] = { 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x44, + 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x69, 0x67, + 0x6E, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x43, 0x6F, 0x2E, 0x31 }; + +static const BYTE contextualInteger[] = { 0xA0, 0x03, 0x02, 0x01, 0x02 }; + +static const BYTE oidContent[] = { 0x06, 0x03, 0x55, 0x04, 0x0A }; +static const BYTE badOidContent[] = { 0x06, 0x89, 0x55, 0x04, 0x0A }; +static const BYTE oidValue[] = { 0x55, 0x04, 0x0A }; + +static const BYTE ia5stringContent[] = { 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, + 0x63, 0x70, 0x73, 0x2E, 0x72, 0x6F, 0x6F, 0x74, 0x2D, + 0x78, 0x31, 0x2E, 0x6C, 0x65, 0x74, 0x73, 0x65, 0x6E, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72, 0x67 }; + +static const BYTE utctimeContent[] = { 0x17, 0x0D, 0x32, 0x31, 0x30, 0x33, 0x31, 0x37, + 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5A }; + +int TestASN1Read(int argc, char* argv[]) +{ + WinPrAsn1Decoder decoder; + WinPrAsn1Decoder seqDecoder; + wStream staticS; + WinPrAsn1_BOOL boolV = 0; + WinPrAsn1_INTEGER integerV = 0; + WinPrAsn1_OID oidV; + WinPrAsn1_IA5STRING ia5stringV = NULL; + WinPrAsn1_UTCTIME utctimeV; + WinPrAsn1_tag tag = 0; + size_t len = 0; + BOOL error = 0; + + /* ============== Test INTEGERs ================ */ + Stream_StaticConstInit(&staticS, integerContent, sizeof(integerContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadInteger(&decoder, &integerV)) + return -1; + + Stream_StaticConstInit(&staticS, badIntegerContent, sizeof(badIntegerContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (WinPrAsn1DecReadInteger(&decoder, &integerV)) + return -1; + + /* ================ Test BOOL ================*/ + Stream_StaticConstInit(&staticS, boolContent, sizeof(boolContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadBoolean(&decoder, &boolV)) + return -10; + + Stream_StaticConstInit(&staticS, badBoolContent, sizeof(badBoolContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (WinPrAsn1DecReadBoolean(&decoder, &boolV)) + return -11; + + /* ================ Test OID ================*/ + Stream_StaticConstInit(&staticS, oidContent, sizeof(oidContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadOID(&decoder, &oidV, TRUE) || oidV.len != 3 || + memcmp(oidV.data, oidValue, oidV.len)) + return -15; + WinPrAsn1FreeOID(&oidV); + + Stream_StaticConstInit(&staticS, badOidContent, sizeof(badOidContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (WinPrAsn1DecReadOID(&decoder, &oidV, TRUE)) + return -15; + WinPrAsn1FreeOID(&oidV); + + Stream_StaticConstInit(&staticS, ia5stringContent, sizeof(ia5stringContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadIA5String(&decoder, &ia5stringV) || + strcmp(ia5stringV, "http://cps.root-x1.letsencrypt.org")) + return -16; + free(ia5stringV); + + /* ================ Test utc time ================*/ + Stream_StaticConstInit(&staticS, utctimeContent, sizeof(utctimeContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadUtcTime(&decoder, &utctimeV) || utctimeV.year != 2021 || + utctimeV.month != 3 || utctimeV.day != 17 || utctimeV.minute != 40 || utctimeV.tz != 'Z') + return -17; + + /* ================ Test sequence ================*/ + Stream_StaticConstInit(&staticS, seqContent, sizeof(seqContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadSequence(&decoder, &seqDecoder)) + return -20; + + Stream_StaticConstInit(&staticS, seqContent, sizeof(seqContent)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + if (!WinPrAsn1DecReadTagLenValue(&decoder, &tag, &len, &seqDecoder)) + return -21; + + if (tag != ER_TAG_SEQUENCE) + return -22; + + if (!WinPrAsn1DecPeekTag(&seqDecoder, &tag) || tag != ER_TAG_OBJECT_IDENTIFIER) + return -23; + + /* ================ Test contextual ================*/ + Stream_StaticConstInit(&staticS, contextualInteger, sizeof(contextualInteger)); + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + error = TRUE; + if (!WinPrAsn1DecReadContextualInteger(&decoder, 0, &error, &integerV) || error) + return -25; + + /* test reading a contextual integer that is not there (index 1). + * that should not touch the decoder read head and we shall be able to extract contextual tag 0 + * after that + */ + WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS); + error = FALSE; + if (WinPrAsn1DecReadContextualInteger(&decoder, 1, &error, &integerV) || error) + return -26; + + error = FALSE; + if (!WinPrAsn1DecReadContextualInteger(&decoder, 0, &error, &integerV) || error) + return -27; + + return 0; +} + +static BYTE oid1_val[] = { 1 }; +static const WinPrAsn1_OID oid1 = { sizeof(oid1_val), oid1_val }; +static BYTE oid2_val[] = { 2, 2 }; +static WinPrAsn1_OID oid2 = { sizeof(oid2_val), oid2_val }; +static BYTE oid3_val[] = { 3, 3, 3 }; +static WinPrAsn1_OID oid3 = { sizeof(oid3_val), oid3_val }; +static BYTE oid4_val[] = { 4, 4, 4, 4 }; +static WinPrAsn1_OID oid4 = { sizeof(oid4_val), oid4_val }; + +int TestASN1Write(int argc, char* argv[]) +{ + wStream* s = NULL; + size_t expectedOuputSz = 0; + int retCode = 100; + WinPrAsn1_UTCTIME utcTime; + WinPrAsn1_IA5STRING ia5string = NULL; + WinPrAsn1Encoder* enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER); + if (!enc) + goto out; + + /* Let's encode something like: + * APP(3) + * SEQ2 + * OID1 + * OID2 + * SEQ3 + * OID3 + * OID4 + * + * [5] integer(200) + * [6] SEQ (empty) + * [7] UTC time (2016-03-17 16:40:41 UTC) + * [8] IA5String(test) + * [9] OctetString + * SEQ(empty) + * + */ + + /* APP(3) */ + retCode = 101; + if (!WinPrAsn1EncAppContainer(enc, 3)) + goto out; + + /* SEQ2 */ + retCode = 102; + if (!WinPrAsn1EncSeqContainer(enc)) + goto out; + + retCode = 103; + if (WinPrAsn1EncOID(enc, &oid1) != 3) + goto out; + + retCode = 104; + if (WinPrAsn1EncOID(enc, &oid2) != 4) + goto out; + + retCode = 105; + if (WinPrAsn1EncEndContainer(enc) != 9) + goto out; + + /* SEQ3 */ + retCode = 110; + if (!WinPrAsn1EncSeqContainer(enc)) + goto out; + + retCode = 111; + if (WinPrAsn1EncOID(enc, &oid3) != 5) + goto out; + + retCode = 112; + if (WinPrAsn1EncOID(enc, &oid4) != 6) + goto out; + + retCode = 113; + if (WinPrAsn1EncEndContainer(enc) != 13) + goto out; + + /* [5] integer(200) */ + retCode = 114; + if (WinPrAsn1EncContextualInteger(enc, 5, 200) != 6) + goto out; + + /* [6] SEQ (empty) */ + retCode = 115; + if (!WinPrAsn1EncContextualSeqContainer(enc, 6)) + goto out; + + retCode = 116; + if (WinPrAsn1EncEndContainer(enc) != 4) + goto out; + + /* [7] UTC time (2016-03-17 16:40:41 UTC) */ + retCode = 117; + utcTime.year = 2016; + utcTime.month = 3; + utcTime.day = 17; + utcTime.hour = 16; + utcTime.minute = 40; + utcTime.second = 41; + utcTime.tz = 'Z'; + if (WinPrAsn1EncContextualUtcTime(enc, 7, &utcTime) != 17) + goto out; + + /* [8] IA5String(test) */ + retCode = 118; + ia5string = "test"; + if (!WinPrAsn1EncContextualContainer(enc, 8)) + goto out; + + retCode = 119; + if (WinPrAsn1EncIA5String(enc, ia5string) != 6) + goto out; + + retCode = 120; + if (WinPrAsn1EncEndContainer(enc) != 8) + goto out; + + /* [9] OctetString + * SEQ(empty) + */ + retCode = 121; + if (!WinPrAsn1EncContextualOctetStringContainer(enc, 9)) + goto out; + + retCode = 122; + if (!WinPrAsn1EncSeqContainer(enc)) + goto out; + + retCode = 123; + if (WinPrAsn1EncEndContainer(enc) != 2) + goto out; + + retCode = 124; + if (WinPrAsn1EncEndContainer(enc) != 6) + goto out; + + /* close APP */ + expectedOuputSz = 24 + 6 + 4 + 17 + 8 + 6; + retCode = 200; + if (WinPrAsn1EncEndContainer(enc) != expectedOuputSz) + goto out; + + /* let's output the result */ + retCode = 201; + s = Stream_New(NULL, 1024); + if (!s) + goto out; + + retCode = 202; + if (!WinPrAsn1EncToStream(enc, s) || Stream_GetPosition(s) != expectedOuputSz) + goto out; + /* winpr_HexDump("", WLOG_ERROR, Stream_Buffer(s), Stream_GetPosition(s));*/ + + /* + * let's perform a mini-performance test, where we encode an ASN1 message with a big depth, + * so that we trigger reallocation routines in the encoder. We're gonna encode something like + * SEQ1 + * SEQ2 + * SEQ3 + * ... + * SEQ1000 + * INTEGER(2) + * + * As static chunks and containers are 50, a depth of 1000 should be enough + * + */ + WinPrAsn1Encoder_Reset(enc); + + retCode = 203; + for (size_t i = 0; i < 1000; i++) + { + if (!WinPrAsn1EncSeqContainer(enc)) + goto out; + } + + retCode = 204; + if (WinPrAsn1EncInteger(enc, 2) != 3) + goto out; + + retCode = 205; + for (size_t i = 0; i < 1000; i++) + { + if (!WinPrAsn1EncEndContainer(enc)) + goto out; + } + + retCode = 0; + +out: + if (s) + Stream_Free(s, TRUE); + WinPrAsn1Encoder_Free(&enc); + return retCode; +} + +int TestASN1(int argc, char* argv[]) +{ + int ret = TestASN1Read(argc, argv); + if (ret) + return ret; + + return TestASN1Write(argc, argv); +} diff --git a/winpr/libwinpr/utils/test/TestArrayList.c b/winpr/libwinpr/utils/test/TestArrayList.c new file mode 100644 index 0000000..069394c --- /dev/null +++ b/winpr/libwinpr/utils/test/TestArrayList.c @@ -0,0 +1,82 @@ + +#include +#include +#include + +int TestArrayList(int argc, char* argv[]) +{ + int count = 0; + int rc = 0; + size_t val = 0; + wArrayList* arrayList = NULL; + const size_t elemsToInsert = 10; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + arrayList = ArrayList_New(TRUE); + if (!arrayList) + return -1; + + for (size_t index = 0; index < elemsToInsert; index++) + { + if (!ArrayList_Append(arrayList, (void*)index)) + return -1; + } + + count = ArrayList_Count(arrayList); + + printf("ArrayList count: %d\n", count); + + SSIZE_T index = ArrayList_IndexOf(arrayList, (void*)(size_t)6, -1, -1); + + printf("ArrayList index: %" PRIdz "\n", index); + + if (index != 6) + return -1; + + ArrayList_Insert(arrayList, 5, (void*)(size_t)100); + + index = ArrayList_IndexOf(arrayList, (void*)(size_t)6, -1, -1); + printf("ArrayList index: %" PRIdz "\n", index); + + if (index != 7) + return -1; + + ArrayList_Remove(arrayList, (void*)(size_t)100); + + rc = ArrayList_IndexOf(arrayList, (void*)(size_t)6, -1, -1); + printf("ArrayList index: %d\n", rc); + + if (rc != 6) + return -1; + + for (size_t index = 0; index < elemsToInsert; index++) + { + val = (size_t)ArrayList_GetItem(arrayList, 0); + if (!ArrayList_RemoveAt(arrayList, 0)) + return -1; + if (val != index) + { + printf("ArrayList: shifted %" PRIdz " entries, expected value %" PRIdz ", got %" PRIdz + "\n", + index, index, val); + return -1; + } + } + + rc = ArrayList_IndexOf(arrayList, (void*)(size_t)elemsToInsert, -1, -1); + printf("ArrayList index: %d\n", rc); + if (rc != -1) + return -1; + + count = ArrayList_Count(arrayList); + printf("ArrayList count: %d\n", count); + if (count != 0) + return -1; + + ArrayList_Clear(arrayList); + ArrayList_Free(arrayList); + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestBacktrace.c b/winpr/libwinpr/utils/test/TestBacktrace.c new file mode 100644 index 0000000..5fea333 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestBacktrace.c @@ -0,0 +1,34 @@ +#include +#include + +int TestBacktrace(int argc, char* argv[]) +{ + int rc = -1; + size_t used = 0; + char** msg = NULL; + void* stack = winpr_backtrace(20); + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!stack) + { + fprintf(stderr, "winpr_backtrace failed!\n"); + return -1; + } + + msg = winpr_backtrace_symbols(stack, &used); + + if (msg) + { + for (size_t x = 0; x < used; x++) + printf("%" PRIuz ": %s\n", x, msg[x]); + + rc = 0; + } + + winpr_backtrace_symbols_fd(stack, fileno(stdout)); + winpr_backtrace_free(stack); + free(msg); + return rc; +} diff --git a/winpr/libwinpr/utils/test/TestBitStream.c b/winpr/libwinpr/utils/test/TestBitStream.c new file mode 100644 index 0000000..83c911c --- /dev/null +++ b/winpr/libwinpr/utils/test/TestBitStream.c @@ -0,0 +1,86 @@ + +#include +#include +#include +#include + +static void BitStrGen(void) +{ + char str[64] = { 0 }; + + for (DWORD i = 0; i < 256;) + { + printf("\t"); + + for (DWORD j = 0; j < 4; j++) + { + if (0) + { + /* Least Significant Bit First */ + str[0] = (i & (1 << 7)) ? '1' : '0'; + str[1] = (i & (1 << 6)) ? '1' : '0'; + str[2] = (i & (1 << 5)) ? '1' : '0'; + str[3] = (i & (1 << 4)) ? '1' : '0'; + str[4] = (i & (1 << 3)) ? '1' : '0'; + str[5] = (i & (1 << 2)) ? '1' : '0'; + str[6] = (i & (1 << 1)) ? '1' : '0'; + str[7] = (i & (1 << 0)) ? '1' : '0'; + str[8] = '\0'; + } + else + { + /* Most Significant Bit First */ + str[7] = (i & (1 << 7)) ? '1' : '0'; + str[6] = (i & (1 << 6)) ? '1' : '0'; + str[5] = (i & (1 << 5)) ? '1' : '0'; + str[4] = (i & (1 << 4)) ? '1' : '0'; + str[3] = (i & (1 << 3)) ? '1' : '0'; + str[2] = (i & (1 << 2)) ? '1' : '0'; + str[1] = (i & (1 << 1)) ? '1' : '0'; + str[0] = (i & (1 << 0)) ? '1' : '0'; + str[8] = '\0'; + } + + printf("\"%s\",%s", str, j == 3 ? "" : " "); + i++; + } + + printf("\n"); + } +} + +int TestBitStream(int argc, char* argv[]) +{ + wBitStream* bs = NULL; + BYTE buffer[1024] = { 0 }; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + bs = BitStream_New(); + if (!bs) + return 1; + BitStream_Attach(bs, buffer, sizeof(buffer)); + BitStream_Write_Bits(bs, 0xAF, 8); /* 11110101 */ + BitStream_Write_Bits(bs, 0xF, 4); /* 1111 */ + BitStream_Write_Bits(bs, 0xA, 4); /* 0101 */ + BitStream_Flush(bs); + BitDump(__func__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST); + BitStream_Write_Bits(bs, 3, 2); /* 11 */ + BitStream_Write_Bits(bs, 0, 3); /* 000 */ + BitStream_Write_Bits(bs, 0x2D, 6); /* 101101 */ + BitStream_Write_Bits(bs, 0x19, 5); /* 11001 */ + // BitStream_Flush(bs); /* flush should be done automatically here (32 bits written) */ + BitDump(__func__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST); + BitStream_Write_Bits(bs, 3, 2); /* 11 */ + BitStream_Flush(bs); + BitDump(__func__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST); + BitStream_Write_Bits(bs, 00, 2); /* 00 */ + BitStream_Write_Bits(bs, 0xF, 4); /* 1111 */ + BitStream_Write_Bits(bs, 0, 20); + BitStream_Write_Bits(bs, 0xAFF, 12); /* 111111110101 */ + BitStream_Flush(bs); + BitDump(__func__, WLOG_INFO, buffer, bs->position, BITDUMP_MSB_FIRST); + BitStream_Free(bs); + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestBufferPool.c b/winpr/libwinpr/utils/test/TestBufferPool.c new file mode 100644 index 0000000..d954caa --- /dev/null +++ b/winpr/libwinpr/utils/test/TestBufferPool.c @@ -0,0 +1,68 @@ + +#include +#include +#include + +int TestBufferPool(int argc, char* argv[]) +{ + DWORD PoolSize = 0; + int BufferSize = 0; + wBufferPool* pool = NULL; + BYTE* Buffers[10]; + int DefaultSize = 1234; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + pool = BufferPool_New(TRUE, -1, 16); + if (!pool) + return -1; + + Buffers[0] = BufferPool_Take(pool, DefaultSize); + Buffers[1] = BufferPool_Take(pool, DefaultSize); + Buffers[2] = BufferPool_Take(pool, 2048); + if (!Buffers[0] || !Buffers[1] || !Buffers[2]) + return -1; + + BufferSize = BufferPool_GetBufferSize(pool, Buffers[0]); + + if (BufferSize != DefaultSize) + { + printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %" PRIu32 "\n", BufferSize, + DefaultSize); + return -1; + } + + BufferSize = BufferPool_GetBufferSize(pool, Buffers[1]); + + if (BufferSize != DefaultSize) + { + printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %" PRIu32 "\n", BufferSize, + DefaultSize); + return -1; + } + + BufferSize = BufferPool_GetBufferSize(pool, Buffers[2]); + + if (BufferSize != 2048) + { + printf("BufferPool_GetBufferSize failure: Actual: %d Expected: 2048\n", BufferSize); + return -1; + } + + BufferPool_Return(pool, Buffers[1]); + + PoolSize = BufferPool_GetPoolSize(pool); + + if (PoolSize != 2) + { + printf("BufferPool_GetPoolSize failure: Actual: %" PRIu32 " Expected: 2\n", PoolSize); + return -1; + } + + BufferPool_Clear(pool); + + BufferPool_Free(pool); + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestCmdLine.c b/winpr/libwinpr/utils/test/TestCmdLine.c new file mode 100644 index 0000000..b6657f5 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestCmdLine.c @@ -0,0 +1,352 @@ +#include +#include +#include +#include +#include +#include + +static const char* testArgv[] = { "mstsc.exe", + "+z", + "/w:1024", + "/h:768", + "/bpp:32", + "/admin", + "/multimon", + "+fonts", + "-wallpaper", + "/v:localhost:3389", + "/valuelist:value1,value2", + "/valuelist-empty:", + 0 }; + +static const char testListAppName[] = "test app name"; +static const char* testListArgs[] = { + "a,b,c,d", "a:,\"b:xxx, yyy\",c", "a:,,,b", "a:,\",b", "\"a,b,c,d d d,fff\"", "", + NULL, "'a,b,\",c'", "\"a,b,',c\"", "', a, ', b,c'", "\"a,b,\",c\"" +}; + +static const char* testListArgs1[] = { testListAppName, "a", "b", "c", "d" }; +static const char* testListArgs2[] = { testListAppName, "a:", "b:xxx, yyy", "c" }; +// static const char* testListArgs3[] = {}; +// static const char* testListArgs4[] = {}; +static const char* testListArgs5[] = { testListAppName, "a", "b", "c", "d d d", "fff" }; +static const char* testListArgs6[] = { testListAppName }; +static const char* testListArgs7[] = { testListAppName }; +static const char* testListArgs8[] = { testListAppName, "a", "b", "\"", "c" }; +static const char* testListArgs9[] = { testListAppName, "a", "b", "'", "c" }; +// static const char* testListArgs10[] = {}; +// static const char* testListArgs11[] = {}; + +static const char** testListArgsResult[] = { testListArgs1, + testListArgs2, + NULL /* testListArgs3 */, + NULL /* testListArgs4 */, + testListArgs5, + testListArgs6, + testListArgs7, + testListArgs8, + testListArgs9, + NULL /* testListArgs10 */, + NULL /* testListArgs11 */ }; +static const size_t testListArgsCount[] = { + ARRAYSIZE(testListArgs1), + ARRAYSIZE(testListArgs2), + 0 /* ARRAYSIZE(testListArgs3) */, + 0 /* ARRAYSIZE(testListArgs4) */, + ARRAYSIZE(testListArgs5), + ARRAYSIZE(testListArgs6), + ARRAYSIZE(testListArgs7), + ARRAYSIZE(testListArgs8), + ARRAYSIZE(testListArgs9), + 0 /* ARRAYSIZE(testListArgs10) */, + 0 /* ARRAYSIZE(testListArgs11) */ +}; + +static BOOL checkResult(size_t index, char** actual, size_t actualCount) +{ + const char** result = testListArgsResult[index]; + const size_t resultCount = testListArgsCount[index]; + + if (resultCount != actualCount) + return FALSE; + + if (actualCount == 0) + { + return (actual == NULL); + } + else + { + if (!actual) + return FALSE; + + for (size_t x = 0; x < actualCount; x++) + { + const char* a = result[x]; + const char* b = actual[x]; + + if (strcmp(a, b) != 0) + return FALSE; + } + } + + return TRUE; +} + +static BOOL TestCommandLineParseCommaSeparatedValuesEx(void) +{ + WINPR_ASSERT(ARRAYSIZE(testListArgs) == ARRAYSIZE(testListArgsResult)); + WINPR_ASSERT(ARRAYSIZE(testListArgs) == ARRAYSIZE(testListArgsCount)); + + for (size_t x = 0; x < ARRAYSIZE(testListArgs); x++) + { + const char* list = testListArgs[x]; + size_t count = 42; + char** ptr = CommandLineParseCommaSeparatedValuesEx(testListAppName, list, &count); + BOOL valid = checkResult(x, ptr, count); + free(ptr); + if (!valid) + return FALSE; + } + + return TRUE; +} + +int TestCmdLine(int argc, char* argv[]) +{ + int status = 0; + int ret = -1; + DWORD flags = 0; + long width = 0; + long height = 0; + const COMMAND_LINE_ARGUMENT_A* arg = NULL; + int testArgc = 0; + char** command_line = NULL; + COMMAND_LINE_ARGUMENT_A args[] = { + { "v", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "destination server" }, + { "port", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "server port" }, + { "w", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "width" }, + { "h", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "height" }, + { "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "fullscreen" }, + { "bpp", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, + "session bpp (color depth)" }, + { "admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "console", + "admin (or console) session" }, + { "multimon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "multi-monitor" }, + { "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "addin", "addin" }, + { "u", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "username" }, + { "p", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "password" }, + { "d", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "domain" }, + { "z", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "compression" }, + { "audio", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "audio output mode" }, + { "mic", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "audio input (microphone)" }, + { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, + "smooth fonts (cleartype)" }, + { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, + "desktop composition" }, + { "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, + "full window drag" }, + { "menu-anims", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, + "menu animations" }, + { "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "themes" }, + { "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "wallpaper" }, + { "codec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "codec" }, + { "nego", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, + "protocol security negotiation" }, + { "sec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, + "force specific protocol security" }, +#if defined(WITH_FREERDP_DEPRECATED) + { "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, + "rdp protocol security" }, + { "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, + "tls protocol security" }, + { "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, + "nla protocol security" }, + { "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, + "nla extended protocol security" }, + { "cert-name", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, + "certificate name" }, + { "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "ignore certificate" }, +#endif + { "valuelist", COMMAND_LINE_VALUE_REQUIRED, ",", NULL, NULL, -1, NULL, + "List of comma separated values." }, + { "valuelist-empty", COMMAND_LINE_VALUE_REQUIRED, ",", NULL, NULL, -1, NULL, + "List of comma separated values. Used to test correct behavior if an empty list was " + "passed." }, + { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, + NULL, "print version" }, + { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", + "print help" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } + }; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS; + testArgc = string_list_length(testArgv); + command_line = string_list_copy(testArgv); + + if (!command_line) + { + printf("Argument duplication failed (not enough memory?)\n"); + return ret; + } + + status = CommandLineParseArgumentsA(testArgc, command_line, args, flags, NULL, NULL, NULL); + + if (status != 0) + { + printf("CommandLineParseArgumentsA failure: %d\n", status); + goto out; + } + + arg = CommandLineFindArgumentA(args, "w"); + + if (strcmp("1024", arg->Value) != 0) + { + printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value); + goto out; + } + + arg = CommandLineFindArgumentA(args, "h"); + + if (strcmp("768", arg->Value) != 0) + { + printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value); + goto out; + } + + arg = CommandLineFindArgumentA(args, "f"); + + if (arg->Value) + { + printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name); + goto out; + } + + arg = CommandLineFindArgumentA(args, "admin"); + + if (!arg->Value) + { + printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name); + goto out; + } + + arg = CommandLineFindArgumentA(args, "multimon"); + + if (!arg->Value) + { + printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name); + goto out; + } + + arg = CommandLineFindArgumentA(args, "v"); + + if (strcmp("localhost:3389", arg->Value) != 0) + { + printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value); + goto out; + } + + arg = CommandLineFindArgumentA(args, "fonts"); + + if (!arg->Value) + { + printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name); + goto out; + } + + arg = CommandLineFindArgumentA(args, "wallpaper"); + + if (arg->Value) + { + printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name); + goto out; + } + + arg = CommandLineFindArgumentA(args, "help"); + + if (arg->Value) + { + printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name); + goto out; + } + + arg = args; + errno = 0; + + do + { + if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) + continue; + + printf("Argument: %s\n", arg->Name); + CommandLineSwitchStart(arg) CommandLineSwitchCase(arg, "v") + { + } + CommandLineSwitchCase(arg, "w") + { + width = strtol(arg->Value, NULL, 0); + + if (errno != 0) + goto out; + } + CommandLineSwitchCase(arg, "h") + { + height = strtol(arg->Value, NULL, 0); + + if (errno != 0) + goto out; + } + CommandLineSwitchCase(arg, "valuelist") + { + char** p = NULL; + size_t count = 0; + p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count); + free(p); + + if (!p || count != 3) + { + printf("CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz + "!=3)\n", + count); + goto out; + } + } + CommandLineSwitchCase(arg, "valuelist-empty") + { + char** p = NULL; + size_t count = 0; + p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count); + free(p); + + if (!p || count != 1) + { + printf("CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz + "!=1)\n", + count); + goto out; + } + } + CommandLineSwitchDefault(arg) + { + } + CommandLineSwitchEnd(arg) + } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + + if ((width != 1024) || (height != 768)) + { + printf("Unexpected width and height: Actual: (%ldx%ld), Expected: (1024x768)\n", width, + height); + goto out; + } + ret = 0; + +out: + string_list_free(command_line); + + if (!TestCommandLineParseCommaSeparatedValuesEx()) + return -1; + return ret; +} diff --git a/winpr/libwinpr/utils/test/TestHashTable.c b/winpr/libwinpr/utils/test/TestHashTable.c new file mode 100644 index 0000000..764853f --- /dev/null +++ b/winpr/libwinpr/utils/test/TestHashTable.c @@ -0,0 +1,448 @@ + +#include +#include +#include + +static char* key1 = "key1"; +static char* key2 = "key2"; +static char* key3 = "key3"; + +static char* val1 = "val1"; +static char* val2 = "val2"; +static char* val3 = "val3"; + +static int test_hash_table_pointer(void) +{ + int rc = -1; + size_t count = 0; + char* value = NULL; + wHashTable* table = NULL; + table = HashTable_New(TRUE); + + if (!table) + return -1; + + if (!HashTable_Insert(table, key1, val1)) + goto fail; + if (!HashTable_Insert(table, key2, val2)) + goto fail; + if (!HashTable_Insert(table, key3, val3)) + goto fail; + count = HashTable_Count(table); + + if (count != 3) + { + printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Remove(table, key2)) + goto fail; + count = HashTable_Count(table); + + if (count != 2) + { + printf("HashTable_Count: Expected : 2, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Remove(table, key3)) + goto fail; + count = HashTable_Count(table); + + if (count != 1) + { + printf("HashTable_Count: Expected : 1, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Remove(table, key1)) + goto fail; + count = HashTable_Count(table); + + if (count != 0) + { + printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Insert(table, key1, val1)) + goto fail; + if (!HashTable_Insert(table, key2, val2)) + goto fail; + if (!HashTable_Insert(table, key3, val3)) + goto fail; + count = HashTable_Count(table); + + if (count != 3) + { + printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count); + goto fail; + } + + value = (char*)HashTable_GetItemValue(table, key1); + + if (strcmp(value, val1) != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val1, value); + goto fail; + } + + value = (char*)HashTable_GetItemValue(table, key2); + + if (strcmp(value, val2) != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val2, value); + goto fail; + } + + value = (char*)HashTable_GetItemValue(table, key3); + + if (strcmp(value, val3) != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val3, value); + goto fail; + } + + if (!HashTable_SetItemValue(table, key2, "apple")) + goto fail; + value = (char*)HashTable_GetItemValue(table, key2); + + if (strcmp(value, "apple") != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", "apple", value); + goto fail; + } + + if (!HashTable_Contains(table, key2)) + { + printf("HashTable_Contains: Expected : TRUE, Actual: FALSE\n"); + goto fail; + } + + if (!HashTable_Remove(table, key2)) + { + printf("HashTable_Remove: Expected : TRUE, Actual: FALSE\n"); + goto fail; + } + + if (HashTable_Remove(table, key2)) + { + printf("HashTable_Remove: Expected : FALSE, Actual: TRUE\n"); + goto fail; + } + + HashTable_Clear(table); + count = HashTable_Count(table); + + if (count != 0) + { + printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count); + goto fail; + } + + rc = 1; +fail: + HashTable_Free(table); + return rc; +} + +static int test_hash_table_string(void) +{ + int rc = -1; + size_t count = 0; + char* value = NULL; + wHashTable* table = HashTable_New(TRUE); + + if (!table) + return -1; + + if (!HashTable_SetupForStringData(table, TRUE)) + goto fail; + + if (!HashTable_Insert(table, key1, val1)) + goto fail; + if (!HashTable_Insert(table, key2, val2)) + goto fail; + if (!HashTable_Insert(table, key3, val3)) + goto fail; + count = HashTable_Count(table); + + if (count != 3) + { + printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Remove(table, key2)) + goto fail; + count = HashTable_Count(table); + + if (count != 2) + { + printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Remove(table, key3)) + goto fail; + count = HashTable_Count(table); + + if (count != 1) + { + printf("HashTable_Count: Expected : 1, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Remove(table, key1)) + goto fail; + count = HashTable_Count(table); + + if (count != 0) + { + printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count); + goto fail; + } + + if (!HashTable_Insert(table, key1, val1)) + goto fail; + if (!HashTable_Insert(table, key2, val2)) + goto fail; + if (!HashTable_Insert(table, key3, val3)) + goto fail; + count = HashTable_Count(table); + + if (count != 3) + { + printf("HashTable_Count: Expected : 3, Actual: %" PRIuz "\n", count); + goto fail; + } + + value = (char*)HashTable_GetItemValue(table, key1); + + if (strcmp(value, val1) != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val1, value); + goto fail; + } + + value = (char*)HashTable_GetItemValue(table, key2); + + if (strcmp(value, val2) != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val2, value); + goto fail; + } + + value = (char*)HashTable_GetItemValue(table, key3); + + if (strcmp(value, val3) != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val3, value); + goto fail; + } + + if (!HashTable_SetItemValue(table, key2, "apple")) + goto fail; + value = (char*)HashTable_GetItemValue(table, key2); + + if (strcmp(value, "apple") != 0) + { + printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", "apple", value); + goto fail; + } + + if (!HashTable_Contains(table, key2)) + { + printf("HashTable_Contains: Expected : TRUE, Actual: FALSE\n"); + goto fail; + } + + if (!HashTable_Remove(table, key2)) + { + printf("HashTable_Remove: Expected : TRUE, Actual: FALSE\n"); + goto fail; + } + + if (HashTable_Remove(table, key2)) + { + printf("HashTable_Remove: Expected : FALSE, Actual: TRUE\n"); + goto fail; + } + + HashTable_Clear(table); + count = HashTable_Count(table); + + if (count != 0) + { + printf("HashTable_Count: Expected : 0, Actual: %" PRIuz "\n", count); + goto fail; + } + + rc = 1; +fail: + HashTable_Free(table); + return rc; +} + +typedef struct +{ + wHashTable* table; + int strlenCounter; + int foreachCalls; + + BOOL test3error; +} ForeachData; + +static BOOL foreachFn1(const void* key, void* value, void* arg) +{ + ForeachData* d = (ForeachData*)arg; + WINPR_UNUSED(key); + d->strlenCounter += strlen((const char*)value); + return TRUE; +} + +static BOOL foreachFn2(const void* key, void* value, void* arg) +{ + ForeachData* d = (ForeachData*)arg; + WINPR_UNUSED(key); + WINPR_UNUSED(value); + d->foreachCalls++; + + if (d->foreachCalls == 2) + return FALSE; + return TRUE; +} + +static BOOL foreachFn3(const void* key, void* value, void* arg) +{ + const char* keyStr = (const char*)key; + + ForeachData* d = (ForeachData*)arg; + ForeachData d2; + + WINPR_UNUSED(value); + WINPR_ASSERT(keyStr); + + if (strcmp(keyStr, "key1") == 0) + { + /* when we pass on key1, let's remove key2 and check that the value is not + * visible anymore (even if has just been marked for removal)*/ + HashTable_Remove(d->table, "key2"); + + if (HashTable_Contains(d->table, "key2")) + { + d->test3error = TRUE; + return FALSE; + } + + if (HashTable_ContainsValue(d->table, "value2")) + { + d->test3error = TRUE; + return FALSE; + } + + /* number of elements of the table shall be correct too */ + if (HashTable_Count(d->table) != 2) + { + d->test3error = TRUE; + return FALSE; + } + + /* we try recursive HashTable_Foreach */ + d2.table = d->table; + d2.strlenCounter = 0; + + if (!HashTable_Foreach(d->table, foreachFn1, &d2)) + { + d->test3error = TRUE; + return FALSE; + } + if (d2.strlenCounter != 8) + { + d->test3error = TRUE; + return FALSE; + } + } + return TRUE; +} + +static int test_hash_foreach(void) +{ + ForeachData foreachData; + wHashTable* table = NULL; + int retCode = 0; + + foreachData.table = table = HashTable_New(TRUE); + if (!table) + return -1; + + if (!HashTable_SetupForStringData(table, TRUE)) + goto out; + + if (HashTable_Insert(table, key1, val1) < 0 || HashTable_Insert(table, key2, val2) < 0 || + HashTable_Insert(table, key3, val3) < 0) + { + retCode = -2; + goto out; + } + + /* let's try a first trivial foreach */ + foreachData.strlenCounter = 0; + if (!HashTable_Foreach(table, foreachFn1, &foreachData)) + { + retCode = -10; + goto out; + } + if (foreachData.strlenCounter != 12) + { + retCode = -11; + goto out; + } + + /* interrupted foreach */ + foreachData.foreachCalls = 0; + if (HashTable_Foreach(table, foreachFn2, &foreachData)) + { + retCode = -20; + goto out; + } + if (foreachData.foreachCalls != 2) + { + retCode = -21; + goto out; + } + + /* let's try a foreach() call that will remove a value from the table in the callback */ + foreachData.test3error = FALSE; + if (!HashTable_Foreach(table, foreachFn3, &foreachData)) + { + retCode = -30; + goto out; + } + if (foreachData.test3error) + { + retCode = -31; + goto out; + } + +out: + HashTable_Free(table); + return retCode; +} + +int TestHashTable(int argc, char* argv[]) +{ + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (test_hash_table_pointer() < 0) + return 1; + + if (test_hash_table_string() < 0) + return 2; + + if (test_hash_foreach() < 0) + return 3; + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestImage.c b/winpr/libwinpr/utils/test/TestImage.c new file mode 100644 index 0000000..8635fa1 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestImage.c @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include +#include + +static const char test_src_filename[] = TEST_SOURCE_PATH "/rgb"; +static const char test_bin_filename[] = TEST_BINARY_PATH "/rgb"; + +static BOOL test_image_equal(const wImage* imageA, const wImage* imageB) +{ + return winpr_image_equal(imageA, imageB, + WINPR_IMAGE_CMP_IGNORE_DEPTH | WINPR_IMAGE_CMP_IGNORE_ALPHA | + WINPR_IMAGE_CMP_FUZZY); +} + +static BOOL test_equal_to(const wImage* bmp, const char* name, UINT32 format) +{ + BOOL rc = FALSE; + wImage* cmp = winpr_image_new(); + if (!cmp) + goto fail; + + char path[MAX_PATH] = { 0 }; + _snprintf(path, sizeof(path), "%s.%s", name, winpr_image_format_extension(format)); + const int cmpSize = winpr_image_read(cmp, path); + if (cmpSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, path); + goto fail; + } + + rc = test_image_equal(bmp, cmp); + if (!rc) + fprintf(stderr, "[%s] winpr_image_eqal failed", __func__); + +fail: + winpr_image_free(cmp, TRUE); + return rc; +} + +static BOOL test_equal(void) +{ + BOOL rc = FALSE; + wImage* bmp = winpr_image_new(); + + if (!bmp) + goto fail; + + char path[MAX_PATH] = { 0 }; + _snprintf(path, sizeof(path), "%s.bmp", test_src_filename); + PathCchConvertStyleA(path, sizeof(path), PATH_STYLE_NATIVE); + + const int bmpSize = winpr_image_read(bmp, path); + if (bmpSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, path); + goto fail; + } + + for (UINT32 x = 0; x < UINT8_MAX; x++) + { + if (!winpr_image_format_is_supported(x)) + continue; + if (!test_equal_to(bmp, test_src_filename, x)) + goto fail; + } + + rc = TRUE; +fail: + winpr_image_free(bmp, TRUE); + + return rc; +} + +static BOOL test_read_write_compare(const char* tname, const char* tdst, UINT32 format) +{ + BOOL rc = FALSE; + wImage* bmp1 = winpr_image_new(); + wImage* bmp2 = winpr_image_new(); + wImage* bmp3 = winpr_image_new(); + if (!bmp1 || !bmp2 || !bmp3) + goto fail; + + char spath[MAX_PATH] = { 0 }; + char dpath[MAX_PATH] = { 0 }; + char bpath1[MAX_PATH] = { 0 }; + char bpath2[MAX_PATH] = { 0 }; + _snprintf(spath, sizeof(spath), "%s.%s", tname, winpr_image_format_extension(format)); + _snprintf(dpath, sizeof(dpath), "%s.%s", tdst, winpr_image_format_extension(format)); + _snprintf(bpath1, sizeof(bpath1), "%s.src.%s", dpath, + winpr_image_format_extension(WINPR_IMAGE_BITMAP)); + _snprintf(bpath2, sizeof(bpath2), "%s.bin.%s", dpath, + winpr_image_format_extension(WINPR_IMAGE_BITMAP)); + PathCchConvertStyleA(spath, sizeof(spath), PATH_STYLE_NATIVE); + PathCchConvertStyleA(dpath, sizeof(dpath), PATH_STYLE_NATIVE); + PathCchConvertStyleA(bpath1, sizeof(bpath1), PATH_STYLE_NATIVE); + PathCchConvertStyleA(bpath2, sizeof(bpath2), PATH_STYLE_NATIVE); + + const int bmpRSize = winpr_image_read(bmp1, spath); + if (bmpRSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, spath); + goto fail; + } + + const int bmpWSize = winpr_image_write(bmp1, dpath); + if (bmpWSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_write failed for %s", __func__, dpath); + goto fail; + } + + const int bmp2RSize = winpr_image_read(bmp2, dpath); + if (bmp2RSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, dpath); + goto fail; + } + + const int bmpSrcWSize = winpr_image_write_ex(bmp1, WINPR_IMAGE_BITMAP, bpath1); + if (bmpSrcWSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_write_ex failed for %s", __func__, bpath1); + goto fail; + } + + /* write a bitmap and read it back. + * this tests if we have the proper internal format */ + const int bmpBinWSize = winpr_image_write_ex(bmp2, WINPR_IMAGE_BITMAP, bpath2); + if (bmpBinWSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_write_ex failed for %s", __func__, bpath2); + goto fail; + } + + const int bmp3RSize = winpr_image_read(bmp3, bpath2); + if (bmp3RSize <= 0) + { + fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, bpath2); + goto fail; + } + + if (!winpr_image_equal(bmp1, bmp2, + WINPR_IMAGE_CMP_IGNORE_DEPTH | WINPR_IMAGE_CMP_IGNORE_ALPHA | + WINPR_IMAGE_CMP_FUZZY)) + { + fprintf(stderr, "[%s] winpr_image_eqal failed bmp1 bmp2", __func__); + goto fail; + } + + rc = winpr_image_equal(bmp3, bmp2, + WINPR_IMAGE_CMP_IGNORE_DEPTH | WINPR_IMAGE_CMP_IGNORE_ALPHA | + WINPR_IMAGE_CMP_FUZZY); + if (!rc) + fprintf(stderr, "[%s] winpr_image_eqal failed bmp3 bmp2", __func__); +fail: + winpr_image_free(bmp1, TRUE); + winpr_image_free(bmp2, TRUE); + winpr_image_free(bmp3, TRUE); + return rc; +} + +static BOOL test_read_write(void) +{ + BOOL rc = TRUE; + for (UINT32 x = 0; x < UINT8_MAX; x++) + { + if (!winpr_image_format_is_supported(x)) + continue; + if (!test_read_write_compare(test_src_filename, test_bin_filename, x)) + rc = FALSE; + } + return rc; +} + +static BOOL test_load_file(const char* name) +{ + BOOL rc = FALSE; + wImage* image = winpr_image_new(); + if (!image || !name) + goto fail; + + const int res = winpr_image_read(image, name); + rc = (res > 0) ? TRUE : FALSE; + +fail: + winpr_image_free(image, TRUE); + return rc; +} + +static BOOL test_load(void) +{ + const char* names[] = { + "rgb.16a.bmp", "rgb.16a.nocolor.bmp", "rgb.16.bmp", "rgb.16.nocolor.bmp", + "rgb.16x.bmp", "rgb.16x.nocolor.bmp", "rgb.24.bmp", "rgb.24.nocolor.bmp", + "rgb.32.bmp", "rgb.32.nocolor.bmp", "rgb.32x.bmp", "rgb.32x.nocolor.bmp", + "rgb.bmp" + }; + + for (size_t x = 0; x < ARRAYSIZE(names); x++) + { + const char* name = names[x]; + char* fname = GetCombinedPath(TEST_SOURCE_PATH, name); + const BOOL res = test_load_file(fname); + free(fname); + if (!res) + return FALSE; + } + + return TRUE; +} + +int TestImage(int argc, char* argv[]) +{ + int rc = 0; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!test_equal()) + rc -= 1; + + if (!test_read_write()) + rc -= 2; + + if (!test_load()) + rc -= 4; + + return rc; +} diff --git a/winpr/libwinpr/utils/test/TestIni.c b/winpr/libwinpr/utils/test/TestIni.c new file mode 100644 index 0000000..2dd24f0 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestIni.c @@ -0,0 +1,160 @@ + +#include +#include + +static const char TEST_INI_01[] = "; This is a sample .ini config file\n" + "\n" + "[first_section]\n" + "one = 1\n" + "five = 5\n" + "animal = BIRD\n" + "\n" + "[second_section]\n" + "path = \"/usr/local/bin\"\n" + "URL = \"http://www.example.com/~username\"\n" + "\n"; + +static const char TEST_INI_02[] = "[FreeRDS]\n" + "prefix=\"/usr/local\"\n" + "bindir=\"bin\"\n" + "sbindir=\"sbin\"\n" + "libdir=\"lib\"\n" + "datarootdir=\"share\"\n" + "localstatedir=\"var\"\n" + "sysconfdir=\"etc\"\n" + "\n"; + +static const char TEST_INI_03[] = "[FreeRDS]\n" + "prefix=\"/usr/local\"\n" + "bindir=\"bin\"\n" + "# some illegal string\n" + "sbindir=\"sbin\"\n" + "libdir=\"lib\"\n" + "invalid key-value pair\n" + "datarootdir=\"share\"\n" + "localstatedir=\"var\"\n" + "sysconfdir=\"etc\"\n" + "\n"; + +int TestIni(int argc, char* argv[]) +{ + int rc = -1; + size_t nKeys = 0; + size_t nSections = 0; + UINT32 iValue = 0; + wIniFile* ini = NULL; + const char* sValue = NULL; + char** keyNames = NULL; + char** sectionNames = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + /* First Sample */ + ini = IniFile_New(); + if (!ini) + goto fail; + + if (IniFile_ReadBuffer(ini, TEST_INI_01) < 0) + goto fail; + + free(sectionNames); + sectionNames = IniFile_GetSectionNames(ini, &nSections); + if (!sectionNames && (nSections > 0)) + goto fail; + + for (size_t i = 0; i < nSections; i++) + { + free(keyNames); + keyNames = IniFile_GetSectionKeyNames(ini, sectionNames[i], &nKeys); + printf("[%s]\n", sectionNames[i]); + if (!keyNames && (nKeys > 0)) + goto fail; + for (size_t j = 0; j < nKeys; j++) + { + sValue = IniFile_GetKeyValueString(ini, sectionNames[i], keyNames[j]); + printf("%s = %s\n", keyNames[j], sValue); + } + } + + iValue = IniFile_GetKeyValueInt(ini, "first_section", "one"); + + if (iValue != 1) + { + printf("IniFile_GetKeyValueInt failure\n"); + goto fail; + } + + iValue = IniFile_GetKeyValueInt(ini, "first_section", "five"); + + if (iValue != 5) + { + printf("IniFile_GetKeyValueInt failure\n"); + goto fail; + } + + sValue = IniFile_GetKeyValueString(ini, "first_section", "animal"); + + if (strcmp(sValue, "BIRD") != 0) + { + printf("IniFile_GetKeyValueString failure\n"); + goto fail; + } + + sValue = IniFile_GetKeyValueString(ini, "second_section", "path"); + + if (strcmp(sValue, "/usr/local/bin") != 0) + { + printf("IniFile_GetKeyValueString failure\n"); + goto fail; + } + + sValue = IniFile_GetKeyValueString(ini, "second_section", "URL"); + + if (strcmp(sValue, "http://www.example.com/~username") != 0) + { + printf("IniFile_GetKeyValueString failure\n"); + goto fail; + } + + IniFile_Free(ini); + /* Second Sample */ + ini = IniFile_New(); + if (!ini) + goto fail; + if (IniFile_ReadBuffer(ini, TEST_INI_02) < 0) + goto fail; + free(sectionNames); + sectionNames = IniFile_GetSectionNames(ini, &nSections); + if (!sectionNames && (nSections > 0)) + goto fail; + + for (size_t i = 0; i < nSections; i++) + { + free(keyNames); + keyNames = IniFile_GetSectionKeyNames(ini, sectionNames[i], &nKeys); + printf("[%s]\n", sectionNames[i]); + + if (!keyNames && (nKeys > 0)) + goto fail; + for (size_t j = 0; j < nKeys; j++) + { + sValue = IniFile_GetKeyValueString(ini, sectionNames[i], keyNames[j]); + printf("%s = %s\n", keyNames[j], sValue); + } + } + + IniFile_Free(ini); + /* Third sample - invalid input */ + ini = IniFile_New(); + + if (IniFile_ReadBuffer(ini, TEST_INI_03) != -1) + goto fail; + + rc = 0; +fail: + free(keyNames); + free(sectionNames); + IniFile_Free(ini); + return rc; +} diff --git a/winpr/libwinpr/utils/test/TestLinkedList.c b/winpr/libwinpr/utils/test/TestLinkedList.c new file mode 100644 index 0000000..6c6a2c3 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestLinkedList.c @@ -0,0 +1,135 @@ + +#include +#include +#include + +int TestLinkedList(int argc, char* argv[]) +{ + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + wLinkedList* list = LinkedList_New(); + if (!list) + return -1; + + if (!LinkedList_AddFirst(list, (void*)(size_t)1)) + return -1; + if (!LinkedList_AddLast(list, (void*)(size_t)2)) + return -1; + if (!LinkedList_AddLast(list, (void*)(size_t)3)) + return -1; + size_t count = LinkedList_Count(list); + + if (count != 3) + { + printf("LinkedList_Count: expected 3, actual: %" PRIuz "\n", count); + return -1; + } + + LinkedList_Enumerator_Reset(list); + + while (LinkedList_Enumerator_MoveNext(list)) + { + printf("\t%p\n", LinkedList_Enumerator_Current(list)); + } + + printf("\n"); + printf("LinkedList First: %p Last: %p\n", LinkedList_First(list), LinkedList_Last(list)); + LinkedList_RemoveFirst(list); + LinkedList_RemoveLast(list); + count = LinkedList_Count(list); + + if (count != 1) + { + printf("LinkedList_Count: expected 1, actual: %" PRIuz "\n", count); + return -1; + } + + LinkedList_Enumerator_Reset(list); + + while (LinkedList_Enumerator_MoveNext(list)) + { + printf("\t%p\n", LinkedList_Enumerator_Current(list)); + } + + printf("\n"); + printf("LinkedList First: %p Last: %p\n", LinkedList_First(list), LinkedList_Last(list)); + LinkedList_RemoveFirst(list); + LinkedList_RemoveLast(list); + count = LinkedList_Count(list); + + if (count != 0) + { + printf("LinkedList_Count: expected 0, actual: %" PRIuz "\n", count); + return -1; + } + + if (!LinkedList_AddFirst(list, (void*)(size_t)4)) + return -1; + if (!LinkedList_AddLast(list, (void*)(size_t)5)) + return -1; + if (!LinkedList_AddLast(list, (void*)(size_t)6)) + return -1; + count = LinkedList_Count(list); + + if (count != 3) + { + printf("LinkedList_Count: expected 3, actual: %" PRIuz "\n", count); + return -1; + } + + LinkedList_Enumerator_Reset(list); + + while (LinkedList_Enumerator_MoveNext(list)) + { + printf("\t%p\n", LinkedList_Enumerator_Current(list)); + } + + printf("\n"); + printf("LinkedList First: %p Last: %p\n", LinkedList_First(list), LinkedList_Last(list)); + if (!LinkedList_Remove(list, (void*)(size_t)5)) + return -1; + LinkedList_Enumerator_Reset(list); + + while (LinkedList_Enumerator_MoveNext(list)) + { + printf("\t%p\n", LinkedList_Enumerator_Current(list)); + } + + printf("\n"); + printf("LinkedList First: %p Last: %p\n", LinkedList_First(list), LinkedList_Last(list)); + LinkedList_Free(list); + /* Test enumerator robustness */ + /* enumerator on an empty list */ + list = LinkedList_New(); + if (!list) + return -1; + LinkedList_Enumerator_Reset(list); + + while (LinkedList_Enumerator_MoveNext(list)) + { + printf("\terror: %p\n", LinkedList_Enumerator_Current(list)); + } + + printf("\n"); + LinkedList_Free(list); + /* Use an enumerator without reset */ + list = LinkedList_New(); + if (!list) + return -1; + if (!LinkedList_AddFirst(list, (void*)(size_t)4)) + return -1; + if (!LinkedList_AddLast(list, (void*)(size_t)5)) + return -1; + if (!LinkedList_AddLast(list, (void*)(size_t)6)) + return -1; + + while (LinkedList_Enumerator_MoveNext(list)) + { + printf("\t%p\n", LinkedList_Enumerator_Current(list)); + } + + printf("\n"); + LinkedList_Free(list); + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestListDictionary.c b/winpr/libwinpr/utils/test/TestListDictionary.c new file mode 100644 index 0000000..7be8013 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestListDictionary.c @@ -0,0 +1,178 @@ + +#include +#include +#include + +static char* key1 = "key1"; +static char* key2 = "key2"; +static char* key3 = "key3"; + +static char* val1 = "val1"; +static char* val2 = "val2"; +static char* val3 = "val3"; + +int TestListDictionary(int argc, char* argv[]) +{ + size_t count = 0; + char* value = NULL; + wListDictionary* list = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + list = ListDictionary_New(TRUE); + if (!list) + return -1; + + if (!ListDictionary_Add(list, key1, val1) || !ListDictionary_Add(list, key2, val2) || + !ListDictionary_Add(list, key3, val3)) + return -1; + + count = ListDictionary_Count(list); + + if (count != 3) + { + printf("ListDictionary_Count: Expected : 3, Actual: %" PRIuz "\n", count); + return -1; + } + + ListDictionary_Remove(list, key2); + + count = ListDictionary_Count(list); + + if (count != 2) + { + printf("ListDictionary_Count: Expected : 2, Actual: %" PRIuz "\n", count); + return -1; + } + + ListDictionary_Remove(list, key3); + + count = ListDictionary_Count(list); + + if (count != 1) + { + printf("ListDictionary_Count: Expected : 1, Actual: %" PRIuz "\n", count); + return -1; + } + + ListDictionary_Remove(list, key1); + + count = ListDictionary_Count(list); + + if (count != 0) + { + printf("ListDictionary_Count: Expected : 0, Actual: %" PRIuz "\n", count); + return -1; + } + + if (!ListDictionary_Add(list, key1, val1) || !ListDictionary_Add(list, key2, val2) || + !ListDictionary_Add(list, key3, val3)) + return -1; + + count = ListDictionary_Count(list); + + if (count != 3) + { + printf("ListDictionary_Count: Expected : 3, Actual: %" PRIuz "\n", count); + return -1; + } + + value = (char*)ListDictionary_GetItemValue(list, key1); + + if (strcmp(value, val1) != 0) + { + printf("ListDictionary_GetItemValue: Expected : %" PRIuz ", Actual: %" PRIuz "\n", + (size_t)val1, (size_t)value); + return -1; + } + + value = (char*)ListDictionary_GetItemValue(list, key2); + + if (strcmp(value, val2) != 0) + { + printf("ListDictionary_GetItemValue: Expected : %" PRIuz ", Actual: %" PRIuz "\n", + (size_t)val2, (size_t)value); + return -1; + } + + value = (char*)ListDictionary_GetItemValue(list, key3); + + if (strcmp(value, val3) != 0) + { + printf("ListDictionary_GetItemValue: Expected : %" PRIuz ", Actual: %" PRIuz "\n", + (size_t)val3, (size_t)value); + return -1; + } + + ListDictionary_SetItemValue(list, key2, "apple"); + + value = (char*)ListDictionary_GetItemValue(list, key2); + + if (strcmp(value, "apple") != 0) + { + printf("ListDictionary_GetItemValue: Expected : %s, Actual: %s\n", "apple", value); + return -1; + } + + if (!ListDictionary_Contains(list, key2)) + { + printf("ListDictionary_Contains: Expected : TRUE, Actual: FALSE\n"); + return -1; + } + + if (!ListDictionary_Take(list, key2)) + { + printf("ListDictionary_Remove: Expected : TRUE, Actual: FALSE\n"); + return -1; + } + + if (ListDictionary_Take(list, key2)) + { + printf("ListDictionary_Remove: Expected : FALSE, Actual: TRUE\n"); + return -1; + } + + value = ListDictionary_Take_Head(list); + count = ListDictionary_Count(list); + if (strncmp(value, val1, 4) || count != 1) + { + printf("ListDictionary_Remove_Head: Expected : %s, Actual: %s Count: %" PRIuz "\n", val1, + value, count); + return -1; + } + + value = ListDictionary_Take_Head(list); + count = ListDictionary_Count(list); + if (strncmp(value, val3, 4) || count != 0) + { + printf("ListDictionary_Remove_Head: Expected : %s, Actual: %s Count: %" PRIuz "\n", val3, + value, count); + return -1; + } + + value = ListDictionary_Take_Head(list); + if (value) + { + printf("ListDictionary_Remove_Head: Expected : (null), Actual: %s\n", value); + return -1; + } + + if (!ListDictionary_Add(list, key1, val1) || !ListDictionary_Add(list, key2, val2) || + !ListDictionary_Add(list, key3, val3)) + return -1; + + ListDictionary_Clear(list); + + count = ListDictionary_Count(list); + + if (count != 0) + { + printf("ListDictionary_Count: Expected : 0, Actual: %" PRIuz "\n", count); + return -1; + } + + ListDictionary_Free(list); + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestMessagePipe.c b/winpr/libwinpr/utils/test/TestMessagePipe.c new file mode 100644 index 0000000..c5a3ee2 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestMessagePipe.c @@ -0,0 +1,105 @@ + +#include +#include +#include + +static DWORD WINAPI message_echo_pipe_client_thread(LPVOID arg) +{ + int index = 0; + wMessagePipe* pipe = (wMessagePipe*)arg; + + while (index < 100) + { + wMessage message = { 0 }; + int count = -1; + + if (!MessageQueue_Post(pipe->In, NULL, 0, (void*)(size_t)index, NULL)) + break; + + if (!MessageQueue_Wait(pipe->Out)) + break; + + if (!MessageQueue_Peek(pipe->Out, &message, TRUE)) + break; + + if (message.id == WMQ_QUIT) + break; + + count = (int)(size_t)message.wParam; + + if (count != index) + printf("Echo count mismatch: Actual: %d, Expected: %d\n", count, index); + + index++; + } + + MessageQueue_PostQuit(pipe->In, 0); + + return 0; +} + +static DWORD WINAPI message_echo_pipe_server_thread(LPVOID arg) +{ + wMessage message = { 0 }; + wMessagePipe* pipe = (wMessagePipe*)arg; + + while (MessageQueue_Wait(pipe->In)) + { + if (MessageQueue_Peek(pipe->In, &message, TRUE)) + { + if (message.id == WMQ_QUIT) + break; + + if (!MessageQueue_Dispatch(pipe->Out, &message)) + break; + } + } + + return 0; +} + +int TestMessagePipe(int argc, char* argv[]) +{ + HANDLE ClientThread = NULL; + HANDLE ServerThread = NULL; + wMessagePipe* EchoPipe = NULL; + int ret = 1; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!(EchoPipe = MessagePipe_New())) + { + printf("failed to create message pipe\n"); + goto out; + } + + if (!(ClientThread = + CreateThread(NULL, 0, message_echo_pipe_client_thread, (void*)EchoPipe, 0, NULL))) + { + printf("failed to create client thread\n"); + goto out; + } + + if (!(ServerThread = + CreateThread(NULL, 0, message_echo_pipe_server_thread, (void*)EchoPipe, 0, NULL))) + { + printf("failed to create server thread\n"); + goto out; + } + + WaitForSingleObject(ClientThread, INFINITE); + WaitForSingleObject(ServerThread, INFINITE); + + ret = 0; + +out: + if (EchoPipe) + MessagePipe_Free(EchoPipe); + if (ClientThread) + CloseHandle(ClientThread); + if (ServerThread) + CloseHandle(ServerThread); + + return ret; +} diff --git a/winpr/libwinpr/utils/test/TestMessageQueue.c b/winpr/libwinpr/utils/test/TestMessageQueue.c new file mode 100644 index 0000000..b3245b1 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestMessageQueue.c @@ -0,0 +1,56 @@ + +#include +#include +#include + +static DWORD WINAPI message_queue_consumer_thread(LPVOID arg) +{ + wMessage message = { 0 }; + wMessageQueue* queue = (wMessageQueue*)arg; + + while (MessageQueue_Wait(queue)) + { + if (MessageQueue_Peek(queue, &message, TRUE)) + { + if (message.id == WMQ_QUIT) + break; + + printf("Message.Type: %" PRIu32 "\n", message.id); + } + } + + return 0; +} + +int TestMessageQueue(int argc, char* argv[]) +{ + HANDLE thread = NULL; + wMessageQueue* queue = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!(queue = MessageQueue_New(NULL))) + { + printf("failed to create message queue\n"); + return 1; + } + + if (!(thread = CreateThread(NULL, 0, message_queue_consumer_thread, (void*)queue, 0, NULL))) + { + printf("failed to create thread\n"); + MessageQueue_Free(queue); + return 1; + } + + if (!MessageQueue_Post(queue, NULL, 123, NULL, NULL) || + !MessageQueue_Post(queue, NULL, 456, NULL, NULL) || + !MessageQueue_Post(queue, NULL, 789, NULL, NULL) || !MessageQueue_PostQuit(queue, 0) || + WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) + return -1; + + MessageQueue_Free(queue); + CloseHandle(thread); + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestPrint.c b/winpr/libwinpr/utils/test/TestPrint.c new file mode 100644 index 0000000..f60b903 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestPrint.c @@ -0,0 +1,401 @@ + +#include +#include +#include +#include + +/** + * C Programming/C Reference/stdio.h/printf: + * http://en.wikibooks.org/wiki/C_Programming/C_Reference/stdio.h/printf + * + * C Programming/Procedures and functions/printf: + * http://en.wikibooks.org/wiki/C_Programming/Procedures_and_functions/printf + * + * C Tutorial – printf, Format Specifiers, Format Conversions and Formatted Output: + * http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output + */ + +#define _printf printf + +static BOOL test_bin_tohex_string(void) +{ + BOOL rc = FALSE; + { + const BYTE binbuffer[33] = { 0 }; + const char empty[33] = { 0 }; + char strbuffer[33] = { 0 }; + + size_t len = + winpr_BinToHexStringBuffer(NULL, sizeof(binbuffer), strbuffer, sizeof(strbuffer), TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer, 0, strbuffer, sizeof(strbuffer), TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = + winpr_BinToHexStringBuffer(binbuffer, sizeof(binbuffer), NULL, sizeof(strbuffer), TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer, sizeof(binbuffer), strbuffer, 0, TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer, 0, strbuffer, 0, TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer, sizeof(binbuffer), NULL, 0, TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(NULL, sizeof(binbuffer), strbuffer, 0, TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + + len = winpr_BinToHexStringBuffer(binbuffer, 0, NULL, 0, TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(NULL, 0, NULL, 0, TRUE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer, 0, NULL, 0, FALSE); + if (len != 0) + goto fail; + if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0) + goto fail; + } + { + const BYTE binbuffer1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + const char strbuffer1[] = "0102030405060708090A0B0C0D0E0F1011"; + const char strbuffer1_space[] = "01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11"; + + char buffer[1024] = { 0 }; + size_t len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer, + sizeof(buffer), FALSE); + if (len != strnlen(strbuffer1, sizeof(strbuffer1))) + goto fail; + if (memcmp(strbuffer1, buffer, sizeof(strbuffer1)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer, sizeof(buffer), + TRUE); + if (len != strnlen(strbuffer1_space, sizeof(strbuffer1_space))) + goto fail; + if (memcmp(strbuffer1_space, buffer, sizeof(strbuffer1_space)) != 0) + goto fail; + } + { + const BYTE binbuffer1[] = { 0xF1, 0xe2, 0xD3, 0xc4, 0xB5, 0xA6, 0x97, 0x88, 0x79, + 0x6A, 0x5b, 0x4C, 0x3d, 0x2E, 0x1f, 0x00, 0xfF }; + const char strbuffer1[] = "F1E2D3C4B5A69788796A5B4C3D2E1F00FF"; + const char strbuffer1_space[] = "F1 E2 D3 C4 B5 A6 97 88 79 6A 5B 4C 3D 2E 1F 00 FF"; + char buffer[1024] = { 0 }; + size_t len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer, + sizeof(buffer), FALSE); + if (len != strnlen(strbuffer1, sizeof(strbuffer1))) + goto fail; + if (memcmp(strbuffer1, buffer, sizeof(strbuffer1)) != 0) + goto fail; + len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer, sizeof(buffer), + TRUE); + if (len != strnlen(strbuffer1_space, sizeof(strbuffer1_space))) + goto fail; + if (memcmp(strbuffer1_space, buffer, sizeof(strbuffer1_space)) != 0) + goto fail; + } + { + } + rc = TRUE; +fail: + return rc; +} + +static BOOL test_bin_tohex_string_alloc(void) +{ + BOOL rc = FALSE; + char* str = NULL; + { + const BYTE binbuffer[33] = { 0 }; + + str = winpr_BinToHexString(NULL, sizeof(binbuffer), TRUE); + if (str) + goto fail; + str = winpr_BinToHexString(binbuffer, 0, TRUE); + if (str) + goto fail; + str = winpr_BinToHexString(binbuffer, 0, FALSE); + if (str) + goto fail; + str = winpr_BinToHexString(NULL, sizeof(binbuffer), FALSE); + if (str) + goto fail; + } + { + const BYTE binbuffer1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + const char strbuffer1[] = "0102030405060708090A0B0C0D0E0F1011"; + const char strbuffer1_space[] = "01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11"; + + str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), FALSE); + if (!str) + goto fail; + if (memcmp(strbuffer1, str, sizeof(strbuffer1)) != 0) + goto fail; + free(str); + str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), TRUE); + if (!str) + goto fail; + if (memcmp(strbuffer1_space, str, sizeof(strbuffer1_space)) != 0) + goto fail; + free(str); + str = NULL; + } + { + const BYTE binbuffer1[] = { 0xF1, 0xe2, 0xD3, 0xc4, 0xB5, 0xA6, 0x97, 0x88, 0x79, + 0x6A, 0x5b, 0x4C, 0x3d, 0x2E, 0x1f, 0x00, 0xfF }; + const char strbuffer1[] = "F1E2D3C4B5A69788796A5B4C3D2E1F00FF"; + const char strbuffer1_space[] = "F1 E2 D3 C4 B5 A6 97 88 79 6A 5B 4C 3D 2E 1F 00 FF"; + str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), FALSE); + if (!str) + goto fail; + if (memcmp(strbuffer1, str, sizeof(strbuffer1)) != 0) + goto fail; + + free(str); + str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), TRUE); + if (!str) + goto fail; + if (memcmp(strbuffer1_space, str, sizeof(strbuffer1_space)) != 0) + goto fail; + free(str); + str = NULL; + } + rc = TRUE; +fail: + free(str); + return rc; +} + +static BOOL test_hex_string_to_bin(void) +{ + BOOL rc = FALSE; + { + const char stringbuffer[] = "123456789ABCDEFabcdef"; + const BYTE empty[1024] = { 0 }; + BYTE buffer[1024] = { 0 }; + size_t len = winpr_HexStringToBinBuffer(NULL, 0, NULL, 0); + if (len != 0) + goto fail; + if (memcmp(buffer, empty, sizeof(buffer)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(NULL, sizeof(stringbuffer), buffer, sizeof(buffer)); + if (len != 0) + goto fail; + if (memcmp(buffer, empty, sizeof(buffer)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, 0, buffer, sizeof(buffer)); + if (len != 0) + goto fail; + if (memcmp(buffer, empty, sizeof(buffer)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), NULL, sizeof(buffer)); + if (len != 0) + goto fail; + if (memcmp(buffer, empty, sizeof(buffer)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, 0); + if (len != 0) + goto fail; + if (memcmp(buffer, empty, sizeof(buffer)) != 0) + goto fail; + } + { + const char stringbuffer[] = "123456789ABCDEF1abcdef"; + const BYTE expected[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, 0xab, 0xcd, 0xef + }; + BYTE buffer[32] = { 0 }; + size_t len = + winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer)); + if (len != sizeof(expected)) + goto fail; + if (memcmp(buffer, expected, sizeof(expected)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, + sizeof(expected) / 2); + if (len != sizeof(expected) / 2) + goto fail; + if (memcmp(buffer, expected, sizeof(expected) / 2) != 0) + goto fail; + } + { + const char stringbuffer[] = "12 34 56 78 9A BC DE F1 ab cd ef"; + const BYTE expected[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, 0xab, 0xcd, 0xef + }; + BYTE buffer[1024] = { 0 }; + size_t len = + winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer)); + if (len != sizeof(expected)) + goto fail; + if (memcmp(buffer, expected, sizeof(expected)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, + sizeof(expected) / 2); + if (len != sizeof(expected) / 2) + goto fail; + if (memcmp(buffer, expected, sizeof(expected) / 2) != 0) + goto fail; + } + { + const char stringbuffer[] = "123456789ABCDEF1abcdef9"; + const BYTE expected[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, + 0xde, 0xf1, 0xab, 0xcd, 0xef, 0x09 }; + BYTE buffer[1024] = { 0 }; + size_t len = + winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer)); + if (len != sizeof(expected)) + goto fail; + if (memcmp(buffer, expected, sizeof(expected)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, + sizeof(expected) / 2); + if (len != sizeof(expected) / 2) + goto fail; + if (memcmp(buffer, expected, sizeof(expected) / 2) != 0) + goto fail; + } + { + const char stringbuffer[] = "12 34 56 78 9A BC DE F1 ab cd ef 9"; + const BYTE expected[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, + 0xde, 0xf1, 0xab, 0xcd, 0xef, 0x09 }; + BYTE buffer[1024] = { 0 }; + size_t len = + winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer)); + if (len != sizeof(expected)) + goto fail; + if (memcmp(buffer, expected, sizeof(expected)) != 0) + goto fail; + len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, + sizeof(expected) / 2); + if (len != sizeof(expected) / 2) + goto fail; + if (memcmp(buffer, expected, sizeof(expected) / 2) != 0) + goto fail; + } + rc = TRUE; +fail: + return rc; +} + +int TestPrint(int argc, char* argv[]) +{ + int a = 0; + int b = 0; + float c = NAN; + float d = NAN; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + /** + * 7 + * 7 + * 007 + * 5.10 + */ + + a = 15; + b = a / 2; + _printf("%d\n", b); + _printf("%3d\n", b); + _printf("%03d\n", b); + c = 15.3f; + d = c / 3.0f; + _printf("%3.2f\n", d); + + /** + * 0 -17.778 + * 20 -6.667 + * 40 04.444 + * 60 15.556 + * 80 26.667 + * 100 37.778 + * 120 48.889 + * 140 60.000 + * 160 71.111 + * 180 82.222 + * 200 93.333 + * 220 104.444 + * 240 115.556 + * 260 126.667 + * 280 137.778 + * 300 148.889 + */ + + for (int a = 0; a <= 300; a = a + 20) + _printf("%3d %06.3f\n", a, (5.0 / 9.0) * (a - 32)); + + /** + * The color: blue + * First number: 12345 + * Second number: 0025 + * Third number: 1234 + * Float number: 3.14 + * Hexadecimal: ff + * Octal: 377 + * Unsigned value: 150 + * Just print the percentage sign % + */ + + _printf("The color: %s\n", "blue"); + _printf("First number: %d\n", 12345); + _printf("Second number: %04d\n", 25); + _printf("Third number: %i\n", 1234); + _printf("Float number: %3.2f\n", 3.14159); + _printf("Hexadecimal: %x/%X\n", 255, 255); + _printf("Octal: %o\n", 255); + _printf("Unsigned value: %u\n", 150); + _printf("Just print the percentage sign %%\n"); + + /** + * :Hello, world!: + * : Hello, world!: + * :Hello, wor: + * :Hello, world!: + * :Hello, world! : + * :Hello, world!: + * : Hello, wor: + * :Hello, wor : + */ + + _printf(":%s:\n", "Hello, world!"); + _printf(":%15s:\n", "Hello, world!"); + _printf(":%.10s:\n", "Hello, world!"); + _printf(":%-10s:\n", "Hello, world!"); + _printf(":%-15s:\n", "Hello, world!"); + _printf(":%.15s:\n", "Hello, world!"); + _printf(":%15.10s:\n", "Hello, world!"); + _printf(":%-15.10s:\n", "Hello, world!"); + + if (!test_bin_tohex_string()) + return -1; + if (!test_bin_tohex_string_alloc()) + return -1; + if (!test_hex_string_to_bin()) + return -1; + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestPubSub.c b/winpr/libwinpr/utils/test/TestPubSub.c new file mode 100644 index 0000000..0b05b15 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestPubSub.c @@ -0,0 +1,73 @@ + +#include +#include +#include + +DEFINE_EVENT_BEGIN(MouseMotion) +int x; +int y; +DEFINE_EVENT_END(MouseMotion) + +DEFINE_EVENT_BEGIN(MouseButton) +int x; +int y; +int flags; +int button; +DEFINE_EVENT_END(MouseButton) + +static void MouseMotionEventHandler(void* context, const MouseMotionEventArgs* e) +{ + printf("MouseMotionEvent: x: %d y: %d\n", e->x, e->y); +} + +static void MouseButtonEventHandler(void* context, const MouseButtonEventArgs* e) +{ + printf("MouseButtonEvent: x: %d y: %d flags: %d button: %d\n", e->x, e->y, e->flags, e->button); +} + +static wEventType Node_Events[] = { DEFINE_EVENT_ENTRY(MouseMotion), + DEFINE_EVENT_ENTRY(MouseButton) }; + +#define NODE_EVENT_COUNT (sizeof(Node_Events) / sizeof(wEventType)) + +int TestPubSub(int argc, char* argv[]) +{ + wPubSub* node = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + node = PubSub_New(TRUE); + if (!node) + return -1; + + PubSub_AddEventTypes(node, Node_Events, NODE_EVENT_COUNT); + + PubSub_SubscribeMouseMotion(node, MouseMotionEventHandler); + PubSub_SubscribeMouseButton(node, MouseButtonEventHandler); + + /* Call Event Handler */ + { + MouseMotionEventArgs e; + + e.x = 64; + e.y = 128; + + PubSub_OnMouseMotion(node, NULL, &e); + } + + { + MouseButtonEventArgs e; + + e.x = 23; + e.y = 56; + e.flags = 7; + e.button = 1; + + PubSub_OnMouseButton(node, NULL, &e); + } + + PubSub_Free(node); + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestQueue.c b/winpr/libwinpr/utils/test/TestQueue.c new file mode 100644 index 0000000..9c65af5 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestQueue.c @@ -0,0 +1,58 @@ + +#include +#include +#include + +int TestQueue(int argc, char* argv[]) +{ + size_t item = 0; + size_t count = 0; + wQueue* queue = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + queue = Queue_New(TRUE, -1, -1); + if (!queue) + return -1; + + for (size_t index = 1; index <= 10; index++) + { + Queue_Enqueue(queue, (void*)(size_t)index); + } + + count = Queue_Count(queue); + printf("queue count: %" PRIuz "\n", count); + + for (size_t index = 1; index <= 10; index++) + { + item = (size_t)Queue_Dequeue(queue); + + if (item != index) + return -1; + } + + count = Queue_Count(queue); + printf("queue count: %" PRIuz "\n", count); + + Queue_Enqueue(queue, (void*)(size_t)1); + Queue_Enqueue(queue, (void*)(size_t)2); + Queue_Enqueue(queue, (void*)(size_t)3); + + Queue_Dequeue(queue); + Queue_Dequeue(queue); + + Queue_Enqueue(queue, (void*)(size_t)4); + Queue_Enqueue(queue, (void*)(size_t)5); + Queue_Enqueue(queue, (void*)(size_t)6); + + Queue_Dequeue(queue); + Queue_Dequeue(queue); + Queue_Dequeue(queue); + Queue_Dequeue(queue); + + Queue_Clear(queue); + Queue_Free(queue); + + return 0; +} 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 +#include +#include + +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; +} diff --git a/winpr/libwinpr/utils/test/TestStreamPool.c b/winpr/libwinpr/utils/test/TestStreamPool.c new file mode 100644 index 0000000..1844a53 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestStreamPool.c @@ -0,0 +1,78 @@ + +#include +#include +#include + +#define BUFFER_SIZE 16384 + +int TestStreamPool(int argc, char* argv[]) +{ + wStream* s[5] = { 0 }; + char buffer[8192] = { 0 }; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + wStreamPool* pool = StreamPool_New(TRUE, BUFFER_SIZE); + + s[0] = StreamPool_Take(pool, 0); + s[1] = StreamPool_Take(pool, 0); + s[2] = StreamPool_Take(pool, 0); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + Stream_Release(s[0]); + Stream_Release(s[1]); + Stream_Release(s[2]); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + s[3] = StreamPool_Take(pool, 0); + s[4] = StreamPool_Take(pool, 0); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + Stream_Release(s[3]); + Stream_Release(s[4]); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + s[2] = StreamPool_Take(pool, 0); + s[3] = StreamPool_Take(pool, 0); + s[4] = StreamPool_Take(pool, 0); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + Stream_AddRef(s[2]); + + Stream_AddRef(s[3]); + Stream_AddRef(s[3]); + + Stream_AddRef(s[4]); + Stream_AddRef(s[4]); + Stream_AddRef(s[4]); + + Stream_Release(s[2]); + Stream_Release(s[2]); + + Stream_Release(s[3]); + Stream_Release(s[3]); + Stream_Release(s[3]); + + Stream_Release(s[4]); + Stream_Release(s[4]); + Stream_Release(s[4]); + Stream_Release(s[4]); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + s[2] = StreamPool_Take(pool, 0); + s[3] = StreamPool_Take(pool, 0); + s[4] = StreamPool_Take(pool, 0); + + printf("%s\n", StreamPool_GetStatistics(pool, buffer, sizeof(buffer))); + + StreamPool_Free(pool); + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestVersion.c b/winpr/libwinpr/utils/test/TestVersion.c new file mode 100644 index 0000000..71a1d74 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestVersion.c @@ -0,0 +1,47 @@ + +#include + +#include +#include + +int TestVersion(int argc, char* argv[]) +{ + const char* version = NULL; + const char* git = NULL; + const char* build = NULL; + int major = 0; + int minor = 0; + int revision = 0; + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + winpr_get_version(&major, &minor, &revision); + + if (major != WINPR_VERSION_MAJOR) + return -1; + + if (minor != WINPR_VERSION_MINOR) + return -1; + + if (revision != WINPR_VERSION_REVISION) + return -1; + + version = winpr_get_version_string(); + + if (!version) + return -1; + + git = winpr_get_build_revision(); + + if (!git) + return -1; + + if (strncmp(git, WINPR_GIT_REVISION, sizeof(WINPR_GIT_REVISION))) + return -1; + + build = winpr_get_build_config(); + + if (!build) + return -1; + + return 0; +} diff --git a/winpr/libwinpr/utils/test/TestWLog.c b/winpr/libwinpr/utils/test/TestWLog.c new file mode 100644 index 0000000..92f1114 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestWLog.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +int TestWLog(int argc, char* argv[]) +{ + wLog* root = NULL; + wLog* logA = NULL; + wLog* logB = NULL; + wLogLayout* layout = NULL; + wLogAppender* appender = NULL; + char* tmp_path = NULL; + char* wlog_file = NULL; + int result = 1; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!(tmp_path = GetKnownPath(KNOWN_PATH_TEMP))) + { + fprintf(stderr, "Failed to get temporary directory!\n"); + goto out; + } + + root = WLog_GetRoot(); + + WLog_SetLogAppenderType(root, WLOG_APPENDER_BINARY); + + appender = WLog_GetLogAppender(root); + if (!WLog_ConfigureAppender(appender, "outputfilename", "test_w.log")) + goto out; + if (!WLog_ConfigureAppender(appender, "outputfilepath", tmp_path)) + goto out; + + layout = WLog_GetLogLayout(root); + WLog_Layout_SetPrefixFormat(root, layout, "[%lv:%mn] [%fl|%fn|%ln] - "); + + WLog_OpenAppender(root); + + logA = WLog_Get("com.test.ChannelA"); + logB = WLog_Get("com.test.ChannelB"); + + WLog_SetLogLevel(logA, WLOG_INFO); + WLog_SetLogLevel(logB, WLOG_ERROR); + + WLog_Print(logA, WLOG_INFO, "this is a test"); + WLog_Print(logA, WLOG_WARN, "this is a %dnd %s", 2, "test"); + WLog_Print(logA, WLOG_ERROR, "this is an error"); + WLog_Print(logA, WLOG_TRACE, "this is a trace output"); + + WLog_Print(logB, WLOG_INFO, "just some info"); + WLog_Print(logB, WLOG_WARN, "we're warning a %dnd %s", 2, "time"); + WLog_Print(logB, WLOG_ERROR, "we've got an error"); + WLog_Print(logB, WLOG_TRACE, "leaving a trace behind"); + + WLog_CloseAppender(root); + + if ((wlog_file = GetCombinedPath(tmp_path, "test_w.log"))) + winpr_DeleteFile(wlog_file); + + result = 0; +out: + free(wlog_file); + free(tmp_path); + + return result; +} diff --git a/winpr/libwinpr/utils/test/TestWLogCallback.c b/winpr/libwinpr/utils/test/TestWLogCallback.c new file mode 100644 index 0000000..1acbf65 --- /dev/null +++ b/winpr/libwinpr/utils/test/TestWLogCallback.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include + +typedef struct +{ + UINT32 level; + char* msg; + char* channel; +} test_t; + +static const char* function = NULL; +static const char* channels[] = { "com.test.channelA", "com.test.channelB" }; + +static const test_t messages[] = { { WLOG_INFO, "this is a test", "com.test.channelA" }, + { WLOG_INFO, "Just some info", "com.test.channelB" }, + { WLOG_WARN, "this is a %dnd %s", "com.test.channelA" }, + { WLOG_WARN, "we're warning a %dnd %s", "com.test.channelB" }, + { WLOG_ERROR, "this is an error", "com.test.channelA" }, + { WLOG_ERROR, "we've got an error", "com.test.channelB" }, + { WLOG_TRACE, "this is a trace output", "com.test.channelA" }, + { WLOG_TRACE, "leaving a trace behind", "com.test.channelB" } }; + +static BOOL success = TRUE; +static int pos = 0; + +static BOOL check(const wLogMessage* msg) +{ + BOOL rc = TRUE; + if (!msg) + rc = FALSE; + else if (strcmp(msg->FileName, __FILE__)) + rc = FALSE; + else if (strcmp(msg->FunctionName, function)) + rc = FALSE; + else if (strcmp(msg->PrefixString, messages[pos].channel)) + rc = FALSE; + else if (msg->Level != messages[pos].level) + rc = FALSE; + else if (strcmp(msg->FormatString, messages[pos].msg)) + rc = FALSE; + pos++; + + if (!rc) + { + fprintf(stderr, "Test failed!\n"); + success = FALSE; + } + return rc; +} + +static BOOL CallbackAppenderMessage(const wLogMessage* msg) +{ + check(msg); + return TRUE; +} + +static BOOL CallbackAppenderData(const wLogMessage* msg) +{ + fprintf(stdout, "%s\n", __func__); + return TRUE; +} + +static BOOL CallbackAppenderImage(const wLogMessage* msg) +{ + fprintf(stdout, "%s\n", __func__); + return TRUE; +} + +static BOOL CallbackAppenderPackage(const wLogMessage* msg) +{ + fprintf(stdout, "%s\n", __func__); + return TRUE; +} + +int TestWLogCallback(int argc, char* argv[]) +{ + wLog* root = NULL; + wLog* logA = NULL; + wLog* logB = NULL; + wLogLayout* layout = NULL; + wLogAppender* appender = NULL; + wLogCallbacks callbacks; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + function = __func__; + + root = WLog_GetRoot(); + + WLog_SetLogAppenderType(root, WLOG_APPENDER_CALLBACK); + + appender = WLog_GetLogAppender(root); + + callbacks.data = CallbackAppenderData; + callbacks.image = CallbackAppenderImage; + callbacks.message = CallbackAppenderMessage; + callbacks.package = CallbackAppenderPackage; + + if (!WLog_ConfigureAppender(appender, "callbacks", (void*)&callbacks)) + return -1; + + layout = WLog_GetLogLayout(root); + WLog_Layout_SetPrefixFormat(root, layout, "%mn"); + + WLog_OpenAppender(root); + + logA = WLog_Get(channels[0]); + logB = WLog_Get(channels[1]); + + WLog_SetLogLevel(logA, WLOG_TRACE); + WLog_SetLogLevel(logB, WLOG_TRACE); + + WLog_Print(logA, messages[0].level, messages[0].msg); + WLog_Print(logB, messages[1].level, messages[1].msg); + WLog_Print(logA, messages[2].level, messages[2].msg, 2, "test"); + WLog_Print(logB, messages[3].level, messages[3].msg, 2, "time"); + WLog_Print(logA, messages[4].level, messages[4].msg); + WLog_Print(logB, messages[5].level, messages[5].msg); + WLog_Print(logA, messages[6].level, messages[6].msg); + WLog_Print(logB, messages[7].level, messages[7].msg); + + WLog_CloseAppender(root); + + return success ? 0 : -1; +} diff --git a/winpr/libwinpr/utils/test/lodepng_32bit.bmp b/winpr/libwinpr/utils/test/lodepng_32bit.bmp new file mode 100644 index 0000000..d52d34c Binary files /dev/null and b/winpr/libwinpr/utils/test/lodepng_32bit.bmp differ diff --git a/winpr/libwinpr/utils/test/lodepng_32bit.png b/winpr/libwinpr/utils/test/lodepng_32bit.png new file mode 100644 index 0000000..9c55f28 Binary files /dev/null and b/winpr/libwinpr/utils/test/lodepng_32bit.png differ diff --git a/winpr/libwinpr/utils/test/rgb.16.bmp b/winpr/libwinpr/utils/test/rgb.16.bmp new file mode 100644 index 0000000..3e6e1ad Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.16.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.16.nocolor.bmp b/winpr/libwinpr/utils/test/rgb.16.nocolor.bmp new file mode 100644 index 0000000..70875dd Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.16.nocolor.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.16a.bmp b/winpr/libwinpr/utils/test/rgb.16a.bmp new file mode 100644 index 0000000..4a7b506 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.16a.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.16a.nocolor.bmp b/winpr/libwinpr/utils/test/rgb.16a.nocolor.bmp new file mode 100644 index 0000000..ae739dd Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.16a.nocolor.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.16x.bmp b/winpr/libwinpr/utils/test/rgb.16x.bmp new file mode 100644 index 0000000..5fb5cd8 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.16x.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.16x.nocolor.bmp b/winpr/libwinpr/utils/test/rgb.16x.nocolor.bmp new file mode 100644 index 0000000..7e04ec3 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.16x.nocolor.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.24.bmp b/winpr/libwinpr/utils/test/rgb.24.bmp new file mode 100644 index 0000000..7719f9d Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.24.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.24.nocolor.bmp b/winpr/libwinpr/utils/test/rgb.24.nocolor.bmp new file mode 100644 index 0000000..ffc30ed Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.24.nocolor.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.32.bmp b/winpr/libwinpr/utils/test/rgb.32.bmp new file mode 100644 index 0000000..5d9c1df Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.32.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.32.nocolor.bmp b/winpr/libwinpr/utils/test/rgb.32.nocolor.bmp new file mode 100644 index 0000000..5217757 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.32.nocolor.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.32x.bmp b/winpr/libwinpr/utils/test/rgb.32x.bmp new file mode 100644 index 0000000..41ae40c Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.32x.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.32x.nocolor.bmp b/winpr/libwinpr/utils/test/rgb.32x.nocolor.bmp new file mode 100644 index 0000000..10abb96 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.32x.nocolor.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.bmp b/winpr/libwinpr/utils/test/rgb.bmp new file mode 100644 index 0000000..3e7e5bb Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.bmp differ diff --git a/winpr/libwinpr/utils/test/rgb.jpg b/winpr/libwinpr/utils/test/rgb.jpg new file mode 100644 index 0000000..89c5a31 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.jpg differ diff --git a/winpr/libwinpr/utils/test/rgb.png b/winpr/libwinpr/utils/test/rgb.png new file mode 100644 index 0000000..70877d4 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.png differ diff --git a/winpr/libwinpr/utils/test/rgb.webp b/winpr/libwinpr/utils/test/rgb.webp new file mode 100644 index 0000000..26e0c05 Binary files /dev/null and b/winpr/libwinpr/utils/test/rgb.webp differ -- cgit v1.2.3