1 #include "../conversion/binaryconversion.h" 2 #include "../conversion/stringbuilder.h" 3 #include "../conversion/stringconversion.h" 4 #include "../tests/testutils.h" 8 #include <cppunit/TestFixture.h> 9 #include <cppunit/extensions/HelperMacros.h> 12 #include <initializer_list> 19 using namespace CPPUNIT_NS;
23 static_assert(
toNormalInt(383) == 255,
"toNormalInt()");
24 static_assert(
swapOrder(static_cast<uint16>(0xABCD)) == 0xCDAB,
"swapOrder(uint16)");
25 static_assert(
swapOrder(static_cast<uint32>(0xABCDEF12)) == 0x12EFCDAB,
"swapOrder(uint32)");
26 static_assert(
swapOrder(static_cast<uint64>(0xABCDEF1234567890)) == 0x9078563412EFCDAB,
"swapOrder(uint64)");
33 CPPUNIT_TEST(testConversionException);
34 CPPUNIT_TEST(testEndianness);
35 CPPUNIT_TEST(testBinaryConversions);
36 CPPUNIT_TEST(testSwapOrderFunctions);
37 CPPUNIT_TEST(testStringEncodingConversions);
38 CPPUNIT_TEST(testStringConversions);
39 CPPUNIT_TEST(testStringBuilder);
40 CPPUNIT_TEST_SUITE_END();
52 void testConversionException();
53 void testEndianness();
54 void testBinaryConversions();
55 void testSwapOrderFunctions();
56 void testStringEncodingConversions();
57 void testStringConversions();
58 void testStringBuilder();
61 template <
typename intType>
62 void testConversion(
const char *message,
function<
void(intType,
char *)> vice,
function<intType(
const char *)> verca, intType
min, intType
max);
65 random_device m_randomDevice;
66 mt19937 m_randomEngine;
73 , m_randomEngine(m_randomDevice())
90 } test = { 0x01020304 };
91 #if defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN) 93 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN ==
true);
94 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN ==
false);
96 CPPUNIT_ASSERT_MESSAGE(
"Byte order assumption (big-endian) is wrong", test.characters[0] == 0x01);
97 #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN) 99 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN ==
false);
100 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN ==
true);
102 CPPUNIT_ASSERT_MESSAGE(
"Byte order assumption (little-endian) is wrong", test.characters[0] == 0x04);
104 CPPUNIT_FAIL(
"There is not valid byte order assumption");
108 template <
typename intType>
109 void ConversionTests::testConversion(
110 const char *message,
function<
void(intType,
char *)> vice,
function<intType(
const char *)> versa, intType
min, intType
max)
112 const intType
random = uniform_int_distribution<intType>(
min,
max)(m_randomEngine);
114 msg << message <<
'(' << hex <<
'0' <<
'x' <<
random <<
')';
116 CPPUNIT_ASSERT_MESSAGE(msg.str(), versa(m_buff) ==
random);
119 #define TEST_TYPE(endianness, function) decltype(endianness::function(m_buff)) 121 #define TEST_CONVERSION(function, endianness) \ 122 testConversion<TEST_TYPE(endianness, function)>("testing " #function, \ 123 static_cast<void (*)(TEST_TYPE(endianness, function), char *)>(&endianness::getBytes), endianness::function, \ 124 numeric_limits<TEST_TYPE(endianness, function)>::min(), numeric_limits<TEST_TYPE(endianness, function)>::max()) 126 #define TEST_BE_CONVERSION(function) TEST_CONVERSION(function, BE) 128 #define TEST_LE_CONVERSION(function) TEST_CONVERSION(function, LE) 130 #define TEST_CUSTOM_CONVERSION(vice, versa, endianness, min, max) \ 131 testConversion<TEST_TYPE(endianness, versa)>( \ 132 "testing " #versa, static_cast<void (*)(TEST_TYPE(endianness, versa), char *)>(&endianness::vice), endianness::versa, min, max) 143 for (
byte b = 1; b < 100; ++b) {
166 CPPUNIT_ASSERT(
swapOrder(static_cast<uint16>(0x7825)) == 0x2578);
167 CPPUNIT_ASSERT(
swapOrder(static_cast<uint32>(0x12345678)) == 0x78563412);
168 CPPUNIT_ASSERT(
swapOrder(static_cast<uint64>(0x1122334455667788)) == 0x8877665544332211);
174 void assertEqual(
const char *message,
const byte *expectedValues,
size_t expectedSize,
const StringData &actualValues)
177 CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expectedSize, actualValues.second);
179 auto *end = expectedValues + expectedSize;
180 auto *
i = reinterpret_cast<byte *>(actualValues.first.get());
181 for (; expectedValues != end; ++expectedValues, ++
i) {
186 #if CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN == true 187 #define LE_STR_FOR_ENDIANNESS(name) name##LE##String 188 #define BE_STR_FOR_ENDIANNESS(name) name##BE##String 189 #elif CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN == true 190 #define LE_STR_FOR_ENDIANNESS(name) name##BE##String 191 #define BE_STR_FOR_ENDIANNESS(name) name##LE##String 210 const byte simpleString[] = {
'A',
'B',
'C',
'D' };
211 const uint16 simpleUtf16LEString[] = { 0x0041, 0x0042, 0x0043, 0x0044 };
212 const uint16 simpleUtf16BEString[] = { 0x4100, 0x4200, 0x4300, 0x4400 };
214 const byte latin1String[] = {
'A',
'B', 0xD6,
'C',
'D' };
215 const byte utf8String[] = {
'A',
'B', 0xC3, 0x96,
'C',
'D' };
216 const uint16 utf16LEString[] = { 0x0041, 0x0042, 0x00D6, 0x0043, 0x0044 };
217 const uint16 utf16BEString[] = { 0x4100, 0x4200, 0xD600, 0x4300, 0x4400 };
247 CPPUNIT_ASSERT_EQUAL(
"0"s, numberToString<unsigned int>(0));
248 CPPUNIT_ASSERT_EQUAL(
"0"s, numberToString<signed int>(0));
250 uniform_int_distribution<uint64> randomDistUnsigned(0);
251 const string stringMsg(
"string"), wideStringMsg(
"wide string"), bufferMsg(
"buffer");
252 for (
byte b = 1; b < 100; ++b) {
253 auto signedRandom = randomDistSigned(m_randomEngine);
254 auto unsignedRandom = randomDistUnsigned(m_randomEngine);
255 for (
const auto base : initializer_list<byte>{ 2, 8, 10, 16 }) {
256 const auto asString = numberToString<uint64, string>(unsignedRandom, static_cast<string::value_type>(base));
257 const auto asWideString = numberToString<uint64, wstring>(unsignedRandom, base);
258 CPPUNIT_ASSERT_EQUAL_MESSAGE(stringMsg, unsignedRandom, stringToNumber<uint64>(asString, static_cast<string::value_type>(base)));
259 CPPUNIT_ASSERT_EQUAL_MESSAGE(wideStringMsg, unsignedRandom, stringToNumber<uint64>(asWideString, base));
260 CPPUNIT_ASSERT_EQUAL_MESSAGE(bufferMsg, unsignedRandom, bufferToNumber<uint64>(asString.data(), asString.size(), base));
262 for (
const auto base : initializer_list<byte>{ 10 }) {
263 const auto asString = numberToString<int64, string>(signedRandom, static_cast<string::value_type>(base));
264 const auto asWideString = numberToString<int64, wstring>(signedRandom, base);
265 CPPUNIT_ASSERT_EQUAL_MESSAGE(stringMsg, signedRandom, stringToNumber<int64>(asString, static_cast<string::value_type>(base)));
266 CPPUNIT_ASSERT_EQUAL_MESSAGE(wideStringMsg, signedRandom, stringToNumber<int64>(asWideString, base));
267 CPPUNIT_ASSERT_EQUAL_MESSAGE(bufferMsg, signedRandom, bufferToNumber<int64>(asString.data(), asString.size(), base));
272 CPPUNIT_ASSERT_EQUAL(1, stringToNumber<int32>(
"01"));
273 CPPUNIT_ASSERT_EQUAL(1, stringToNumber<int32>(L
"01"s));
274 CPPUNIT_ASSERT_EQUAL(1, stringToNumber<int32>(u
"01"s));
275 CPPUNIT_ASSERT_EQUAL(-23, stringToNumber<int32>(
" - 023"s));
276 CPPUNIT_ASSERT_EQUAL(-23, bufferToNumber<int32>(
" - 023", 6));
277 CPPUNIT_ASSERT_EQUAL(1u, stringToNumber<uint32>(
"01"));
278 CPPUNIT_ASSERT_EQUAL(1u, stringToNumber<uint32>(L
"01"s));
279 CPPUNIT_ASSERT_EQUAL(1u, stringToNumber<uint32>(u
"01"s));
280 CPPUNIT_ASSERT_EQUAL(23u, stringToNumber<uint32>(
" 023"s));
281 CPPUNIT_ASSERT_EQUAL(23u, bufferToNumber<uint32>(
" 023", 5));
282 CPPUNIT_ASSERT_EQUAL(255u, stringToNumber<uint32>(
"fF", 16));
287 CPPUNIT_ASSERT_EQUAL(
"TEST"s, interpretIntegerAsString<uint32>(0x54455354));
290 vector<string> splitTestExpected({
"1",
"2,3" });
291 vector<string> splitTestActual = splitString<vector<string>>(
"1,2,3"s,
","s, EmptyPartsTreat::Keep, 2);
292 CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
293 splitTestActual = splitStringSimple<vector<string>>(
"1,2,3"s,
","s, 2);
294 CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
295 splitTestExpected = {
"1",
"2,3",
"4,,5" };
296 splitTestActual = splitString<vector<string>>(
"1,2,,3,4,,5"s,
","s, EmptyPartsTreat::Merge, 3);
297 CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
298 string splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Keep),
" "s,
false,
"("s,
")"s);
299 CPPUNIT_ASSERT_EQUAL(
"() (a) () (ab) (ABC) (s)"s, splitJoinTest);
300 splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Keep),
" "s,
true,
"("s,
")"s);
301 CPPUNIT_ASSERT_EQUAL(
"(a) (ab) (ABC) (s)"s, splitJoinTest);
302 splitJoinTest =
joinStrings(
splitStringSimple<vector<string>>(
",a,,ab,ABC,s"s,
","s),
" "s,
true,
"("s,
")"s);
303 CPPUNIT_ASSERT_EQUAL(
"(a) (ab) (ABC) (s)"s, splitJoinTest);
304 splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Omit),
" "s,
false,
"("s,
")"s);
305 CPPUNIT_ASSERT_EQUAL(
"(a) (ab) (ABC) (s)"s, splitJoinTest);
306 splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Merge),
" "s,
false,
"("s,
")"s);
307 CPPUNIT_ASSERT_EQUAL(
"(a,ab) (ABC) (s)"s, splitJoinTest);
310 string findReplaceTest(
"findAndReplace()");
311 findAndReplace<string>(findReplaceTest,
"And",
"Or");
312 CPPUNIT_ASSERT_EQUAL(
"findOrReplace()"s, findReplaceTest);
315 CPPUNIT_ASSERT(!startsWith<string>(findReplaceTest,
"findAnd"));
316 CPPUNIT_ASSERT(startsWith<string>(findReplaceTest,
"findOr"));
317 CPPUNIT_ASSERT(!startsWith<string>(findReplaceTest,
"findAnd"s));
318 CPPUNIT_ASSERT(startsWith<string>(findReplaceTest,
"findOr"s));
321 CPPUNIT_ASSERT(containsSubstrings<string>(
"this string contains foo and bar", {
"foo",
"bar" }));
322 CPPUNIT_ASSERT(!containsSubstrings<string>(
"this string contains foo and bar", {
"bar",
"foo" }));
325 string truncateTest(
"foo bar ");
327 CPPUNIT_ASSERT_EQUAL(
"foo"s, truncateTest);
330 uniform_int_distribution<byte> randomDistChar;
331 byte originalBase64Data[4047];
332 for (
byte &c : originalBase64Data) {
333 c = randomDistChar(m_randomEngine);
335 auto encodedBase64Data =
encodeBase64(originalBase64Data,
sizeof(originalBase64Data));
336 auto decodedBase64Data =
decodeBase64(encodedBase64Data.data(), static_cast<uint32>(encodedBase64Data.size()));
337 CPPUNIT_ASSERT(decodedBase64Data.second ==
sizeof(originalBase64Data));
338 for (
unsigned int i = 0;
i <
sizeof(originalBase64Data); ++
i) {
339 CPPUNIT_ASSERT(decodedBase64Data.first[
i] == originalBase64Data[
i]);
342 encodedBase64Data =
encodeBase64(originalBase64Data,
sizeof(originalBase64Data) - 1);
343 CPPUNIT_ASSERT_EQUAL(
'=', encodedBase64Data.at(encodedBase64Data.size() - 1));
344 CPPUNIT_ASSERT_NO_THROW(
decodeBase64(encodedBase64Data.data(), static_cast<uint32>(encodedBase64Data.size())));
345 encodedBase64Data =
encodeBase64(originalBase64Data,
sizeof(originalBase64Data) - 2);
346 CPPUNIT_ASSERT_EQUAL(
'=', encodedBase64Data.at(encodedBase64Data.size() - 1));
347 CPPUNIT_ASSERT_EQUAL(
'=', encodedBase64Data.at(encodedBase64Data.size() - 2));
348 CPPUNIT_ASSERT_NO_THROW(
decodeBase64(encodedBase64Data.data(), static_cast<uint32>(encodedBase64Data.size())));
355 CPPUNIT_ASSERT_EQUAL(
"2.50 KiB (2560 byte)"s,
dataSizeToString((2048ull + 512ull),
true));
356 CPPUNIT_ASSERT_EQUAL(
"2.50 MiB"s,
dataSizeToString((2048ull + 512ull) * 1024ull));
357 CPPUNIT_ASSERT_EQUAL(
"2.50 GiB"s,
dataSizeToString((2048ull + 512ull) * 1024ull * 1024ull));
358 CPPUNIT_ASSERT_EQUAL(
"2.50 TiB"s,
dataSizeToString((2048ull + 512ull) * 1024ull * 1024ull * 1024ull));
361 CPPUNIT_ASSERT_EQUAL(
"128 Mbit/s"s,
bitrateToString(128.0 * 1e3,
false));
362 CPPUNIT_ASSERT_EQUAL(
"128 Gbit/s"s,
bitrateToString(128.0 * 1e6,
false));
377 const tuple<const char *, string, int, const char *> tuple(
"string1",
"string2", 1234,
"string3");
378 CPPUNIT_ASSERT_EQUAL(
string(
"string1string21234string3"),
tupleToString(tuple));
379 CPPUNIT_ASSERT_EQUAL(
string(
"foobarfoo2bar2"),
tupleToString(
string(
"foo") %
"bar" %
string(
"foo2") %
"bar2"));
380 CPPUNIT_ASSERT_EQUAL(
string(
"v2.3.0"),
argsToString(
"v2.", 3,
'.', 0));
383 CPPUNIT_ASSERT_EQUAL_MESSAGE(
384 "result can be passed to any function taking a std::string"s,
"123456789"s,
functionTakingString(
"12" %
string(
"34") %
'5' % 67 +
"89"));
385 constexpr
double velocityExample = 27.0;
386 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"real-word example"s,
"velocity: 27 km/h (7.5 m/s)"s,
388 CPPUNIT_ASSERT_EQUAL_MESSAGE(
389 "regular + operator still works (no problems with ambiguity)"s,
"regular + still works"s,
"regular"s +
" + still works");
CPP_UTILITIES_EXPORT constexpr uint16 toUInt16(const char *value)
Returns a 16-bit unsigned integer converted from two bytes at a specified position in a char array.
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (little-endian).
CPP_UTILITIES_EXPORT constexpr uint32 toUInt24(const char *value)
Returns a 32-bit unsigned integer converted from three bytes at a specified position in a char array.
CPP_UTILITIES_EXPORT std::string encodeBase64(const byte *data, uint32 dataSize)
Encodes the specified data to Base64.
std::pair< std::unique_ptr< char[], StringDataDeleter >, std::size_t > StringData
Type used to return string encoding conversion result.
Container splitStringSimple(const typename Container::value_type &string, const typename Container::value_type &delimiter, int maxParts=-1)
Splits the given string (which might also be a string view) at the specified delimiter.
void testSwapOrderFunctions()
Tests swap order functions.
The ConversionException class is thrown by the various conversion functions of this library when a co...
CPP_UTILITIES_EXPORT constexpr int32 toInt32(const char *value)
Returns a 32-bit signed integer converted from four bytes at a specified position in a char array.
CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (big-endian) string to UTF-8.
void testBinaryConversions()
Tests most important binary conversions.
constexpr StringType argsToString(Args &&... args)
#define TEST_LE_CONVERSION(function)
CPPUNIT_TEST_SUITE_REGISTRATION(ConversionTests)
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar='\0')
Truncates all characters after the first occurrence of the specified terminationChar and the terminat...
void testStringConversions()
Tests miscellaneous string conversions.
StringType numberToString(IntegralType number, typename StringType::value_type base=10)
Converts the given number to its equivalent string representation using the specified base.
CPP_UTILITIES_EXPORT constexpr int16 toInt16(const char *value)
Returns a 16-bit signed integer converted from two bytes at a specified position in a char array.
void testEndianness()
Tests whether macros for endianness are correct.
#define TEST_CUSTOM_CONVERSION(vice, versa, endianness, min, max)
CPP_UTILITIES_EXPORT int random(int lowerbounds, int upperbounds)
Returns a pseudo random number between lowerbounds and upperbounds.
void testConversionException()
#define BE_STR_FOR_ENDIANNESS(name)
Selects right string for big-endian checks.
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (big-endian).
string functionTakingString(const string &str)
constexpr T max(T first, T second)
Returns the greatest of the given items.
CPP_UTILITIES_EXPORT constexpr uint16 swapOrder(uint16 value)
Swaps the byte order of the specified 16-bit unsigned integer.
Contains classes and functions utilizing creating of test applications.
#define TEST_BE_CONVERSION(function)
CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to Latin-1.
CPP_UTILITIES_EXPORT void getBytes24(uint32 value, char *outputbuffer)
Stores the specified 24-bit unsigned integer value at a specified position in a char array.
Contains several functions providing conversions between different data types.
CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (little-endian) string to UTF-8.
CPP_UTILITIES_EXPORT constexpr uint64 toUInt64(const char *value)
Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a char array.
constexpr T min(T first, T second)
Returns the smallest of the given items.
AsHexNumber< T > asHexNumber(const T &value)
Wraps a value to be printed using the hex system in the error case when asserted with cppunit (or sim...
CPP_UTILITIES_EXPORT constexpr int64 toInt64(const char *value)
Returns a 64-bit signed integer converted from eight bytes at a specified position in a char array.
void testStringEncodingConversions()
Tests string encoding conversions.
CPP_UTILITIES_EXPORT constexpr uint32 toSynchsafeInt(uint32 normalInt)
Returns a 32-bit synchsafe integer converted from a normal 32-bit integer.
void assertEqual(const char *message, const byte *expectedValues, size_t expectedSize, const StringData &actualValues)
Internally used for string encoding tests to check results.
Container::value_type joinStrings(const Container &strings, const typename Container::value_type &delimiter=typename Container::value_type(), bool omitEmpty=false, const typename Container::value_type &leftClosure=typename Container::value_type(), const typename Container::value_type &rightClosure=typename Container::value_type())
Joins the given strings using the specified delimiter.
CPP_UTILITIES_EXPORT StringData convertString(const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor=1.0f)
Converts the specified string from one character set to another.
CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified Latin-1 string to UTF-8.
#define LE_STR_FOR_ENDIANNESS(name)
Selects right string for little-endian checks.
StringType tupleToString(const std::tuple< Args... > &tuple)
Concatenates all strings hold by the specified tuple.
CPP_UTILITIES_EXPORT constexpr uint32 toNormalInt(uint32 synchsafeInt)
Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
Container splitString(const typename Container::value_type &string, const typename Container::value_type &delimiter, EmptyPartsTreat emptyPartsRole=EmptyPartsTreat::Keep, int maxParts=-1)
Splits the given string at the specified delimiter.
CPP_UTILITIES_EXPORT std::string dataSizeToString(uint64 sizeInByte, bool includeByte=false)
Converts the specified data size in byte to its equivalent std::string representation.
CPP_UTILITIES_EXPORT std::pair< std::unique_ptr< byte[]>, uint32 > decodeBase64(const char *encodedStr, const uint32 strSize)
Decodes the specified Base64 encoded string.
CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits=false)
Converts the specified bitrate in kbit/s to its equivalent std::string representation.
The ConversionTests class tests classes and methods of the ConversionUtilities namespace.
std::uint16_t uint16
unsigned 16-bit integer
CPP_UTILITIES_EXPORT constexpr uint32 toUInt32(const char *value)
Returns a 32-bit unsigned integer converted from four bytes at a specified position in a char array.