Milestone 5: deliver embedded RDP sessions and lifecycle hardening
55
third_party/FreeRDP/winpr/libwinpr/utils/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
set(MODULE_NAME "TestWinPRUtils")
|
||||
set(MODULE_PREFIX "TEST_WINPR_UTILS")
|
||||
|
||||
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
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_compile_definitions(TEST_SOURCE_PATH="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
add_compile_definitions(TEST_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")
|
||||
|
||||
add_executable(img-cnv img-cnv.c)
|
||||
target_link_libraries(img-cnv winpr)
|
||||
347
third_party/FreeRDP/winpr/libwinpr/utils/test/TestASN1.c
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
#include <winpr/asn1.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
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 positiveIntegerContent[] = { 0x02, 0x02, 0x00, 0xff };
|
||||
static const BYTE negativeIntegerContent[] = { 0x02, 0x01, 0xff };
|
||||
|
||||
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_init();
|
||||
WinPrAsn1Decoder seqDecoder = WinPrAsn1Decoder_init();
|
||||
wStream staticS = WINPR_C_ARRAY_INIT;
|
||||
WinPrAsn1_BOOL boolV = 0;
|
||||
WinPrAsn1_INTEGER integerV = 0;
|
||||
WinPrAsn1_OID oidV = WINPR_C_ARRAY_INIT;
|
||||
WinPrAsn1_IA5STRING ia5stringV = nullptr;
|
||||
WinPrAsn1_UTCTIME utctimeV = WINPR_C_ARRAY_INIT;
|
||||
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, positiveIntegerContent, sizeof(positiveIntegerContent));
|
||||
WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
|
||||
if (!WinPrAsn1DecReadInteger(&decoder, &integerV) && integerV != 0xff)
|
||||
return -1;
|
||||
|
||||
Stream_StaticConstInit(&staticS, negativeIntegerContent, sizeof(negativeIntegerContent));
|
||||
WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
|
||||
if (!WinPrAsn1DecReadInteger(&decoder, &integerV) && integerV != -1)
|
||||
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) != 0))
|
||||
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") != 0))
|
||||
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 = nullptr;
|
||||
size_t expectedOuputSz = 0;
|
||||
int retCode = 100;
|
||||
WinPrAsn1_UTCTIME utcTime;
|
||||
WinPrAsn1_IA5STRING ia5string = nullptr;
|
||||
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(nullptr, 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);
|
||||
}
|
||||
84
third_party/FreeRDP/winpr/libwinpr/utils/test/TestArrayList.c
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
int TestArrayList(int argc, char* argv[])
|
||||
{
|
||||
int res = -1;
|
||||
SSIZE_T rc = 0;
|
||||
size_t val = 0;
|
||||
const size_t elemsToInsert = 10;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
wArrayList* arrayList = ArrayList_New(TRUE);
|
||||
if (!arrayList)
|
||||
return -1;
|
||||
|
||||
for (size_t index = 0; index < elemsToInsert; index++)
|
||||
{
|
||||
if (!ArrayList_Append(arrayList, (void*)index))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
size_t count = ArrayList_Count(arrayList);
|
||||
|
||||
printf("ArrayList count: %" PRIuz "\n", count);
|
||||
|
||||
SSIZE_T index = ArrayList_IndexOf(arrayList, (void*)(size_t)6, -1, -1);
|
||||
|
||||
printf("ArrayList index: %" PRIdz "\n", index);
|
||||
|
||||
if (index != 6)
|
||||
goto fail;
|
||||
|
||||
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)
|
||||
goto fail;
|
||||
|
||||
ArrayList_Remove(arrayList, (void*)(size_t)100);
|
||||
|
||||
rc = ArrayList_IndexOf(arrayList, (void*)(size_t)6, -1, -1);
|
||||
printf("ArrayList index: %" PRIdz "\n", rc);
|
||||
|
||||
if (rc != 6)
|
||||
goto fail;
|
||||
|
||||
for (size_t index = 0; index < elemsToInsert; index++)
|
||||
{
|
||||
val = (size_t)ArrayList_GetItem(arrayList, 0);
|
||||
if (!ArrayList_RemoveAt(arrayList, 0))
|
||||
goto fail;
|
||||
|
||||
if (val != index)
|
||||
{
|
||||
printf("ArrayList: shifted %" PRIdz " entries, expected value %" PRIdz ", got %" PRIdz
|
||||
"\n",
|
||||
index, index, val);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ArrayList_IndexOf(arrayList, (void*)elemsToInsert, -1, -1);
|
||||
printf("ArrayList index: %" PRIdz "\n", rc);
|
||||
if (rc != -1)
|
||||
goto fail;
|
||||
|
||||
count = ArrayList_Count(arrayList);
|
||||
printf("ArrayList count: %" PRIuz "\n", count);
|
||||
if (count != 0)
|
||||
goto fail;
|
||||
|
||||
ArrayList_Clear(arrayList);
|
||||
res = 0;
|
||||
fail:
|
||||
ArrayList_Free(arrayList);
|
||||
|
||||
return res;
|
||||
}
|
||||
34
third_party/FreeRDP/winpr/libwinpr/utils/test/TestBacktrace.c
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <winpr/debug.h>
|
||||
|
||||
int TestBacktrace(int argc, char* argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
size_t used = 0;
|
||||
char** msg = nullptr;
|
||||
void* stack = winpr_backtrace(20);
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
if (!stack)
|
||||
{
|
||||
(void)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((void*)msg);
|
||||
return rc;
|
||||
}
|
||||
86
third_party/FreeRDP/winpr/libwinpr/utils/test/TestBitStream.c
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
static void BitStrGen(void)
|
||||
{
|
||||
char str[64] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
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 = nullptr;
|
||||
BYTE buffer[1024] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
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;
|
||||
}
|
||||
68
third_party/FreeRDP/winpr/libwinpr/utils/test/TestBufferPool.c
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
int TestBufferPool(int argc, char* argv[])
|
||||
{
|
||||
DWORD PoolSize = 0;
|
||||
SSIZE_T BufferSize = 0;
|
||||
wBufferPool* pool = nullptr;
|
||||
BYTE* Buffers[10] = WINPR_C_ARRAY_INIT;
|
||||
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: %" PRIdz " Expected: %" PRIu32 "\n",
|
||||
BufferSize, DefaultSize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BufferSize = BufferPool_GetBufferSize(pool, Buffers[1]);
|
||||
|
||||
if (BufferSize != DefaultSize)
|
||||
{
|
||||
printf("BufferPool_GetBufferSize failure: Actual: %" PRIdz " Expected: %" PRIu32 "\n",
|
||||
BufferSize, DefaultSize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BufferSize = BufferPool_GetBufferSize(pool, Buffers[2]);
|
||||
|
||||
if (BufferSize != 2048)
|
||||
{
|
||||
printf("BufferPool_GetBufferSize failure: Actual: %" PRIdz " 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;
|
||||
}
|
||||
379
third_party/FreeRDP/winpr/libwinpr/utils/test/TestCmdLine.c
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
#include <errno.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <winpr/strlst.h>
|
||||
|
||||
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:",
|
||||
nullptr };
|
||||
|
||||
static const char testListAppName[] = "test app name";
|
||||
static const char* testListArgs[] = {
|
||||
"g:some.gateway.server,u:some\\\"user,p:some\\\"password,d:some\\\"domain,type:auto",
|
||||
"a,b,c,d",
|
||||
"a:,\"b:xxx, yyy\",c",
|
||||
"a:,,,b",
|
||||
"a:,\",b",
|
||||
"\"a,b,c,d d d,fff\"",
|
||||
"",
|
||||
nullptr,
|
||||
"'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* testListArgs12[] = { testListAppName, "g:some.gateway.server",
|
||||
"u:some\\\"user", "p:some\\\"password",
|
||||
"d:some\\\"domain", "type:auto" };
|
||||
|
||||
static const char** testListArgsResult[] = {
|
||||
testListArgs12,
|
||||
testListArgs1,
|
||||
testListArgs2,
|
||||
nullptr /* testListArgs3 */,
|
||||
nullptr /* testListArgs4 */,
|
||||
testListArgs5,
|
||||
testListArgs6,
|
||||
testListArgs7,
|
||||
testListArgs8,
|
||||
testListArgs9,
|
||||
nullptr /* testListArgs10 */,
|
||||
nullptr /* testListArgs11 */
|
||||
};
|
||||
static const size_t testListArgsCount[] = {
|
||||
ARRAYSIZE(testListArgs12), 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 == nullptr);
|
||||
}
|
||||
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++)
|
||||
{
|
||||
union
|
||||
{
|
||||
char* p;
|
||||
char** pp;
|
||||
const char** ppc;
|
||||
} ptr;
|
||||
const char* list = testListArgs[x];
|
||||
size_t count = 42;
|
||||
ptr.pp = CommandLineParseCommaSeparatedValuesEx(testListAppName, list, &count);
|
||||
BOOL valid = checkResult(x, ptr.pp, count);
|
||||
free(ptr.p);
|
||||
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 = nullptr;
|
||||
int testArgc = 0;
|
||||
char** command_line = nullptr;
|
||||
COMMAND_LINE_ARGUMENT_A args[] = {
|
||||
{ "v", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"destination server" },
|
||||
{ "port", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"server port" },
|
||||
{ "w", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr, "width" },
|
||||
{ "h", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr, "height" },
|
||||
{ "f", COMMAND_LINE_VALUE_FLAG, nullptr, nullptr, nullptr, -1, nullptr, "fullscreen" },
|
||||
{ "bpp", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"session bpp (color depth)" },
|
||||
{ "admin", COMMAND_LINE_VALUE_FLAG, nullptr, nullptr, nullptr, -1, "console",
|
||||
"admin (or console) session" },
|
||||
{ "multimon", COMMAND_LINE_VALUE_FLAG, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"multi-monitor" },
|
||||
{ "a", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, "addin", "addin" },
|
||||
{ "u", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr, "username" },
|
||||
{ "p", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr, "password" },
|
||||
{ "d", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr, "domain" },
|
||||
{ "z", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueFalse, nullptr, -1, nullptr,
|
||||
"compression" },
|
||||
{ "audio", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"audio output mode" },
|
||||
{ "mic", COMMAND_LINE_VALUE_FLAG, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"audio input (microphone)" },
|
||||
{ "fonts", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueFalse, nullptr, -1, nullptr,
|
||||
"smooth fonts (cleartype)" },
|
||||
{ "aero", COMMAND_LINE_VALUE_BOOL, nullptr, nullptr, BoolValueFalse, -1, nullptr,
|
||||
"desktop composition" },
|
||||
{ "window-drag", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueFalse, nullptr, -1, nullptr,
|
||||
"full window drag" },
|
||||
{ "menu-anims", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueFalse, nullptr, -1, nullptr,
|
||||
"menu animations" },
|
||||
{ "themes", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueTrue, nullptr, -1, nullptr,
|
||||
"themes" },
|
||||
{ "wallpaper", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueTrue, nullptr, -1, nullptr,
|
||||
"wallpaper" },
|
||||
{ "codec", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr, "codec" },
|
||||
{ "nego", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueTrue, nullptr, -1, nullptr,
|
||||
"protocol security negotiation" },
|
||||
{ "sec", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"force specific protocol security" },
|
||||
#if defined(WITH_FREERDP_DEPRECATED)
|
||||
{ "sec-rdp", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueTrue, nullptr, -1, nullptr,
|
||||
"rdp protocol security" },
|
||||
{ "sec-tls", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueTrue, nullptr, -1, nullptr,
|
||||
"tls protocol security" },
|
||||
{ "sec-nla", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueTrue, nullptr, -1, nullptr,
|
||||
"nla protocol security" },
|
||||
{ "sec-ext", COMMAND_LINE_VALUE_BOOL, nullptr, BoolValueFalse, nullptr, -1, nullptr,
|
||||
"nla extended protocol security" },
|
||||
{ "cert-name", COMMAND_LINE_VALUE_REQUIRED, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"certificate name" },
|
||||
{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, nullptr, nullptr, nullptr, -1, nullptr,
|
||||
"ignore certificate" },
|
||||
#endif
|
||||
{ "valuelist", COMMAND_LINE_VALUE_REQUIRED, "<val1>,<val2>", nullptr, nullptr, -1, nullptr,
|
||||
"List of comma separated values." },
|
||||
{ "valuelist-empty", COMMAND_LINE_VALUE_REQUIRED, "<val1>,<val2>", nullptr, nullptr, -1,
|
||||
nullptr,
|
||||
"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, nullptr, nullptr,
|
||||
nullptr, -1, nullptr, "print version" },
|
||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, nullptr, nullptr, nullptr, -1,
|
||||
"?", "print help" },
|
||||
{ nullptr, 0, nullptr, nullptr, nullptr, -1, nullptr, nullptr }
|
||||
};
|
||||
|
||||
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, nullptr, nullptr, nullptr);
|
||||
|
||||
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, nullptr, 0);
|
||||
|
||||
if (errno != 0)
|
||||
goto out;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "h")
|
||||
{
|
||||
height = strtol(arg->Value, nullptr, 0);
|
||||
|
||||
if (errno != 0)
|
||||
goto out;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "valuelist")
|
||||
{
|
||||
size_t count = 0;
|
||||
char** p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count);
|
||||
free((void*)p);
|
||||
|
||||
if (!p || count != 3)
|
||||
{
|
||||
printf("CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz
|
||||
"!=3)\n",
|
||||
count);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
CommandLineSwitchCase(arg, "valuelist-empty")
|
||||
{
|
||||
size_t count = 0;
|
||||
char** p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count);
|
||||
free((void*)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)) != nullptr);
|
||||
|
||||
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;
|
||||
}
|
||||
446
third_party/FreeRDP/winpr/libwinpr/utils/test/TestHashTable.c
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
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 = nullptr;
|
||||
wHashTable* table = nullptr;
|
||||
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 = nullptr;
|
||||
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;
|
||||
size_t strlenCounter;
|
||||
size_t 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++;
|
||||
|
||||
return (d->foreachCalls != 2);
|
||||
}
|
||||
|
||||
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 = nullptr;
|
||||
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;
|
||||
}
|
||||
232
third_party/FreeRDP/winpr/libwinpr/utils/test/TestImage.c
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
#include <stdio.h>
|
||||
#include <winpr/string.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/image.h>
|
||||
|
||||
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] = WINPR_C_ARRAY_INIT;
|
||||
(void)_snprintf(path, sizeof(path), "%s.%s", name, winpr_image_format_extension(format));
|
||||
const int cmpSize = winpr_image_read(cmp, path);
|
||||
if (cmpSize <= 0)
|
||||
{
|
||||
(void)fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = test_image_equal(bmp, cmp);
|
||||
if (!rc)
|
||||
(void)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] = WINPR_C_ARRAY_INIT;
|
||||
(void)_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)
|
||||
{
|
||||
(void)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] = WINPR_C_ARRAY_INIT;
|
||||
char dpath[MAX_PATH] = WINPR_C_ARRAY_INIT;
|
||||
char bpath1[MAX_PATH] = WINPR_C_ARRAY_INIT;
|
||||
char bpath2[MAX_PATH] = WINPR_C_ARRAY_INIT;
|
||||
(void)_snprintf(spath, sizeof(spath), "%s.%s", tname, winpr_image_format_extension(format));
|
||||
(void)_snprintf(dpath, sizeof(dpath), "%s.%s", tdst, winpr_image_format_extension(format));
|
||||
(void)_snprintf(bpath1, sizeof(bpath1), "%s.src.%s", dpath,
|
||||
winpr_image_format_extension(WINPR_IMAGE_BITMAP));
|
||||
(void)_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)
|
||||
{
|
||||
(void)fprintf(stderr, "[%s] winpr_image_read failed for %s", __func__, spath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
const int bmpWSize = winpr_image_write(bmp1, dpath);
|
||||
if (bmpWSize <= 0)
|
||||
{
|
||||
(void)fprintf(stderr, "[%s] winpr_image_write failed for %s", __func__, dpath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
const int bmp2RSize = winpr_image_read(bmp2, dpath);
|
||||
if (bmp2RSize <= 0)
|
||||
{
|
||||
(void)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)
|
||||
{
|
||||
(void)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)
|
||||
{
|
||||
(void)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)
|
||||
{
|
||||
(void)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))
|
||||
{
|
||||
(void)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)
|
||||
(void)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);
|
||||
|
||||
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;
|
||||
}
|
||||
160
third_party/FreeRDP/winpr/libwinpr/utils/test/TestIni.c
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/ini.h>
|
||||
|
||||
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 = nullptr;
|
||||
const char* sValue = nullptr;
|
||||
char** keyNames = nullptr;
|
||||
char** sectionNames = nullptr;
|
||||
|
||||
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((void*)sectionNames);
|
||||
sectionNames = IniFile_GetSectionNames(ini, &nSections);
|
||||
if (!sectionNames && (nSections > 0))
|
||||
goto fail;
|
||||
|
||||
for (size_t i = 0; i < nSections; i++)
|
||||
{
|
||||
free((void*)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((void*)sectionNames);
|
||||
sectionNames = IniFile_GetSectionNames(ini, &nSections);
|
||||
if (!sectionNames && (nSections > 0))
|
||||
goto fail;
|
||||
|
||||
for (size_t i = 0; i < nSections; i++)
|
||||
{
|
||||
free((void*)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((void*)keyNames);
|
||||
free((void*)sectionNames);
|
||||
IniFile_Free(ini);
|
||||
return rc;
|
||||
}
|
||||
135
third_party/FreeRDP/winpr/libwinpr/utils/test/TestLinkedList.c
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
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;
|
||||
}
|
||||
178
third_party/FreeRDP/winpr/libwinpr/utils/test/TestListDictionary.c
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
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 = nullptr;
|
||||
wListDictionary* list = nullptr;
|
||||
|
||||
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) != 0) || (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) != 0) || (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;
|
||||
}
|
||||
105
third_party/FreeRDP/winpr/libwinpr/utils/test/TestMessagePipe.c
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
static DWORD WINAPI message_echo_pipe_client_thread(LPVOID arg)
|
||||
{
|
||||
int index = 0;
|
||||
wMessagePipe* pipe = (wMessagePipe*)arg;
|
||||
|
||||
while (index < 100)
|
||||
{
|
||||
wMessage message = WINPR_C_ARRAY_INIT;
|
||||
int count = -1;
|
||||
|
||||
if (!MessageQueue_Post(pipe->In, nullptr, 0, (void*)(size_t)index, nullptr))
|
||||
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 = WINPR_C_ARRAY_INIT;
|
||||
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 = nullptr;
|
||||
HANDLE ServerThread = nullptr;
|
||||
wMessagePipe* EchoPipe = nullptr;
|
||||
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(nullptr, 0, message_echo_pipe_client_thread, (void*)EchoPipe,
|
||||
0, nullptr)))
|
||||
{
|
||||
printf("failed to create client thread\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(ServerThread = CreateThread(nullptr, 0, message_echo_pipe_server_thread, (void*)EchoPipe,
|
||||
0, nullptr)))
|
||||
{
|
||||
printf("failed to create server thread\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
(void)WaitForSingleObject(ClientThread, INFINITE);
|
||||
(void)WaitForSingleObject(ServerThread, INFINITE);
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (EchoPipe)
|
||||
MessagePipe_Free(EchoPipe);
|
||||
if (ClientThread)
|
||||
(void)CloseHandle(ClientThread);
|
||||
if (ServerThread)
|
||||
(void)CloseHandle(ServerThread);
|
||||
|
||||
return ret;
|
||||
}
|
||||
192
third_party/FreeRDP/winpr/libwinpr/utils/test/TestMessageQueue.c
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
static DWORD WINAPI message_queue_consumer_thread(LPVOID arg)
|
||||
{
|
||||
wMessage message = WINPR_C_ARRAY_INIT;
|
||||
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;
|
||||
}
|
||||
|
||||
static bool wrap_test(bool (*fkt)(wMessageQueue* queue))
|
||||
{
|
||||
wMessageQueue* queue = MessageQueue_New(nullptr);
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
WINPR_ASSERT(fkt);
|
||||
const bool rc = fkt(queue);
|
||||
MessageQueue_Free(queue);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool check(const wMessage* message, size_t pos)
|
||||
{
|
||||
if (!message)
|
||||
return false;
|
||||
if (message->context != (void*)13)
|
||||
return false;
|
||||
if (message->id != pos)
|
||||
return false;
|
||||
if (message->wParam != (void*)23)
|
||||
return false;
|
||||
if (message->lParam != (void*)42)
|
||||
return false;
|
||||
if (message->Free != nullptr)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool append(wMessageQueue* queue, size_t pos)
|
||||
{
|
||||
const wMessage message = { .context = (void*)13,
|
||||
.id = WINPR_ASSERTING_INT_CAST(DWORD, pos),
|
||||
.wParam = (void*)23,
|
||||
.lParam = (void*)42,
|
||||
.Free = nullptr };
|
||||
|
||||
return MessageQueue_Dispatch(queue, &message);
|
||||
}
|
||||
|
||||
static bool fill_capcity(wMessageQueue* queue, size_t* pos)
|
||||
{
|
||||
WINPR_ASSERT(pos);
|
||||
|
||||
size_t cpos = *pos;
|
||||
const size_t capacity = MessageQueue_Capacity(queue);
|
||||
while (MessageQueue_Size(queue) < capacity)
|
||||
{
|
||||
if (!append(queue, cpos++))
|
||||
return false;
|
||||
}
|
||||
*pos = cpos;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool drain(wMessageQueue* queue, size_t expect)
|
||||
{
|
||||
wMessage message = WINPR_C_ARRAY_INIT;
|
||||
if (MessageQueue_Get(queue, &message) < 0)
|
||||
return false;
|
||||
if (!check(&message, expect))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool drain_capcity(wMessageQueue* queue, size_t remain, size_t* pos)
|
||||
{
|
||||
WINPR_ASSERT(pos);
|
||||
|
||||
size_t cpos = *pos;
|
||||
while (MessageQueue_Size(queue) > remain)
|
||||
{
|
||||
if (!drain(queue, cpos++))
|
||||
return false;
|
||||
}
|
||||
*pos = cpos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_growth_move(wMessageQueue* queue, bool big)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
|
||||
const size_t cap = MessageQueue_Capacity(queue);
|
||||
if (cap < 4)
|
||||
return false;
|
||||
|
||||
size_t wpos = 0;
|
||||
size_t rpos = 0;
|
||||
if (!fill_capcity(queue, &wpos))
|
||||
return false;
|
||||
|
||||
if (big)
|
||||
{
|
||||
if (!append(queue, wpos++))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!drain_capcity(queue, 3, &rpos))
|
||||
return false;
|
||||
|
||||
if (!fill_capcity(queue, &wpos))
|
||||
return false;
|
||||
|
||||
if (!append(queue, wpos++))
|
||||
return false;
|
||||
|
||||
return drain_capcity(queue, 0, &rpos);
|
||||
}
|
||||
|
||||
static bool test_growth_big_move(wMessageQueue* queue)
|
||||
{
|
||||
return test_growth_move(queue, true);
|
||||
}
|
||||
|
||||
static bool test_growth_small_move(wMessageQueue* queue)
|
||||
{
|
||||
return test_growth_move(queue, false);
|
||||
}
|
||||
|
||||
static bool test_operation_run(wMessageQueue* queue, HANDLE thread)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
WINPR_ASSERT(thread);
|
||||
|
||||
if (!MessageQueue_Post(queue, nullptr, 123, nullptr, nullptr))
|
||||
return false;
|
||||
|
||||
if (!MessageQueue_Post(queue, nullptr, 456, nullptr, nullptr))
|
||||
return false;
|
||||
|
||||
if (!MessageQueue_Post(queue, nullptr, 789, nullptr, nullptr))
|
||||
return false;
|
||||
|
||||
if (!MessageQueue_PostQuit(queue, 0))
|
||||
return false;
|
||||
|
||||
const DWORD status = WaitForSingleObject(thread, INFINITE);
|
||||
return (status == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
static bool test_operation(wMessageQueue* queue)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
|
||||
HANDLE thread = CreateThread(nullptr, 0, message_queue_consumer_thread, queue, 0, nullptr);
|
||||
if (!thread)
|
||||
{
|
||||
printf("failed to create thread\n");
|
||||
return false;
|
||||
}
|
||||
const bool rc = test_operation_run(queue, thread);
|
||||
if (!CloseHandle(thread))
|
||||
return false;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TestMessageQueue(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
|
||||
{
|
||||
if (!wrap_test(test_growth_big_move))
|
||||
return -1;
|
||||
if (!wrap_test(test_growth_small_move))
|
||||
return -2;
|
||||
if (!wrap_test(test_operation))
|
||||
return -3;
|
||||
return 0;
|
||||
}
|
||||
402
third_party/FreeRDP/winpr/libwinpr/utils/test/TestPrint.c
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
/**
|
||||
* 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 // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
|
||||
|
||||
static BOOL test_bin_tohex_string(void)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
{
|
||||
const BYTE binbuffer[33] = WINPR_C_ARRAY_INIT;
|
||||
const char empty[33] = WINPR_C_ARRAY_INIT;
|
||||
char strbuffer[33] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
size_t len = winpr_BinToHexStringBuffer(nullptr, 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), nullptr, 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), nullptr, 0, TRUE);
|
||||
if (len != 0)
|
||||
goto fail;
|
||||
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
|
||||
goto fail;
|
||||
len = winpr_BinToHexStringBuffer(nullptr, sizeof(binbuffer), strbuffer, 0, TRUE);
|
||||
if (len != 0)
|
||||
goto fail;
|
||||
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
|
||||
goto fail;
|
||||
|
||||
len = winpr_BinToHexStringBuffer(binbuffer, 0, nullptr, 0, TRUE);
|
||||
if (len != 0)
|
||||
goto fail;
|
||||
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
|
||||
goto fail;
|
||||
len = winpr_BinToHexStringBuffer(nullptr, 0, nullptr, 0, TRUE);
|
||||
if (len != 0)
|
||||
goto fail;
|
||||
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
|
||||
goto fail;
|
||||
len = winpr_BinToHexStringBuffer(binbuffer, 0, nullptr, 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] = WINPR_C_ARRAY_INIT;
|
||||
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] = WINPR_C_ARRAY_INIT;
|
||||
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 = nullptr;
|
||||
{
|
||||
const BYTE binbuffer[33] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
str = winpr_BinToHexString(nullptr, 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(nullptr, 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 = nullptr;
|
||||
}
|
||||
{
|
||||
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 = nullptr;
|
||||
}
|
||||
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] = WINPR_C_ARRAY_INIT;
|
||||
BYTE buffer[1024] = WINPR_C_ARRAY_INIT;
|
||||
size_t len = winpr_HexStringToBinBuffer(nullptr, 0, nullptr, 0);
|
||||
if (len != 0)
|
||||
goto fail;
|
||||
if (memcmp(buffer, empty, sizeof(buffer)) != 0)
|
||||
goto fail;
|
||||
len = winpr_HexStringToBinBuffer(nullptr, 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), nullptr, 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] = WINPR_C_ARRAY_INIT;
|
||||
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] = WINPR_C_ARRAY_INIT;
|
||||
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] = WINPR_C_ARRAY_INIT;
|
||||
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] = WINPR_C_ARRAY_INIT;
|
||||
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;
|
||||
}
|
||||
75
third_party/FreeRDP/winpr/libwinpr/utils/test/TestPubSub.c
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
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 = nullptr;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
node = PubSub_New(TRUE);
|
||||
if (!node)
|
||||
return -1;
|
||||
|
||||
PubSub_AddEventTypes(node, Node_Events, NODE_EVENT_COUNT);
|
||||
|
||||
if (PubSub_SubscribeMouseMotion(node, MouseMotionEventHandler) < 0)
|
||||
return -1;
|
||||
if (PubSub_SubscribeMouseButton(node, MouseButtonEventHandler) < 0)
|
||||
return -1;
|
||||
|
||||
/* Call Event Handler */
|
||||
{
|
||||
MouseMotionEventArgs e;
|
||||
|
||||
e.x = 64;
|
||||
e.y = 128;
|
||||
|
||||
PubSub_OnMouseMotion(node, nullptr, &e);
|
||||
}
|
||||
|
||||
{
|
||||
MouseButtonEventArgs e;
|
||||
|
||||
e.x = 23;
|
||||
e.y = 56;
|
||||
e.flags = 7;
|
||||
e.button = 1;
|
||||
|
||||
PubSub_OnMouseButton(node, nullptr, &e);
|
||||
}
|
||||
|
||||
PubSub_Free(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
225
third_party/FreeRDP/winpr/libwinpr/utils/test/TestQueue.c
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
static bool wrap_test(bool (*fkt)(wQueue* queue))
|
||||
{
|
||||
wQueue* queue = Queue_New(TRUE, -1, -1);
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
WINPR_ASSERT(fkt);
|
||||
const bool rc = fkt(queue);
|
||||
Queue_Free(queue);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool check(const void* ptr, size_t pos)
|
||||
{
|
||||
if (!ptr)
|
||||
return false;
|
||||
if (ptr != (void*)(pos + 23))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool append(wQueue* queue, size_t pos)
|
||||
{
|
||||
void* ptr = (void*)(pos + 23);
|
||||
return Queue_Enqueue(queue, ptr);
|
||||
}
|
||||
|
||||
static bool fill_capcity(wQueue* queue, size_t* pos)
|
||||
{
|
||||
WINPR_ASSERT(pos);
|
||||
|
||||
size_t cpos = *pos;
|
||||
const size_t capacity = Queue_Capacity(queue);
|
||||
while (Queue_Count(queue) < capacity)
|
||||
{
|
||||
if (!append(queue, cpos++))
|
||||
return false;
|
||||
}
|
||||
*pos = cpos;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool drain(wQueue* queue, size_t expect)
|
||||
{
|
||||
void* ptr = Queue_Dequeue(queue);
|
||||
return check(ptr, expect);
|
||||
}
|
||||
|
||||
static bool drain_capcity(wQueue* queue, size_t remain, size_t* pos)
|
||||
{
|
||||
WINPR_ASSERT(pos);
|
||||
|
||||
size_t cpos = *pos;
|
||||
while (Queue_Count(queue) > remain)
|
||||
{
|
||||
if (!drain(queue, cpos++))
|
||||
return false;
|
||||
}
|
||||
*pos = cpos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_growth_move(wQueue* queue, bool big)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
|
||||
const size_t cap = Queue_Capacity(queue);
|
||||
if (cap < 4)
|
||||
return false;
|
||||
|
||||
size_t wpos = 0;
|
||||
size_t rpos = 0;
|
||||
if (!fill_capcity(queue, &wpos))
|
||||
return false;
|
||||
|
||||
/* Ensure the (base) capacity is larger than the allocation step
|
||||
* so a full copy of tail will not be possible */
|
||||
if (big)
|
||||
{
|
||||
if (!append(queue, wpos++))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!drain_capcity(queue, 3, &rpos))
|
||||
return false;
|
||||
|
||||
if (!fill_capcity(queue, &wpos))
|
||||
return false;
|
||||
|
||||
if (!append(queue, wpos++))
|
||||
return false;
|
||||
|
||||
return drain_capcity(queue, 0, &rpos);
|
||||
}
|
||||
|
||||
static bool test_growth_big_move(wQueue* queue)
|
||||
{
|
||||
return test_growth_move(queue, true);
|
||||
}
|
||||
static bool test_growth_small_move(wQueue* queue)
|
||||
{
|
||||
return test_growth_move(queue, false);
|
||||
}
|
||||
|
||||
static bool check_size(wQueue* queue, size_t expected)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
const size_t count = Queue_Count(queue);
|
||||
printf("queue count: %" PRIuz "\n", count);
|
||||
return (count == expected);
|
||||
}
|
||||
|
||||
static bool enqueue(wQueue* queue, size_t val)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
void* ptr = (void*)(23 + val);
|
||||
return Queue_Enqueue(queue, ptr);
|
||||
}
|
||||
|
||||
static bool dequeue(wQueue* queue, size_t expected)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
const void* pexpect = (void*)(23 + expected);
|
||||
void* ptr = Queue_Dequeue(queue);
|
||||
return (pexpect == ptr);
|
||||
}
|
||||
|
||||
static bool legacy_test(wQueue* queue)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
|
||||
for (size_t index = 1; index <= 10; index++)
|
||||
{
|
||||
if (!enqueue(queue, index))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_size(queue, 10))
|
||||
return false;
|
||||
|
||||
for (size_t index = 1; index <= 10; index++)
|
||||
{
|
||||
if (!dequeue(queue, index))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_size(queue, 0))
|
||||
return false;
|
||||
|
||||
if (!enqueue(queue, 1))
|
||||
return false;
|
||||
if (!enqueue(queue, 2))
|
||||
return false;
|
||||
if (!enqueue(queue, 3))
|
||||
return false;
|
||||
|
||||
if (!check_size(queue, 3))
|
||||
return false;
|
||||
|
||||
if (!dequeue(queue, 1))
|
||||
return false;
|
||||
if (!dequeue(queue, 2))
|
||||
return false;
|
||||
|
||||
if (!check_size(queue, 1))
|
||||
return false;
|
||||
|
||||
if (!enqueue(queue, 4))
|
||||
return false;
|
||||
if (!enqueue(queue, 5))
|
||||
return false;
|
||||
if (!enqueue(queue, 6))
|
||||
return false;
|
||||
|
||||
if (!check_size(queue, 4))
|
||||
return false;
|
||||
|
||||
if (!dequeue(queue, 3))
|
||||
return false;
|
||||
if (!dequeue(queue, 4))
|
||||
return false;
|
||||
if (!dequeue(queue, 5))
|
||||
return false;
|
||||
if (!dequeue(queue, 6))
|
||||
return false;
|
||||
|
||||
if (!check_size(queue, 0))
|
||||
return false;
|
||||
|
||||
Queue_Clear(queue);
|
||||
|
||||
if (!check_size(queue, 0))
|
||||
return false;
|
||||
|
||||
for (size_t x = 0; x < 32; x++)
|
||||
{
|
||||
void* ptr = (void*)(23 + x);
|
||||
if (!Queue_Enqueue(queue, ptr))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_size(queue, 32))
|
||||
return false;
|
||||
|
||||
Queue_Clear(queue);
|
||||
|
||||
return check_size(queue, 0);
|
||||
}
|
||||
|
||||
int TestQueue(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
|
||||
{
|
||||
if (!wrap_test(test_growth_big_move))
|
||||
return -1;
|
||||
if (!wrap_test(test_growth_small_move))
|
||||
return -2;
|
||||
if (!wrap_test(legacy_test))
|
||||
return -3;
|
||||
return 0;
|
||||
}
|
||||
859
third_party/FreeRDP/winpr/libwinpr/utils/test/TestStream.c
vendored
Normal file
@@ -0,0 +1,859 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
static BOOL TestStream_Verify(wStream* s, size_t mincap, size_t len, size_t pos)
|
||||
{
|
||||
if (Stream_Buffer(s) == nullptr)
|
||||
{
|
||||
printf("stream buffer is null\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Stream_ConstPointer(s) == nullptr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* Test creation of a 0-size stream with no buffer */
|
||||
wStream* s = Stream_New(nullptr, 0);
|
||||
|
||||
if (s)
|
||||
return FALSE;
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL TestStream_Static(void)
|
||||
{
|
||||
BYTE buffer[20] = WINPR_C_ARRAY_INIT;
|
||||
wStream staticStream = WINPR_C_ARRAY_INIT;
|
||||
wStream* s = &staticStream;
|
||||
UINT16 v = 0;
|
||||
/* Test creation of a static stream */
|
||||
Stream_StaticInit(s, buffer, sizeof(buffer));
|
||||
Stream_Write_UINT16(s, 0xcab1);
|
||||
Stream_ResetPosition(s);
|
||||
Stream_Read_UINT16(s, v);
|
||||
|
||||
if (v != 0xcab1)
|
||||
return FALSE;
|
||||
|
||||
Stream_ResetPosition(s);
|
||||
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_ResetPosition(s);
|
||||
Stream_Read_UINT16(s, v);
|
||||
|
||||
if (v != 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, v);
|
||||
|
||||
if (v != 2)
|
||||
return FALSE;
|
||||
|
||||
// Intentional warning as the stream is not allocated.
|
||||
// Still, Stream_Free should not release such memory, therefore this statement
|
||||
// is required to test that.
|
||||
WINPR_PRAGMA_DIAG_PUSH
|
||||
WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
|
||||
Stream_Free(s, TRUE);
|
||||
WINPR_PRAGMA_DIAG_POP
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL TestStream_Create(size_t count, BOOL selfAlloc)
|
||||
{
|
||||
size_t len = 0;
|
||||
size_t cap = 0;
|
||||
wStream* s = nullptr;
|
||||
void* buffer = nullptr;
|
||||
|
||||
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 : nullptr, 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, (BYTE)(i % 256), cap);
|
||||
|
||||
if (memcmp(buffer, Stream_Buffer(s), cap) != 0)
|
||||
{
|
||||
printf("%s: buffer memory corruption\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
Stream_Free(s, buffer == nullptr);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
fail:
|
||||
free(buffer);
|
||||
|
||||
if (s)
|
||||
{
|
||||
Stream_Free(s, buffer == nullptr);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TestStream_Extent(UINT32 maxSize)
|
||||
{
|
||||
wStream* s = nullptr;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!(s = Stream_New(nullptr, 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_Get_UINT8_BE Stream_Peek_Get_UINT8
|
||||
#define Stream_Get_UINT8_BE Stream_Get_UINT8
|
||||
#define Stream_Peek_INT8_BE Stream_Peek_INT8
|
||||
#define Stream_Peek_Get_INT8_BE Stream_Peek_Get_INT8
|
||||
#define Stream_Read_INT8_BE Stream_Read_INT8
|
||||
#define Stream_Get_INT8_BE Stream_Get_INT8
|
||||
|
||||
#define TestStream_PeekAndRead(_s, _r, _t) \
|
||||
do \
|
||||
{ \
|
||||
_t _a = 0; \
|
||||
_t _b = 0; \
|
||||
BYTE* _p = Stream_Buffer(_s); \
|
||||
Stream_ResetPosition(_s); \
|
||||
Stream_Peek_##_t(_s, _a); \
|
||||
Stream_Read_##_t(_s, _b); \
|
||||
if (_a != _b) \
|
||||
{ \
|
||||
printf("%s: test1 " #_t "_LE failed\n", __func__); \
|
||||
(_r) = FALSE; \
|
||||
} \
|
||||
Stream_Rewind(_s, sizeof(_t)); \
|
||||
const _t _d = Stream_Peek_Get_##_t(_s); \
|
||||
const _t _c = Stream_Get_##_t(_s); \
|
||||
if (_c != _d) \
|
||||
{ \
|
||||
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_ResetPosition(_s); \
|
||||
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; \
|
||||
} \
|
||||
Stream_Rewind(_s, sizeof(_t)); \
|
||||
const _t _e = Stream_Peek_Get_##_t##_BE(_s); \
|
||||
const _t _f = Stream_Get_##_t##_BE(_s); \
|
||||
if (_e != _f) \
|
||||
{ \
|
||||
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_WriteAndRead(UINT64 value)
|
||||
{
|
||||
union
|
||||
{
|
||||
UINT8 u8;
|
||||
UINT16 u16;
|
||||
UINT32 u32;
|
||||
UINT64 u64;
|
||||
INT8 i8;
|
||||
INT16 i16;
|
||||
INT32 i32;
|
||||
INT64 i64;
|
||||
} val;
|
||||
val.u64 = value;
|
||||
|
||||
wStream* s = Stream_New(nullptr, 1024);
|
||||
if (!s)
|
||||
return FALSE;
|
||||
BOOL rc = FALSE;
|
||||
|
||||
{
|
||||
Stream_Write_UINT8(s, val.u8);
|
||||
Stream_Rewind_UINT8(s);
|
||||
const UINT8 ru8 = Stream_Get_UINT8(s);
|
||||
Stream_Rewind_UINT8(s);
|
||||
if (val.u8 != ru8)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_UINT16(s, val.u16);
|
||||
Stream_Rewind_UINT16(s);
|
||||
const UINT16 ru = Stream_Get_UINT16(s);
|
||||
Stream_Rewind_UINT16(s);
|
||||
if (val.u16 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_UINT16_BE(s, val.u16);
|
||||
Stream_Rewind_UINT16(s);
|
||||
const UINT16 ru = Stream_Get_UINT16_BE(s);
|
||||
Stream_Rewind_UINT16(s);
|
||||
if (val.u16 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_UINT32(s, val.u32);
|
||||
Stream_Rewind_UINT32(s);
|
||||
const UINT32 ru = Stream_Get_UINT32(s);
|
||||
Stream_Rewind_UINT32(s);
|
||||
if (val.u32 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_UINT32_BE(s, val.u32);
|
||||
Stream_Rewind_UINT32(s);
|
||||
const UINT32 ru = Stream_Get_UINT32_BE(s);
|
||||
Stream_Rewind_UINT32(s);
|
||||
if (val.u32 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_UINT64(s, val.u64);
|
||||
Stream_Rewind_UINT64(s);
|
||||
const UINT64 ru = Stream_Get_UINT64(s);
|
||||
Stream_Rewind_UINT64(s);
|
||||
if (val.u64 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_UINT64_BE(s, val.u64);
|
||||
Stream_Rewind_UINT64(s);
|
||||
const UINT64 ru = Stream_Get_UINT64_BE(s);
|
||||
Stream_Rewind_UINT64(s);
|
||||
if (val.u64 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT8(s, val.i8);
|
||||
Stream_Rewind(s, 1);
|
||||
const INT8 ru8 = Stream_Get_INT8(s);
|
||||
Stream_Rewind(s, 1);
|
||||
if (val.i8 != ru8)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT16(s, val.i16);
|
||||
Stream_Rewind(s, 2);
|
||||
const INT16 ru = Stream_Get_INT16(s);
|
||||
Stream_Rewind(s, 2);
|
||||
if (val.i16 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT16_BE(s, val.i16);
|
||||
Stream_Rewind(s, 2);
|
||||
const INT16 ru = Stream_Get_INT16_BE(s);
|
||||
Stream_Rewind(s, 2);
|
||||
if (val.i16 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT32(s, val.i32);
|
||||
Stream_Rewind(s, 4);
|
||||
const INT32 ru = Stream_Get_INT32(s);
|
||||
Stream_Rewind(s, 4);
|
||||
if (val.i32 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT32_BE(s, val.i32);
|
||||
Stream_Rewind(s, 4);
|
||||
const INT32 ru = Stream_Get_INT32_BE(s);
|
||||
Stream_Rewind(s, 4);
|
||||
if (val.i32 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT64(s, val.i64);
|
||||
Stream_Rewind(s, 8);
|
||||
const INT64 ru = Stream_Get_INT64(s);
|
||||
Stream_Rewind(s, 8);
|
||||
if (val.i64 != ru)
|
||||
goto fail;
|
||||
}
|
||||
{
|
||||
Stream_Write_INT64_BE(s, val.i64);
|
||||
Stream_Rewind(s, 8);
|
||||
const INT64 ru = Stream_Get_INT64_BE(s);
|
||||
Stream_Rewind(s, 8);
|
||||
if (val.i64 != ru)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = TRUE;
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL TestStream_Reading(void)
|
||||
{
|
||||
BYTE src[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
wStream* s = nullptr;
|
||||
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(nullptr, 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_ResetPosition(s);
|
||||
|
||||
if (s->pointer != s->buffer)
|
||||
goto out;
|
||||
|
||||
Stream_Write_UINT8(s, 42);
|
||||
|
||||
if (s->pointer != s->buffer + 1)
|
||||
goto out;
|
||||
|
||||
Stream_ResetPosition(s);
|
||||
|
||||
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_ResetPosition(s);
|
||||
|
||||
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_ResetPosition(s);
|
||||
|
||||
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_ResetPosition(s);
|
||||
|
||||
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(nullptr, 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(nullptr, 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(nullptr, sizeof(data));
|
||||
|
||||
if (!s)
|
||||
goto out;
|
||||
|
||||
Stream_Write(s, data, sizeof(data));
|
||||
|
||||
if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0)
|
||||
goto out;
|
||||
|
||||
Stream_ResetPosition(s);
|
||||
|
||||
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_ResetPosition(s);
|
||||
|
||||
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(nullptr, sizeof(data));
|
||||
|
||||
if (!s)
|
||||
goto out;
|
||||
|
||||
Stream_Write(s, data, sizeof(data));
|
||||
|
||||
if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0)
|
||||
goto out;
|
||||
|
||||
Stream_ResetPosition(s);
|
||||
|
||||
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_ResetPosition(s);
|
||||
|
||||
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(nullptr, sizeof(data));
|
||||
wStream* d = Stream_New(nullptr, 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_ResetPosition(s);
|
||||
|
||||
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;
|
||||
|
||||
if (!TestStream_WriteAndRead(0x1234567890abcdef))
|
||||
return 13;
|
||||
|
||||
for (size_t x = 0; x < 10; x++)
|
||||
{
|
||||
UINT64 val = 0;
|
||||
if (winpr_RAND(&val, sizeof(val)) < 0)
|
||||
return -1;
|
||||
if (!TestStream_WriteAndRead(val))
|
||||
return 14;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
82
third_party/FreeRDP/winpr/libwinpr/utils/test/TestStreamPool.c
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#define BUFFER_SIZE 16384
|
||||
|
||||
int TestStreamPool(int argc, char* argv[])
|
||||
{
|
||||
wStream* s[5] = WINPR_C_ARRAY_INIT;
|
||||
char buffer[8192] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
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)));
|
||||
|
||||
Stream_Release(s[2]);
|
||||
Stream_Release(s[3]);
|
||||
Stream_Release(s[4]);
|
||||
|
||||
StreamPool_Free(pool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
47
third_party/FreeRDP/winpr/libwinpr/utils/test/TestVersion.c
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <winpr/version.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
int TestVersion(int argc, char* argv[])
|
||||
{
|
||||
const char* version = nullptr;
|
||||
const char* git = nullptr;
|
||||
const char* build = nullptr;
|
||||
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)) != 0)
|
||||
return -1;
|
||||
|
||||
build = winpr_get_build_config();
|
||||
|
||||
if (!build)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
69
third_party/FreeRDP/winpr/libwinpr/utils/test/TestWLog.c
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
int TestWLog(int argc, char* argv[])
|
||||
{
|
||||
wLog* root = nullptr;
|
||||
wLog* logA = nullptr;
|
||||
wLog* logB = nullptr;
|
||||
wLogLayout* layout = nullptr;
|
||||
wLogAppender* appender = nullptr;
|
||||
char* tmp_path = nullptr;
|
||||
char* wlog_file = nullptr;
|
||||
int result = 1;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
if (!(tmp_path = GetKnownPath(KNOWN_PATH_TEMP)))
|
||||
{
|
||||
(void)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;
|
||||
}
|
||||
128
third_party/FreeRDP/winpr/libwinpr/utils/test/TestWLogCallback.c
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 level;
|
||||
char* msg;
|
||||
char* channel;
|
||||
} test_t;
|
||||
|
||||
static const char* function = nullptr;
|
||||
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__) != 0)
|
||||
rc = FALSE;
|
||||
else if (strcmp(msg->FunctionName, function) != 0)
|
||||
rc = FALSE;
|
||||
else if (strcmp(msg->PrefixString, messages[pos].channel) != 0)
|
||||
rc = FALSE;
|
||||
else if (msg->Level != messages[pos].level)
|
||||
rc = FALSE;
|
||||
else if (strcmp(msg->FormatString, messages[pos].msg) != 0)
|
||||
rc = FALSE;
|
||||
pos++;
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
(void)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)
|
||||
{
|
||||
(void)fprintf(stdout, "%s\n", __func__);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CallbackAppenderImage(const wLogMessage* msg)
|
||||
{
|
||||
(void)fprintf(stdout, "%s\n", __func__);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CallbackAppenderPackage(const wLogMessage* msg)
|
||||
{
|
||||
(void)fprintf(stdout, "%s\n", __func__);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int TestWLogCallback(int argc, char* argv[])
|
||||
{
|
||||
wLog* root = nullptr;
|
||||
wLog* logA = nullptr;
|
||||
wLog* logB = nullptr;
|
||||
wLogLayout* layout = nullptr;
|
||||
wLogAppender* appender = nullptr;
|
||||
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;
|
||||
}
|
||||
105
third_party/FreeRDP/winpr/libwinpr/utils/test/img-cnv.c
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <winpr/image.h>
|
||||
|
||||
static const int formats[] = { WINPR_IMAGE_BITMAP, WINPR_IMAGE_PNG, WINPR_IMAGE_JPEG,
|
||||
WINPR_IMAGE_WEBP };
|
||||
|
||||
static void usage(int argc, char* argv[])
|
||||
{
|
||||
const char* prg = "INVALID";
|
||||
if (argc > 0)
|
||||
prg = argv[0];
|
||||
|
||||
(void)fprintf(stdout, "%s <src> <dst>\n", prg);
|
||||
(void)fprintf(stdout, "\tConvert image <src> to <dst>\n");
|
||||
(void)fprintf(stdout, "\tSupported formats (for this build):\n");
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(formats); x++)
|
||||
{
|
||||
const int format = formats[x];
|
||||
const char* ext = winpr_image_format_extension(format);
|
||||
const char* mime = winpr_image_format_mime(format);
|
||||
const BOOL supported = winpr_image_format_is_supported(format);
|
||||
if (supported)
|
||||
{
|
||||
(void)fprintf(stdout, "\t\t%s [.%s]\n", mime, ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int detect_format(const char* name)
|
||||
{
|
||||
const char* dot = strrchr(name, '.');
|
||||
if (!dot)
|
||||
{
|
||||
(void)fprintf(stderr, "'%s' does not have a file extension\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(formats); x++)
|
||||
{
|
||||
const int format = formats[x];
|
||||
const char* ext = winpr_image_format_extension(format);
|
||||
const char* mime = winpr_image_format_mime(format);
|
||||
const BOOL supported = winpr_image_format_is_supported(format);
|
||||
if (strcmp(&dot[1], ext) == 0)
|
||||
{
|
||||
(void)fprintf(stdout, "'%s' is of format %s [supported:%s]\n", name, mime,
|
||||
supported ? "true" : "false");
|
||||
if (!supported)
|
||||
return -2;
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
(void)fprintf(stderr, "'%s' is a unsupported format\n", name);
|
||||
return -3;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int rc = -4;
|
||||
if (argc != 3)
|
||||
{
|
||||
usage(argc, argv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* src = argv[1];
|
||||
const char* dst = argv[2];
|
||||
|
||||
const int sfmt = detect_format(src);
|
||||
const int dfmt = detect_format(dst);
|
||||
if ((sfmt < 0) || (dfmt < 0))
|
||||
{
|
||||
usage(argc, argv);
|
||||
return -2;
|
||||
}
|
||||
|
||||
wImage* img = winpr_image_new();
|
||||
if (!img)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
const int rrc = winpr_image_read(img, src);
|
||||
if (rrc <= 0)
|
||||
{
|
||||
(void)fprintf(stderr, "Failed to read image '%s': %d\n", src, rrc);
|
||||
goto fail;
|
||||
}
|
||||
const int wrc = winpr_image_write(img, dst);
|
||||
if (wrc <= 0)
|
||||
{
|
||||
(void)fprintf(stderr, "Failed to write image '%s': %d\n", dst, wrc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
(void)fprintf(stdout, "Successfully converted '%s' to '%s'\n", src, dst);
|
||||
rc = 0;
|
||||
fail:
|
||||
winpr_image_free(img, TRUE);
|
||||
return rc;
|
||||
}
|
||||
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/lodepng_32bit.bmp
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/lodepng_32bit.png
vendored
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.16.bmp
vendored
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.16.nocolor.bmp
vendored
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.16a.bmp
vendored
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.16a.nocolor.bmp
vendored
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.16x.bmp
vendored
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.16x.nocolor.bmp
vendored
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.24.bmp
vendored
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.24.nocolor.bmp
vendored
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.32.bmp
vendored
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.32.nocolor.bmp
vendored
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.32x.bmp
vendored
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.32x.nocolor.bmp
vendored
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.bmp
vendored
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.jpg
vendored
Normal file
|
After Width: | Height: | Size: 274 KiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.png
vendored
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
third_party/FreeRDP/winpr/libwinpr/utils/test/rgb.webp
vendored
Normal file
|
After Width: | Height: | Size: 20 KiB |