1#include <gtest/gtest.h>
2
3#include <base/system.h>
4
5#include <game/gamecore.h>
6
7TEST(Str, Dist)
8{
9 EXPECT_EQ(str_utf8_dist("aaa", "aaa"), 0);
10 EXPECT_EQ(str_utf8_dist("123", "123"), 0);
11 EXPECT_EQ(str_utf8_dist("", ""), 0);
12 EXPECT_EQ(str_utf8_dist("a", "b"), 1);
13 EXPECT_EQ(str_utf8_dist("", "aaa"), 3);
14 EXPECT_EQ(str_utf8_dist("123", ""), 3);
15 EXPECT_EQ(str_utf8_dist("ä", ""), 1);
16 EXPECT_EQ(str_utf8_dist("Hëllö", "Hello"), 2);
17 // https://en.wikipedia.org/w/index.php?title=Levenshtein_distance&oldid=828480025#Example
18 EXPECT_EQ(str_utf8_dist("kitten", "sitting"), 3);
19 EXPECT_EQ(str_utf8_dist("flaw", "lawn"), 2);
20 EXPECT_EQ(str_utf8_dist("saturday", "sunday"), 3);
21}
22
23TEST(Str, Utf8Isspace)
24{
25 EXPECT_TRUE(str_utf8_isspace(0x200b)); // Zero-width space
26 EXPECT_TRUE(str_utf8_isspace(' '));
27 EXPECT_FALSE(str_utf8_isspace('a'));
28 // Control characters.
29 for(char c = 0; c < 0x20; c++)
30 {
31 EXPECT_TRUE(str_utf8_isspace(c));
32 }
33}
34
35TEST(Str, Utf8SkipWhitespaces)
36{
37 EXPECT_STREQ(str_utf8_skip_whitespaces("abc"), "abc");
38 EXPECT_STREQ(str_utf8_skip_whitespaces("abc "), "abc ");
39 EXPECT_STREQ(str_utf8_skip_whitespaces(" abc"), "abc");
40 EXPECT_STREQ(str_utf8_skip_whitespaces("\xe2\x80\x8b abc"), "abc");
41}
42
43TEST(Str, Utf8TrimRight)
44{
45 char A1[] = "abc";
46 str_utf8_trim_right(param: A1);
47 EXPECT_STREQ(A1, "abc");
48 char A2[] = " abc";
49 str_utf8_trim_right(param: A2);
50 EXPECT_STREQ(A2, " abc");
51 char A3[] = "abc ";
52 str_utf8_trim_right(param: A3);
53 EXPECT_STREQ(A3, "abc");
54 char A4[] = "abc \xe2\x80\x8b";
55 str_utf8_trim_right(param: A4);
56 EXPECT_STREQ(A4, "abc");
57}
58
59TEST(Str, Utf8CompConfusables)
60{
61 EXPECT_TRUE(str_utf8_comp_confusable("abc", "abc") == 0);
62 EXPECT_TRUE(str_utf8_comp_confusable("rn", "m") == 0);
63 EXPECT_TRUE(str_utf8_comp_confusable("m", "rn") == 0);
64 EXPECT_TRUE(str_utf8_comp_confusable("rna", "ma") == 0);
65 EXPECT_TRUE(str_utf8_comp_confusable("ma", "rna") == 0);
66 EXPECT_FALSE(str_utf8_comp_confusable("mA", "rna") == 0);
67 EXPECT_FALSE(str_utf8_comp_confusable("ma", "rnA") == 0);
68 EXPECT_TRUE(str_utf8_comp_confusable("arn", "am") == 0);
69 EXPECT_TRUE(str_utf8_comp_confusable("am", "arn") == 0);
70 EXPECT_FALSE(str_utf8_comp_confusable("Am", "arn") == 0);
71 EXPECT_FALSE(str_utf8_comp_confusable("am", "Arn") == 0);
72 EXPECT_TRUE(str_utf8_comp_confusable("l", "ӏ") == 0); // CYRILLIC SMALL LETTER PALOCHKA
73 EXPECT_TRUE(str_utf8_comp_confusable("i", "¡") == 0); // INVERTED EXCLAMATION MARK
74 EXPECT_FALSE(str_utf8_comp_confusable("o", "x") == 0);
75 EXPECT_TRUE(str_utf8_comp_confusable("aceiou", "ąçęįǫų") == 0);
76}
77
78TEST(Str, Utf8ToSkeleton)
79{
80 int aBuf[32];
81 EXPECT_EQ(str_utf8_to_skeleton("abc", aBuf, 0), 0);
82 EXPECT_EQ(str_utf8_to_skeleton("", aBuf, std::size(aBuf)), 0);
83 EXPECT_EQ(str_utf8_to_skeleton("abc", aBuf, std::size(aBuf)), 3);
84 EXPECT_EQ(aBuf[0], 'a');
85 EXPECT_EQ(aBuf[1], 'b');
86 EXPECT_EQ(aBuf[2], 'c');
87 EXPECT_EQ(str_utf8_to_skeleton("m", aBuf, std::size(aBuf)), 2);
88 EXPECT_EQ(aBuf[0], 'r');
89 EXPECT_EQ(aBuf[1], 'n');
90 EXPECT_EQ(str_utf8_to_skeleton("rn", aBuf, std::size(aBuf)), 2);
91 EXPECT_EQ(aBuf[0], 'r');
92 EXPECT_EQ(aBuf[1], 'n');
93 EXPECT_EQ(str_utf8_to_skeleton("ӏ", aBuf, std::size(aBuf)), 1); // CYRILLIC SMALL LETTER PALOCHKA
94 EXPECT_EQ(aBuf[0], 'i');
95 EXPECT_EQ(str_utf8_to_skeleton("¡", aBuf, std::size(aBuf)), 1); // INVERTED EXCLAMATION MARK
96 EXPECT_EQ(aBuf[0], 'i');
97 EXPECT_EQ(str_utf8_to_skeleton("ąçęįǫų", aBuf, std::size(aBuf)), 6);
98 EXPECT_EQ(aBuf[0], 'a');
99 EXPECT_EQ(aBuf[1], 'c');
100 EXPECT_EQ(aBuf[2], 'e');
101 EXPECT_EQ(aBuf[3], 'i');
102 EXPECT_EQ(aBuf[4], 'o');
103 EXPECT_EQ(aBuf[5], 'u');
104}
105
106TEST(Str, Utf8ToLower)
107{
108 EXPECT_TRUE(str_utf8_tolower('A') == 'a');
109 EXPECT_TRUE(str_utf8_tolower('z') == 'z');
110 EXPECT_TRUE(str_utf8_tolower(192) == 224); // À -> à
111 EXPECT_TRUE(str_utf8_tolower(7882) == 7883); // Ị -> ị
112
113 EXPECT_TRUE(str_utf8_comp_nocase("ÖlÜ", "ölü") == 0);
114 EXPECT_TRUE(str_utf8_comp_nocase("ÜlÖ", "ölü") > 0); // ü > ö
115 EXPECT_TRUE(str_utf8_comp_nocase("ÖlÜ", "ölüa") < 0); // NULL < a
116 EXPECT_TRUE(str_utf8_comp_nocase("ölüa", "ÖlÜ") > 0); // a < NULL
117
118#if(CHAR_MIN < 0)
119 const char a[2] = {CHAR_MIN, 0};
120 const char b[2] = {0, 0};
121 EXPECT_TRUE(str_utf8_comp_nocase(a, b) > 0);
122 EXPECT_TRUE(str_utf8_comp_nocase(b, a) < 0);
123#endif
124
125 EXPECT_TRUE(str_utf8_comp_nocase_num("ÖlÜ", "ölüa", 5) == 0);
126 EXPECT_TRUE(str_utf8_comp_nocase_num("ÖlÜ", "ölüa", 6) != 0);
127 EXPECT_TRUE(str_utf8_comp_nocase_num("a", "z", 0) == 0);
128 EXPECT_TRUE(str_utf8_comp_nocase_num("a", "z", 1) != 0);
129}
130
131TEST(Str, Utf8FindNocase)
132{
133 const char *pStr = "abc";
134 const char *pEnd;
135 EXPECT_EQ(str_utf8_find_nocase(pStr, "a", &pEnd), pStr);
136 EXPECT_EQ(pEnd, pStr + str_length("a"));
137 EXPECT_EQ(str_utf8_find_nocase(pStr, "b", &pEnd), pStr + str_length("a"));
138 EXPECT_EQ(pEnd, pStr + str_length("ab"));
139 EXPECT_EQ(str_utf8_find_nocase(pStr, "c", &pEnd), pStr + str_length("ab"));
140 EXPECT_EQ(pEnd, pStr + str_length("abc"));
141 EXPECT_EQ(str_utf8_find_nocase(pStr, "d", &pEnd), nullptr);
142 EXPECT_EQ(pEnd, nullptr);
143
144 EXPECT_EQ(str_utf8_find_nocase(pStr, "A", &pEnd), pStr);
145 EXPECT_EQ(pEnd, pStr + str_length("a"));
146 EXPECT_EQ(str_utf8_find_nocase(pStr, "B", &pEnd), pStr + str_length("a"));
147 EXPECT_EQ(pEnd, pStr + str_length("ab"));
148 EXPECT_EQ(str_utf8_find_nocase(pStr, "C", &pEnd), pStr + str_length("ab"));
149 EXPECT_EQ(pEnd, pStr + str_length("abc"));
150 EXPECT_EQ(str_utf8_find_nocase(pStr, "D", &pEnd), nullptr);
151 EXPECT_EQ(pEnd, nullptr);
152
153 pStr = "ÄÖÜ";
154 EXPECT_EQ(str_utf8_find_nocase(pStr, "ä", &pEnd), pStr);
155 EXPECT_EQ(pEnd, pStr + str_length("Ä"));
156 EXPECT_EQ(str_utf8_find_nocase(pStr, "ö", &pEnd), pStr + str_length("Ä"));
157 EXPECT_EQ(pEnd, pStr + str_length("ÄÖ"));
158 EXPECT_EQ(str_utf8_find_nocase(pStr, "ü", &pEnd), pStr + str_length("ÄÖ"));
159 EXPECT_EQ(pEnd, pStr + str_length("ÄÖÜ"));
160 EXPECT_EQ(str_utf8_find_nocase(pStr, "z", &pEnd), nullptr);
161 EXPECT_EQ(pEnd, nullptr);
162
163 // Both 'I' and 'İ' map to 'i'
164 pStr = "antimatter";
165 EXPECT_EQ(str_utf8_find_nocase(pStr, "I", &pEnd), pStr + str_length("ant"));
166 EXPECT_EQ(pEnd, pStr + str_length("anti"));
167 EXPECT_EQ(str_utf8_find_nocase(pStr, "İ", &pEnd), pStr + str_length("ant"));
168 EXPECT_EQ(pEnd, pStr + str_length("anti"));
169 pStr = "ANTIMATTER";
170 EXPECT_EQ(str_utf8_find_nocase(pStr, "i", &pEnd), pStr + str_length("ANT"));
171 EXPECT_EQ(pEnd, pStr + str_length("ANTI"));
172 pStr = "ANTİMATTER";
173 EXPECT_EQ(str_utf8_find_nocase(pStr, "i", &pEnd), pStr + str_length("ANT"));
174 EXPECT_EQ(pEnd, pStr + str_length("ANTİ"));
175}
176
177TEST(Str, Utf8FixTruncation)
178{
179 char aaBuf[][32] = {
180 "",
181 "\xff",
182 "abc",
183 "abc\xff",
184 "blub\xffxyz",
185 "привет Наташа\xff",
186 "до свидания\xffОлег",
187 };
188 const char *apExpected[] = {
189 "",
190 "",
191 "abc",
192 "abc",
193 "blub\xffxyz",
194 "привет Наташа",
195 "до свидания\xffОлег",
196 };
197 for(unsigned i = 0; i < std::size(aaBuf); i++)
198 {
199 EXPECT_EQ(str_utf8_fix_truncation(aaBuf[i]), str_length(apExpected[i]));
200 EXPECT_STREQ(aaBuf[i], apExpected[i]);
201 }
202}
203
204TEST(Str, Startswith)
205{
206 EXPECT_TRUE(str_startswith("abcdef", "abc"));
207 EXPECT_FALSE(str_startswith("abc", "abcdef"));
208
209 EXPECT_TRUE(str_startswith("xyz", ""));
210 EXPECT_FALSE(str_startswith("", "xyz"));
211
212 EXPECT_FALSE(str_startswith("house", "home"));
213 EXPECT_FALSE(str_startswith("blackboard", "board"));
214
215 EXPECT_TRUE(str_startswith("поплавать", "по"));
216 EXPECT_FALSE(str_startswith("плавать", "по"));
217
218 static const char ABCDEFG[] = "abcdefg";
219 static const char ABC[] = "abc";
220 EXPECT_EQ(str_startswith(ABCDEFG, ABC) - ABCDEFG, str_length(ABC));
221}
222
223TEST(Str, StartswithNocase)
224{
225 EXPECT_TRUE(str_startswith_nocase("Abcdef", "abc"));
226 EXPECT_FALSE(str_startswith_nocase("aBc", "abcdef"));
227
228 EXPECT_TRUE(str_startswith_nocase("xYz", ""));
229 EXPECT_FALSE(str_startswith_nocase("", "xYz"));
230
231 EXPECT_FALSE(str_startswith_nocase("house", "home"));
232 EXPECT_FALSE(str_startswith_nocase("Blackboard", "board"));
233
234 EXPECT_TRUE(str_startswith_nocase("поплавать", "по"));
235 EXPECT_FALSE(str_startswith_nocase("плавать", "по"));
236
237 static const char ABCDEFG[] = "aBcdefg";
238 static const char ABC[] = "abc";
239 EXPECT_EQ(str_startswith_nocase(ABCDEFG, ABC) - ABCDEFG, str_length(ABC));
240}
241
242TEST(Str, Endswith)
243{
244 EXPECT_TRUE(str_endswith("abcdef", "def"));
245 EXPECT_FALSE(str_endswith("def", "abcdef"));
246
247 EXPECT_TRUE(str_endswith("xyz", ""));
248 EXPECT_FALSE(str_endswith("", "xyz"));
249
250 EXPECT_FALSE(str_endswith("rhyme", "mine"));
251 EXPECT_FALSE(str_endswith("blackboard", "black"));
252
253 EXPECT_TRUE(str_endswith("люди", "юди"));
254 EXPECT_FALSE(str_endswith("люди", "любовь"));
255
256 static const char ABCDEFG[] = "abcdefg";
257 static const char DEFG[] = "defg";
258 EXPECT_EQ(str_endswith(ABCDEFG, DEFG) - ABCDEFG,
259 str_length(ABCDEFG) - str_length(DEFG));
260}
261
262TEST(StrFormat, Positional)
263{
264 char aBuf[256];
265
266 // normal
267 str_format(buffer: aBuf, buffer_size: sizeof(aBuf), format: "%s %s", "first", "second");
268 EXPECT_STREQ(aBuf, "first second");
269
270 // normal with positional arguments
271 str_format(buffer: aBuf, buffer_size: sizeof(aBuf), format: "%1$s %2$s", "first", "second");
272 EXPECT_STREQ(aBuf, "first second");
273
274 // reverse
275 str_format(buffer: aBuf, buffer_size: sizeof(aBuf), format: "%2$s %1$s", "first", "second");
276 EXPECT_STREQ(aBuf, "second first");
277
278 // duplicate
279 str_format(buffer: aBuf, buffer_size: sizeof(aBuf), format: "%1$s %1$s %2$d %1$s %2$d", "str", 1);
280 EXPECT_STREQ(aBuf, "str str 1 str 1");
281}
282
283TEST(Str, EndswithNocase)
284{
285 EXPECT_TRUE(str_endswith_nocase("abcdef", "deF"));
286 EXPECT_FALSE(str_endswith_nocase("def", "abcdef"));
287
288 EXPECT_TRUE(str_endswith_nocase("xyz", ""));
289 EXPECT_FALSE(str_endswith_nocase("", "xyz"));
290
291 EXPECT_FALSE(str_endswith_nocase("rhyme", "minE"));
292 EXPECT_FALSE(str_endswith_nocase("blackboard", "black"));
293
294 EXPECT_TRUE(str_endswith_nocase("люди", "юди"));
295 EXPECT_FALSE(str_endswith_nocase("люди", "любовь"));
296
297 static const char ABCDEFG[] = "abcdefG";
298 static const char DEFG[] = "defg";
299 EXPECT_EQ(str_endswith_nocase(ABCDEFG, DEFG) - ABCDEFG,
300 str_length(ABCDEFG) - str_length(DEFG));
301}
302
303TEST(Str, HexEncode)
304{
305 char aOut[64];
306 const char *pData = "ABCD";
307 str_hex(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 0);
308 EXPECT_STREQ(aOut, "");
309 str_hex(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 1);
310 EXPECT_STREQ(aOut, "41 ");
311 str_hex(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 2);
312 EXPECT_STREQ(aOut, "41 42 ");
313 str_hex(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 3);
314 EXPECT_STREQ(aOut, "41 42 43 ");
315 str_hex(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4);
316 EXPECT_STREQ(aOut, "41 42 43 44 ");
317
318 str_hex(dst: aOut, dst_size: 1, data: pData, data_size: 4);
319 EXPECT_STREQ(aOut, "");
320 str_hex(dst: aOut, dst_size: 2, data: pData, data_size: 4);
321 EXPECT_STREQ(aOut, "");
322 str_hex(dst: aOut, dst_size: 3, data: pData, data_size: 4);
323 EXPECT_STREQ(aOut, "");
324 str_hex(dst: aOut, dst_size: 4, data: pData, data_size: 4);
325 EXPECT_STREQ(aOut, "41 ");
326 str_hex(dst: aOut, dst_size: 5, data: pData, data_size: 4);
327 EXPECT_STREQ(aOut, "41 ");
328 str_hex(dst: aOut, dst_size: 6, data: pData, data_size: 4);
329 EXPECT_STREQ(aOut, "41 ");
330 str_hex(dst: aOut, dst_size: 7, data: pData, data_size: 4);
331 EXPECT_STREQ(aOut, "41 42 ");
332 str_hex(dst: aOut, dst_size: 8, data: pData, data_size: 4);
333 EXPECT_STREQ(aOut, "41 42 ");
334}
335
336TEST(Str, HexEncodeCstyle)
337{
338 char aOut[128];
339 const char *pData = "ABCD";
340 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 0);
341 EXPECT_STREQ(aOut, "");
342 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 1);
343 EXPECT_STREQ(aOut, "0x41");
344 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 2);
345 EXPECT_STREQ(aOut, "0x41, 0x42");
346 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 3);
347 EXPECT_STREQ(aOut, "0x41, 0x42, 0x43");
348 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4);
349 EXPECT_STREQ(aOut, "0x41, 0x42, 0x43, 0x44");
350
351 str_hex_cstyle(dst: aOut, dst_size: 1, data: pData, data_size: 4);
352 EXPECT_STREQ(aOut, "");
353 str_hex_cstyle(dst: aOut, dst_size: 2, data: pData, data_size: 4);
354 EXPECT_STREQ(aOut, "");
355 str_hex_cstyle(dst: aOut, dst_size: 3, data: pData, data_size: 4);
356 EXPECT_STREQ(aOut, "");
357 str_hex_cstyle(dst: aOut, dst_size: 4, data: pData, data_size: 4);
358 EXPECT_STREQ(aOut, "");
359 str_hex_cstyle(dst: aOut, dst_size: 5, data: pData, data_size: 4);
360 EXPECT_STREQ(aOut, "");
361 str_hex_cstyle(dst: aOut, dst_size: 6, data: pData, data_size: 4);
362 EXPECT_STREQ(aOut, "");
363 str_hex_cstyle(dst: aOut, dst_size: 7, data: pData, data_size: 4);
364 EXPECT_STREQ(aOut, "0x41");
365 str_hex_cstyle(dst: aOut, dst_size: 12, data: pData, data_size: 4);
366 EXPECT_STREQ(aOut, "0x41");
367 str_hex_cstyle(dst: aOut, dst_size: 13, data: pData, data_size: 4);
368 EXPECT_STREQ(aOut, "0x41, 0x42");
369 str_hex_cstyle(dst: aOut, dst_size: 14, data: pData, data_size: 4);
370 EXPECT_STREQ(aOut, "0x41, 0x42");
371
372 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4, bytes_per_line: 1);
373 EXPECT_STREQ(aOut, "0x41,\n0x42,\n0x43,\n0x44");
374 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4, bytes_per_line: 2);
375 EXPECT_STREQ(aOut, "0x41, 0x42,\n0x43, 0x44");
376 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4, bytes_per_line: 3);
377 EXPECT_STREQ(aOut, "0x41, 0x42, 0x43,\n0x44");
378 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4, bytes_per_line: 4);
379 EXPECT_STREQ(aOut, "0x41, 0x42, 0x43, 0x44");
380 str_hex_cstyle(dst: aOut, dst_size: sizeof(aOut), data: pData, data_size: 4, bytes_per_line: 500);
381 EXPECT_STREQ(aOut, "0x41, 0x42, 0x43, 0x44");
382}
383
384TEST(Str, HexDecode)
385{
386 char aOut[5] = {'a', 'b', 'c', 'd', 0};
387 EXPECT_EQ(str_hex_decode(aOut, 0, ""), 0);
388 EXPECT_STREQ(aOut, "abcd");
389 EXPECT_EQ(str_hex_decode(aOut, 0, " "), 2);
390 EXPECT_STREQ(aOut, "abcd");
391 EXPECT_EQ(str_hex_decode(aOut, 1, "1"), 2);
392 EXPECT_STREQ(aOut + 1, "bcd");
393 EXPECT_EQ(str_hex_decode(aOut, 1, "41"), 0);
394 EXPECT_STREQ(aOut, "Abcd");
395 EXPECT_EQ(str_hex_decode(aOut, 1, "4x"), 1);
396 EXPECT_STREQ(aOut + 1, "bcd");
397 EXPECT_EQ(str_hex_decode(aOut, 1, "x1"), 1);
398 EXPECT_STREQ(aOut + 1, "bcd");
399 EXPECT_EQ(str_hex_decode(aOut, 1, "411"), 2);
400 EXPECT_STREQ(aOut + 1, "bcd");
401 EXPECT_EQ(str_hex_decode(aOut, 4, "41424344"), 0);
402 EXPECT_STREQ(aOut, "ABCD");
403}
404
405void StrBase64Str(char *pBuffer, int BufferSize, const char *pString)
406{
407 str_base64(dst: pBuffer, dst_size: BufferSize, data: pString, data_size: str_length(str: pString));
408}
409
410TEST(Str, Base64)
411{
412 char aBuf[128];
413 str_base64(dst: aBuf, dst_size: sizeof(aBuf), data: "\0", data_size: 1);
414 EXPECT_STREQ(aBuf, "AA==");
415 str_base64(dst: aBuf, dst_size: sizeof(aBuf), data: "\0\0", data_size: 2);
416 EXPECT_STREQ(aBuf, "AAA=");
417 str_base64(dst: aBuf, dst_size: sizeof(aBuf), data: "\0\0\0", data_size: 3);
418 EXPECT_STREQ(aBuf, "AAAA");
419
420 StrBase64Str(pBuffer: aBuf, BufferSize: sizeof(aBuf), pString: "");
421 EXPECT_STREQ(aBuf, "");
422
423 // https://en.wikipedia.org/w/index.php?title=Base64&oldid=1033503483#Output_padding
424 StrBase64Str(pBuffer: aBuf, BufferSize: sizeof(aBuf), pString: "pleasure.");
425 EXPECT_STREQ(aBuf, "cGxlYXN1cmUu");
426 StrBase64Str(pBuffer: aBuf, BufferSize: sizeof(aBuf), pString: "leasure.");
427 EXPECT_STREQ(aBuf, "bGVhc3VyZS4=");
428 StrBase64Str(pBuffer: aBuf, BufferSize: sizeof(aBuf), pString: "easure.");
429 EXPECT_STREQ(aBuf, "ZWFzdXJlLg==");
430 StrBase64Str(pBuffer: aBuf, BufferSize: sizeof(aBuf), pString: "asure.");
431 EXPECT_STREQ(aBuf, "YXN1cmUu");
432 StrBase64Str(pBuffer: aBuf, BufferSize: sizeof(aBuf), pString: "sure.");
433 EXPECT_STREQ(aBuf, "c3VyZS4=");
434}
435
436TEST(Str, Base64Decode)
437{
438 char aOut[17];
439 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
440 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), ""), 0);
441 EXPECT_STREQ(aOut, "XXXXXXXXXXXXXXXX");
442
443 // https://en.wikipedia.org/w/index.php?title=Base64&oldid=1033503483#Output_padding
444 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
445 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), "cGxlYXN1cmUu"), 9);
446 EXPECT_STREQ(aOut, "pleasure.XXXXXXX");
447 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
448 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), "bGVhc3VyZS4="), 8);
449 EXPECT_STREQ(aOut, "leasure.XXXXXXXX");
450 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
451 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), "ZWFzdXJlLg=="), 7);
452 EXPECT_STREQ(aOut, "easure.XXXXXXXXX");
453 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
454 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), "YXN1cmUu"), 6);
455 EXPECT_STREQ(aOut, "asure.XXXXXXXXXX");
456 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
457 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), "c3VyZS4="), 5);
458 EXPECT_STREQ(aOut, "sure.XXXXXXXXXXX");
459 str_copy(dst: aOut, src: "XXXXXXXXXXXXXXXX", dst_size: sizeof(aOut));
460 EXPECT_EQ(str_base64_decode(aOut, sizeof(aOut), "////"), 3);
461 EXPECT_STREQ(aOut, "\xff\xff\xffXXXXXXXXXXXXX");
462}
463
464TEST(Str, Base64DecodeError)
465{
466 char aBuf[128];
467 // Wrong padding.
468 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "A"), 0);
469 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "AA"), 0);
470 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "AAA"), 0);
471 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "A==="), 0);
472 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "=AAA"), 0);
473 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "===="), 0);
474 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "AAA=AAAA"), 0);
475 // Invalid characters.
476 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "----"), 0);
477 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "AAAA "), 0);
478 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "AAA "), 0);
479 // Invalid padding values.
480 EXPECT_LT(str_base64_decode(aBuf, sizeof(aBuf), "//=="), 0);
481}
482
483TEST(Str, Tokenize)
484{
485 char aTest[] = "GER,RUS,ZAF,BRA,CAN";
486 const char *apOut[] = {"GER", "RUS", "ZAF", "BRA", "CAN"};
487 char aBuf[4];
488
489 int n = 0;
490 for(const char *pTok = aTest; (pTok = str_next_token(str: pTok, delim: ",", buffer: aBuf, buffer_size: sizeof(aBuf)));)
491 EXPECT_STREQ(apOut[n++], aBuf);
492
493 char aTest2[] = "";
494 EXPECT_EQ(str_next_token(aTest2, ",", aBuf, sizeof(aBuf)), nullptr);
495
496 char aTest3[] = "+b";
497 str_next_token(str: aTest3, delim: "+", buffer: aBuf, buffer_size: sizeof(aBuf));
498 EXPECT_STREQ(aBuf, "b");
499}
500
501TEST(Str, InList)
502{
503 char aTest[] = "GER,RUS,ZAF,BRA,CAN";
504 EXPECT_TRUE(str_in_list(aTest, ",", "GER"));
505 EXPECT_TRUE(str_in_list(aTest, ",", "RUS"));
506 EXPECT_TRUE(str_in_list(aTest, ",", "ZAF"));
507 EXPECT_TRUE(str_in_list(aTest, ",", "BRA"));
508 EXPECT_TRUE(str_in_list(aTest, ",", "CAN"));
509
510 EXPECT_FALSE(str_in_list(aTest, ",", "CHN"));
511 EXPECT_FALSE(str_in_list(aTest, ",", "R,R"));
512
513 EXPECT_FALSE(str_in_list("abc,xyz", ",", "abcdef"));
514 EXPECT_FALSE(str_in_list("", ",", ""));
515 EXPECT_FALSE(str_in_list("", ",", "xyz"));
516
517 EXPECT_TRUE(str_in_list("FOO,,BAR", ",", ""));
518 EXPECT_TRUE(str_in_list("abc,,def", ",", "def"));
519}
520
521TEST(Str, Format)
522{
523 char aBuf[4];
524 EXPECT_EQ(str_format(aBuf, 4, "%d:", 9), 2);
525 EXPECT_STREQ(aBuf, "9:");
526 EXPECT_EQ(str_format(aBuf, 4, "%d: ", 9), 3);
527 EXPECT_STREQ(aBuf, "9: ");
528 EXPECT_EQ(str_format(aBuf, 4, "%d: ", 99), 3);
529 EXPECT_STREQ(aBuf, "99:");
530}
531
532TEST(Str, FormatTruncate)
533{
534 const char *pStr = "DDNet最好了";
535 char aBuf[64];
536 str_format(buffer: aBuf, buffer_size: 7, format: "%s", pStr);
537 EXPECT_STREQ(aBuf, "DDNet");
538 str_format(buffer: aBuf, buffer_size: 8, format: "%s", pStr);
539 EXPECT_STREQ(aBuf, "DDNet");
540 str_format(buffer: aBuf, buffer_size: 9, format: "%s", pStr);
541 EXPECT_STREQ(aBuf, "DDNet最");
542 str_format(buffer: aBuf, buffer_size: 10, format: "%s", pStr);
543 EXPECT_STREQ(aBuf, "DDNet最");
544 str_format(buffer: aBuf, buffer_size: 11, format: "%s", pStr);
545 EXPECT_STREQ(aBuf, "DDNet最");
546 str_format(buffer: aBuf, buffer_size: 12, format: "%s", pStr);
547 EXPECT_STREQ(aBuf, "DDNet最好");
548 str_format(buffer: aBuf, buffer_size: 13, format: "%s", pStr);
549 EXPECT_STREQ(aBuf, "DDNet最好");
550 str_format(buffer: aBuf, buffer_size: 14, format: "%s", pStr);
551 EXPECT_STREQ(aBuf, "DDNet最好");
552 str_format(buffer: aBuf, buffer_size: 15, format: "%s", pStr);
553 EXPECT_STREQ(aBuf, "DDNet最好了");
554 str_format(buffer: aBuf, buffer_size: 16, format: "%s", pStr);
555 EXPECT_STREQ(aBuf, "DDNet最好了");
556}
557
558TEST(Str, TrimWords)
559{
560 const char *pStr1 = "aa bb ccc dddd eeeee";
561 EXPECT_STREQ(str_trim_words(pStr1, 0), "aa bb ccc dddd eeeee");
562 EXPECT_STREQ(str_trim_words(pStr1, 1), "bb ccc dddd eeeee");
563 EXPECT_STREQ(str_trim_words(pStr1, 2), "ccc dddd eeeee");
564 EXPECT_STREQ(str_trim_words(pStr1, 3), "dddd eeeee");
565 EXPECT_STREQ(str_trim_words(pStr1, 4), "eeeee");
566 EXPECT_STREQ(str_trim_words(pStr1, 5), "");
567 EXPECT_STREQ(str_trim_words(pStr1, 100), "");
568 const char *pStr2 = " aaa bb ";
569 EXPECT_STREQ(str_trim_words(pStr2, 0), "aaa bb ");
570 EXPECT_STREQ(str_trim_words(pStr2, 1), "bb ");
571 EXPECT_STREQ(str_trim_words(pStr2, 2), "");
572 EXPECT_STREQ(str_trim_words(pStr2, 100), "");
573 const char *pStr3 = "\n\naa bb\t\tccc\r\n\r\ndddd";
574 EXPECT_STREQ(str_trim_words(pStr3, 0), "aa bb\t\tccc\r\n\r\ndddd");
575 EXPECT_STREQ(str_trim_words(pStr3, 1), "bb\t\tccc\r\n\r\ndddd");
576 EXPECT_STREQ(str_trim_words(pStr3, 2), "ccc\r\n\r\ndddd");
577 EXPECT_STREQ(str_trim_words(pStr3, 3), "dddd");
578 EXPECT_STREQ(str_trim_words(pStr3, 4), "");
579 EXPECT_STREQ(str_trim_words(pStr3, 100), "");
580}
581
582TEST(Str, CopyNum)
583{
584 const char *pFoo = "Foobaré";
585 char aBuf[64];
586 str_utf8_truncate(dst: aBuf, dst_size: 3, src: pFoo, truncation_len: 1);
587 EXPECT_STREQ(aBuf, "F");
588 str_utf8_truncate(dst: aBuf, dst_size: 3, src: pFoo, truncation_len: 2);
589 EXPECT_STREQ(aBuf, "Fo");
590 str_utf8_truncate(dst: aBuf, dst_size: 3, src: pFoo, truncation_len: 3);
591 EXPECT_STREQ(aBuf, "Fo");
592 str_utf8_truncate(dst: aBuf, dst_size: sizeof(aBuf), src: pFoo, truncation_len: 6);
593 EXPECT_STREQ(aBuf, "Foobar");
594 str_utf8_truncate(dst: aBuf, dst_size: sizeof(aBuf), src: pFoo, truncation_len: 7);
595 EXPECT_STREQ(aBuf, "Foobaré");
596 str_utf8_truncate(dst: aBuf, dst_size: sizeof(aBuf), src: pFoo, truncation_len: 0);
597 EXPECT_STREQ(aBuf, "");
598
599 char aBuf2[8];
600 str_utf8_truncate(dst: aBuf2, dst_size: sizeof(aBuf2), src: pFoo, truncation_len: 7);
601 EXPECT_STREQ(aBuf2, "Foobar");
602 char aBuf3[9];
603 str_utf8_truncate(dst: aBuf3, dst_size: sizeof(aBuf3), src: pFoo, truncation_len: 7);
604 EXPECT_STREQ(aBuf3, "Foobaré");
605}
606
607TEST(Str, Copy)
608{
609 const char *pStr = "DDNet最好了";
610 char aBuf[64];
611 str_copy(dst: aBuf, src: pStr, dst_size: 7);
612 EXPECT_STREQ(aBuf, "DDNet");
613 str_copy(dst: aBuf, src: pStr, dst_size: 8);
614 EXPECT_STREQ(aBuf, "DDNet");
615 str_copy(dst: aBuf, src: pStr, dst_size: 9);
616 EXPECT_STREQ(aBuf, "DDNet最");
617 str_copy(dst: aBuf, src: pStr, dst_size: 10);
618 EXPECT_STREQ(aBuf, "DDNet最");
619 str_copy(dst: aBuf, src: pStr, dst_size: 11);
620 EXPECT_STREQ(aBuf, "DDNet最");
621 str_copy(dst: aBuf, src: pStr, dst_size: 12);
622 EXPECT_STREQ(aBuf, "DDNet最好");
623 str_copy(dst: aBuf, src: pStr, dst_size: 13);
624 EXPECT_STREQ(aBuf, "DDNet最好");
625 str_copy(dst: aBuf, src: pStr, dst_size: 14);
626 EXPECT_STREQ(aBuf, "DDNet最好");
627 str_copy(dst: aBuf, src: pStr, dst_size: 15);
628 EXPECT_STREQ(aBuf, "DDNet最好了");
629 str_copy(dst: aBuf, src: pStr, dst_size: 16);
630 EXPECT_STREQ(aBuf, "DDNet最好了");
631 str_copy(dst&: aBuf, src: pStr);
632 EXPECT_STREQ(aBuf, "DDNet最好了");
633}
634
635TEST(Str, Append)
636{
637 char aBuf[64];
638 aBuf[0] = '\0';
639 str_append(dst: aBuf, src: "DDNet最好了", dst_size: 7);
640 EXPECT_STREQ(aBuf, "DDNet");
641 str_append(dst: aBuf, src: "最", dst_size: 8);
642 EXPECT_STREQ(aBuf, "DDNet");
643 str_append(dst: aBuf, src: "最", dst_size: 9);
644 EXPECT_STREQ(aBuf, "DDNet最");
645 str_append(dst: aBuf, src: "好", dst_size: 10);
646 EXPECT_STREQ(aBuf, "DDNet最");
647 str_append(dst: aBuf, src: "好", dst_size: 11);
648 EXPECT_STREQ(aBuf, "DDNet最");
649 str_append(dst: aBuf, src: "好", dst_size: 12);
650 EXPECT_STREQ(aBuf, "DDNet最好");
651 str_append(dst: aBuf, src: "了", dst_size: 13);
652 EXPECT_STREQ(aBuf, "DDNet最好");
653 str_append(dst: aBuf, src: "了", dst_size: 14);
654 EXPECT_STREQ(aBuf, "DDNet最好");
655 str_append(dst: aBuf, src: "了", dst_size: 15);
656 EXPECT_STREQ(aBuf, "DDNet最好了");
657 str_append(dst: aBuf, src: "了", dst_size: 16);
658 EXPECT_STREQ(aBuf, "DDNet最好了");
659 aBuf[0] = '\0';
660 str_append(dst&: aBuf, src: "DDNet最好了");
661 EXPECT_STREQ(aBuf, "DDNet最好了");
662}
663
664TEST(Str, Utf8Stats)
665{
666 size_t Size, Count;
667
668 str_utf8_stats(str: "abc", max_size: 4, max_count: 3, size: &Size, count: &Count);
669 EXPECT_EQ(Size, 3);
670 EXPECT_EQ(Count, 3);
671
672 str_utf8_stats(str: "abc", max_size: 2, max_count: 3, size: &Size, count: &Count);
673 EXPECT_EQ(Size, 1);
674 EXPECT_EQ(Count, 1);
675
676 str_utf8_stats(str: "", max_size: 1, max_count: 0, size: &Size, count: &Count);
677 EXPECT_EQ(Size, 0);
678 EXPECT_EQ(Count, 0);
679
680 str_utf8_stats(str: "abcde", max_size: 6, max_count: 5, size: &Size, count: &Count);
681 EXPECT_EQ(Size, 5);
682 EXPECT_EQ(Count, 5);
683
684 str_utf8_stats(str: "любовь", max_size: 13, max_count: 6, size: &Size, count: &Count);
685 EXPECT_EQ(Size, 12);
686 EXPECT_EQ(Count, 6);
687
688 str_utf8_stats(str: "abc愛", max_size: 7, max_count: 4, size: &Size, count: &Count);
689 EXPECT_EQ(Size, 6);
690 EXPECT_EQ(Count, 4);
691
692 str_utf8_stats(str: "abc愛", max_size: 6, max_count: 4, size: &Size, count: &Count);
693 EXPECT_EQ(Size, 3);
694 EXPECT_EQ(Count, 3);
695
696 str_utf8_stats(str: "любовь", max_size: 13, max_count: 3, size: &Size, count: &Count);
697 EXPECT_EQ(Size, 6);
698 EXPECT_EQ(Count, 3);
699}
700
701TEST(Str, Utf8OffsetBytesToChars)
702{
703 EXPECT_EQ(str_utf8_offset_bytes_to_chars("", 0), 0);
704 EXPECT_EQ(str_utf8_offset_bytes_to_chars("", 100), 0);
705
706 EXPECT_EQ(str_utf8_offset_bytes_to_chars("abc", 0), 0);
707 EXPECT_EQ(str_utf8_offset_bytes_to_chars("abc", 1), 1);
708 EXPECT_EQ(str_utf8_offset_bytes_to_chars("abc", 2), 2);
709 EXPECT_EQ(str_utf8_offset_bytes_to_chars("abc", 3), 3);
710 EXPECT_EQ(str_utf8_offset_bytes_to_chars("abc", 100), 3);
711
712 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 0), 0);
713 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 2), 1);
714 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 4), 2);
715 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 6), 3);
716 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 8), 4);
717 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 10), 5);
718 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 12), 6);
719 EXPECT_EQ(str_utf8_offset_bytes_to_chars("любовь", 100), 6);
720
721 EXPECT_EQ(str_utf8_offset_bytes_to_chars("DDNet最好了", 5), 5);
722 EXPECT_EQ(str_utf8_offset_bytes_to_chars("DDNet最好了", 8), 6);
723 EXPECT_EQ(str_utf8_offset_bytes_to_chars("DDNet最好了", 11), 7);
724 EXPECT_EQ(str_utf8_offset_bytes_to_chars("DDNet最好了", 14), 8);
725 EXPECT_EQ(str_utf8_offset_bytes_to_chars("DDNet最好了", 100), 8);
726}
727
728TEST(Str, Utf8OffsetCharsToBytes)
729{
730 EXPECT_EQ(str_utf8_offset_chars_to_bytes("", 0), 0);
731 EXPECT_EQ(str_utf8_offset_chars_to_bytes("", 100), 0);
732
733 EXPECT_EQ(str_utf8_offset_chars_to_bytes("abc", 0), 0);
734 EXPECT_EQ(str_utf8_offset_chars_to_bytes("abc", 1), 1);
735 EXPECT_EQ(str_utf8_offset_chars_to_bytes("abc", 2), 2);
736 EXPECT_EQ(str_utf8_offset_chars_to_bytes("abc", 3), 3);
737 EXPECT_EQ(str_utf8_offset_chars_to_bytes("abc", 100), 3);
738
739 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 0), 0);
740 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 1), 2);
741 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 2), 4);
742 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 3), 6);
743 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 4), 8);
744 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 5), 10);
745 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 6), 12);
746 EXPECT_EQ(str_utf8_offset_chars_to_bytes("любовь", 100), 12);
747
748 EXPECT_EQ(str_utf8_offset_chars_to_bytes("DDNet最好了", 5), 5);
749 EXPECT_EQ(str_utf8_offset_chars_to_bytes("DDNet最好了", 6), 8);
750 EXPECT_EQ(str_utf8_offset_chars_to_bytes("DDNet最好了", 7), 11);
751 EXPECT_EQ(str_utf8_offset_chars_to_bytes("DDNet最好了", 8), 14);
752 EXPECT_EQ(str_utf8_offset_chars_to_bytes("DDNet最好了", 100), 14);
753}
754
755TEST(Str, Time)
756{
757 char aBuf[32] = "foobar";
758
759 EXPECT_EQ(str_time(123456, TIME_DAYS, aBuf, 0), -1);
760 EXPECT_STREQ(aBuf, "foobar");
761
762 EXPECT_EQ(str_time(123456, TIME_SECS_CENTISECS + 1, aBuf, sizeof(aBuf)), -1);
763 EXPECT_STREQ(aBuf, "");
764
765 EXPECT_EQ(str_time(-123456, TIME_MINS_CENTISECS, aBuf, sizeof(aBuf)), 5);
766 EXPECT_STREQ(aBuf, "00.00");
767
768 EXPECT_EQ(str_time(INT64_MAX, TIME_DAYS, aBuf, sizeof(aBuf)), 23);
769 EXPECT_STREQ(aBuf, "1067519911673d 00:09:18");
770
771 EXPECT_EQ(str_time(123456, TIME_DAYS, aBuf, sizeof(aBuf)), 5);
772 EXPECT_STREQ(aBuf, "20:34");
773 EXPECT_EQ(str_time(1234567, TIME_DAYS, aBuf, sizeof(aBuf)), 8);
774 EXPECT_STREQ(aBuf, "03:25:45");
775 EXPECT_EQ(str_time(12345678, TIME_DAYS, aBuf, sizeof(aBuf)), 11);
776 EXPECT_STREQ(aBuf, "1d 10:17:36");
777
778 EXPECT_EQ(str_time(123456, TIME_HOURS, aBuf, sizeof(aBuf)), 5);
779 EXPECT_STREQ(aBuf, "20:34");
780 EXPECT_EQ(str_time(1234567, TIME_HOURS, aBuf, sizeof(aBuf)), 8);
781 EXPECT_STREQ(aBuf, "03:25:45");
782 EXPECT_EQ(str_time(12345678, TIME_HOURS, aBuf, sizeof(aBuf)), 8);
783 EXPECT_STREQ(aBuf, "34:17:36");
784
785 EXPECT_EQ(str_time(123456, TIME_MINS, aBuf, sizeof(aBuf)), 5);
786 EXPECT_STREQ(aBuf, "20:34");
787 EXPECT_EQ(str_time(1234567, TIME_MINS, aBuf, sizeof(aBuf)), 6);
788 EXPECT_STREQ(aBuf, "205:45");
789 EXPECT_EQ(str_time(12345678, TIME_MINS, aBuf, sizeof(aBuf)), 7);
790 EXPECT_STREQ(aBuf, "2057:36");
791
792 EXPECT_EQ(str_time(123456, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf)), 8);
793 EXPECT_STREQ(aBuf, "20:34.56");
794 EXPECT_EQ(str_time(1234567, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf)), 11);
795 EXPECT_STREQ(aBuf, "03:25:45.67");
796 EXPECT_EQ(str_time(12345678, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf)), 11);
797 EXPECT_STREQ(aBuf, "34:17:36.78");
798
799 EXPECT_EQ(str_time(123456, TIME_MINS_CENTISECS, aBuf, sizeof(aBuf)), 8);
800 EXPECT_STREQ(aBuf, "20:34.56");
801 EXPECT_EQ(str_time(1234567, TIME_MINS_CENTISECS, aBuf, sizeof(aBuf)), 9);
802 EXPECT_STREQ(aBuf, "205:45.67");
803 EXPECT_EQ(str_time(12345678, TIME_MINS_CENTISECS, aBuf, sizeof(aBuf)), 10);
804 EXPECT_STREQ(aBuf, "2057:36.78");
805
806 EXPECT_EQ(str_time(123456, TIME_SECS_CENTISECS, aBuf, sizeof(aBuf)), 5);
807 EXPECT_STREQ(aBuf, "34.56");
808 EXPECT_EQ(str_time(1234567, TIME_SECS_CENTISECS, aBuf, sizeof(aBuf)), 5);
809 EXPECT_STREQ(aBuf, "45.67");
810 EXPECT_EQ(str_time(12345678, TIME_SECS_CENTISECS, aBuf, sizeof(aBuf)), 5);
811 EXPECT_STREQ(aBuf, "36.78");
812}
813
814TEST(Str, TimeFloat)
815{
816 char aBuf[64];
817 EXPECT_EQ(str_time_float(123456.78, TIME_DAYS, aBuf, sizeof(aBuf)), 11);
818 EXPECT_STREQ(aBuf, "1d 10:17:36");
819
820 EXPECT_EQ(str_time_float(12.16, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf)), 5);
821 EXPECT_STREQ(aBuf, "12.16");
822
823 EXPECT_EQ(str_time_float(22.995, TIME_MINS, aBuf, sizeof(aBuf)), 5);
824 EXPECT_STREQ(aBuf, "00:22");
825}
826
827TEST(Str, HasCc)
828{
829 EXPECT_FALSE(str_has_cc(""));
830 EXPECT_FALSE(str_has_cc("a"));
831 EXPECT_FALSE(str_has_cc("Merhaba dünya!"));
832
833 EXPECT_TRUE(str_has_cc("\n"));
834 EXPECT_TRUE(str_has_cc("\r"));
835 EXPECT_TRUE(str_has_cc("\t"));
836 EXPECT_TRUE(str_has_cc("a\n"));
837 EXPECT_TRUE(str_has_cc("a\rb"));
838 EXPECT_TRUE(str_has_cc("\tb"));
839 EXPECT_TRUE(str_has_cc("\n\n"));
840 EXPECT_TRUE(str_has_cc("\x1C"));
841 EXPECT_TRUE(str_has_cc("\x1D"));
842 EXPECT_TRUE(str_has_cc("\x1E"));
843 EXPECT_TRUE(str_has_cc("\x1F"));
844}
845
846TEST(Str, SanitizeCc)
847{
848 char aBuf[64];
849 str_copy(dst&: aBuf, src: "");
850 str_sanitize_cc(str: aBuf);
851 EXPECT_STREQ(aBuf, "");
852 str_copy(dst&: aBuf, src: "a");
853 str_sanitize_cc(str: aBuf);
854 EXPECT_STREQ(aBuf, "a");
855 str_copy(dst&: aBuf, src: "Merhaba dünya!");
856 str_sanitize_cc(str: aBuf);
857 EXPECT_STREQ(aBuf, "Merhaba dünya!");
858
859 str_copy(dst&: aBuf, src: "\n");
860 str_sanitize_cc(str: aBuf);
861 EXPECT_STREQ(aBuf, " ");
862 str_copy(dst&: aBuf, src: "\r");
863 str_sanitize_cc(str: aBuf);
864 EXPECT_STREQ(aBuf, " ");
865 str_copy(dst&: aBuf, src: "\t");
866 str_sanitize_cc(str: aBuf);
867 EXPECT_STREQ(aBuf, " ");
868 str_copy(dst&: aBuf, src: "a\n");
869 str_sanitize_cc(str: aBuf);
870 EXPECT_STREQ(aBuf, "a ");
871 str_copy(dst&: aBuf, src: "a\rb");
872 str_sanitize_cc(str: aBuf);
873 EXPECT_STREQ(aBuf, "a b");
874 str_copy(dst&: aBuf, src: "\tb");
875 str_sanitize_cc(str: aBuf);
876 EXPECT_STREQ(aBuf, " b");
877 str_copy(dst&: aBuf, src: "\n\n");
878 str_sanitize_cc(str: aBuf);
879 EXPECT_STREQ(aBuf, " ");
880 str_copy(dst&: aBuf, src: "\x1C");
881 str_sanitize_cc(str: aBuf);
882 EXPECT_STREQ(aBuf, " ");
883 str_copy(dst&: aBuf, src: "\x1D");
884 str_sanitize_cc(str: aBuf);
885 EXPECT_STREQ(aBuf, " ");
886 str_copy(dst&: aBuf, src: "\x1E");
887 str_sanitize_cc(str: aBuf);
888 EXPECT_STREQ(aBuf, " ");
889 str_copy(dst&: aBuf, src: "\x1F");
890 str_sanitize_cc(str: aBuf);
891 EXPECT_STREQ(aBuf, " ");
892}
893
894TEST(Str, Sanitize)
895{
896 char aBuf[64];
897 str_copy(dst&: aBuf, src: "");
898 str_sanitize(str: aBuf);
899 EXPECT_STREQ(aBuf, "");
900 str_copy(dst&: aBuf, src: "a");
901 str_sanitize(str: aBuf);
902 EXPECT_STREQ(aBuf, "a");
903 str_copy(dst&: aBuf, src: "Merhaba dünya!");
904 str_sanitize(str: aBuf);
905 EXPECT_STREQ(aBuf, "Merhaba dünya!");
906 str_copy(dst&: aBuf, src: "\n");
907 str_sanitize(str: aBuf);
908 EXPECT_STREQ(aBuf, "\n");
909 str_copy(dst&: aBuf, src: "\r");
910 str_sanitize(str: aBuf);
911 EXPECT_STREQ(aBuf, "\r");
912 str_copy(dst&: aBuf, src: "\t");
913 str_sanitize(str: aBuf);
914 EXPECT_STREQ(aBuf, "\t");
915 str_copy(dst&: aBuf, src: "a\n");
916 str_sanitize(str: aBuf);
917 EXPECT_STREQ(aBuf, "a\n");
918 str_copy(dst&: aBuf, src: "a\rb");
919 str_sanitize(str: aBuf);
920 EXPECT_STREQ(aBuf, "a\rb");
921 str_copy(dst&: aBuf, src: "\tb");
922 str_sanitize(str: aBuf);
923 EXPECT_STREQ(aBuf, "\tb");
924 str_copy(dst&: aBuf, src: "\n\n");
925 str_sanitize(str: aBuf);
926 EXPECT_STREQ(aBuf, "\n\n");
927
928 str_copy(dst&: aBuf, src: "\x1C");
929 str_sanitize(str: aBuf);
930 EXPECT_STREQ(aBuf, " ");
931 str_copy(dst&: aBuf, src: "\x1D");
932 str_sanitize(str: aBuf);
933 EXPECT_STREQ(aBuf, " ");
934 str_copy(dst&: aBuf, src: "\x1E");
935 str_sanitize(str: aBuf);
936 EXPECT_STREQ(aBuf, " ");
937 str_copy(dst&: aBuf, src: "\x1F");
938 str_sanitize(str: aBuf);
939 EXPECT_STREQ(aBuf, " ");
940}
941
942TEST(Str, CleanWhitespaces)
943{
944 char aBuf[64];
945 str_copy(dst&: aBuf, src: "aa bb ccc dddd eeeee");
946 str_clean_whitespaces(str: aBuf);
947 EXPECT_STREQ(aBuf, "aa bb ccc dddd eeeee");
948 str_copy(dst&: aBuf, src: " ");
949 str_clean_whitespaces(str: aBuf);
950 EXPECT_STREQ(aBuf, "");
951 str_copy(dst&: aBuf, src: " aa");
952 str_clean_whitespaces(str: aBuf);
953 EXPECT_STREQ(aBuf, "aa");
954 str_copy(dst&: aBuf, src: "aa ");
955 str_clean_whitespaces(str: aBuf);
956 EXPECT_STREQ(aBuf, "aa");
957 str_copy(dst&: aBuf, src: " aa bb ccc dddd eeeee ");
958 str_clean_whitespaces(str: aBuf);
959 EXPECT_STREQ(aBuf, "aa bb ccc dddd eeeee");
960}
961
962TEST(Str, SkipToWhitespace)
963{
964 char aBuf[64];
965 str_copy(dst&: aBuf, src: "");
966 EXPECT_EQ(str_skip_to_whitespace(aBuf), aBuf);
967 EXPECT_EQ(str_skip_to_whitespace_const(aBuf), aBuf);
968 str_copy(dst&: aBuf, src: " a");
969 EXPECT_EQ(str_skip_to_whitespace(aBuf), aBuf);
970 EXPECT_EQ(str_skip_to_whitespace_const(aBuf), aBuf);
971 str_copy(dst&: aBuf, src: "aaaa b");
972 EXPECT_EQ(str_skip_to_whitespace(aBuf), aBuf + 4);
973 EXPECT_EQ(str_skip_to_whitespace_const(aBuf), aBuf + 4);
974 str_copy(dst&: aBuf, src: "aaaa\n\nb");
975 EXPECT_EQ(str_skip_to_whitespace(aBuf), aBuf + 4);
976 EXPECT_EQ(str_skip_to_whitespace_const(aBuf), aBuf + 4);
977 str_copy(dst&: aBuf, src: "aaaa\r\rb");
978 EXPECT_EQ(str_skip_to_whitespace(aBuf), aBuf + 4);
979 EXPECT_EQ(str_skip_to_whitespace_const(aBuf), aBuf + 4);
980 str_copy(dst&: aBuf, src: "aaaa\t\tb");
981 EXPECT_EQ(str_skip_to_whitespace(aBuf), aBuf + 4);
982 EXPECT_EQ(str_skip_to_whitespace_const(aBuf), aBuf + 4);
983}
984
985TEST(Str, SkipWhitespaces)
986{
987 char aBuf[64];
988 str_copy(dst&: aBuf, src: "");
989 EXPECT_EQ(str_skip_whitespaces(aBuf), aBuf);
990 EXPECT_EQ(str_skip_whitespaces_const(aBuf), aBuf);
991 str_copy(dst&: aBuf, src: "aaaa");
992 EXPECT_EQ(str_skip_whitespaces(aBuf), aBuf);
993 EXPECT_EQ(str_skip_whitespaces_const(aBuf), aBuf);
994 str_copy(dst&: aBuf, src: " \n\r\taaaa");
995 EXPECT_EQ(str_skip_whitespaces(aBuf), aBuf + 4);
996 EXPECT_EQ(str_skip_whitespaces_const(aBuf), aBuf + 4);
997}
998
999TEST(Str, CompFilename)
1000{
1001 EXPECT_EQ(str_comp_filenames("a", "a"), 0);
1002 EXPECT_LT(str_comp_filenames("a", "b"), 0);
1003 EXPECT_GT(str_comp_filenames("b", "a"), 0);
1004 EXPECT_EQ(str_comp_filenames("A", "a"), 0);
1005 EXPECT_LT(str_comp_filenames("A", "b"), 0);
1006 EXPECT_GT(str_comp_filenames("b", "A"), 0);
1007 EXPECT_LT(str_comp_filenames("a", "B"), 0);
1008 EXPECT_GT(str_comp_filenames("B", "a"), 0);
1009 EXPECT_EQ(str_comp_filenames("1A", "1a"), 0);
1010 EXPECT_LT(str_comp_filenames("1a", "1B"), 0);
1011 EXPECT_GT(str_comp_filenames("1B", "1a"), 0);
1012 EXPECT_LT(str_comp_filenames("1a", "1b"), 0);
1013 EXPECT_GT(str_comp_filenames("1b", "1a"), 0);
1014 EXPECT_GT(str_comp_filenames("12a", "1B"), 0);
1015 EXPECT_LT(str_comp_filenames("1B", "12a"), 0);
1016 EXPECT_GT(str_comp_filenames("10a", "1B"), 0);
1017 EXPECT_LT(str_comp_filenames("1B", "10a"), 0);
1018 EXPECT_GT(str_comp_filenames("10a", "00B"), 0);
1019 EXPECT_LT(str_comp_filenames("00B", "10a"), 0);
1020 EXPECT_GT(str_comp_filenames("10a", "09B"), 0);
1021 EXPECT_LT(str_comp_filenames("09B", "10a"), 0);
1022 EXPECT_LT(str_comp_filenames("abc", "abcd"), 0);
1023 EXPECT_GT(str_comp_filenames("abcd", "abc"), 0);
1024 EXPECT_LT(str_comp_filenames("abc2", "abcd1"), 0);
1025 EXPECT_GT(str_comp_filenames("abcd1", "abc2"), 0);
1026 EXPECT_LT(str_comp_filenames("abc50", "abcd"), 0);
1027 EXPECT_GT(str_comp_filenames("abcd", "abc50"), 0);
1028 EXPECT_EQ(str_comp_filenames("file0", "file0"), 0);
1029 EXPECT_LT(str_comp_filenames("file0", "file1"), 0);
1030 EXPECT_GT(str_comp_filenames("file1", "file0"), 0);
1031 EXPECT_LT(str_comp_filenames("file1", "file09"), 0);
1032 EXPECT_GT(str_comp_filenames("file09", "file1"), 0);
1033 EXPECT_LT(str_comp_filenames("file1", "file009"), 0);
1034 EXPECT_GT(str_comp_filenames("file009", "file1"), 0);
1035 EXPECT_GT(str_comp_filenames("file10", "file00"), 0);
1036 EXPECT_LT(str_comp_filenames("file00", "file10"), 0);
1037 EXPECT_GT(str_comp_filenames("file10", "file09"), 0);
1038 EXPECT_LT(str_comp_filenames("file09", "file10"), 0);
1039 EXPECT_LT(str_comp_filenames("file13", "file37"), 0);
1040 EXPECT_GT(str_comp_filenames("file37", "file13"), 0);
1041 EXPECT_LT(str_comp_filenames("file1.ext", "file09.ext"), 0);
1042 EXPECT_GT(str_comp_filenames("file09.ext", "file1.ext"), 0);
1043 EXPECT_LT(str_comp_filenames("file1.ext", "file009.ext"), 0);
1044 EXPECT_GT(str_comp_filenames("file009.ext", "file1.ext"), 0);
1045 EXPECT_EQ(str_comp_filenames("file0.ext", "file0.ext"), 0);
1046 EXPECT_LT(str_comp_filenames("file13.ext", "file37.ext"), 0);
1047 EXPECT_GT(str_comp_filenames("file37.ext", "file13.ext"), 0);
1048 EXPECT_LT(str_comp_filenames("FILE13.EXT", "file37.ext"), 0);
1049 EXPECT_GT(str_comp_filenames("file37.ext", "FILE13.EXT"), 0);
1050 EXPECT_GT(str_comp_filenames("file10.ext", "file00.ext"), 0);
1051 EXPECT_LT(str_comp_filenames("file00.ext", "file10.ext"), 0);
1052 EXPECT_GT(str_comp_filenames("file10.ext", "file09.ext"), 0);
1053 EXPECT_LT(str_comp_filenames("file09.ext", "file10.ext"), 0);
1054 EXPECT_LT(str_comp_filenames("file42", "file1337"), 0);
1055 EXPECT_GT(str_comp_filenames("file1337", "file42"), 0);
1056 EXPECT_LT(str_comp_filenames("file42.ext", "file1337.ext"), 0);
1057 EXPECT_GT(str_comp_filenames("file1337.ext", "file42.ext"), 0);
1058 EXPECT_GT(str_comp_filenames("file4414520", "file2055"), 0);
1059 EXPECT_LT(str_comp_filenames("file4414520", "file205523151812419"), 0);
1060}
1061
1062TEST(Str, RightChar)
1063{
1064 const char *pStr = "a bb ccc dddd eeeee";
1065 EXPECT_EQ(str_rchr(pStr, 'a'), pStr);
1066 EXPECT_EQ(str_rchr(pStr, 'b'), pStr + 3);
1067 EXPECT_EQ(str_rchr(pStr, 'c'), pStr + 7);
1068 EXPECT_EQ(str_rchr(pStr, 'd'), pStr + 12);
1069 EXPECT_EQ(str_rchr(pStr, ' '), pStr + 19);
1070 EXPECT_EQ(str_rchr(pStr, 'e'), pStr + 24);
1071 EXPECT_EQ(str_rchr(pStr, '\0'), pStr + str_length(pStr));
1072 EXPECT_EQ(str_rchr(pStr, 'y'), nullptr);
1073}
1074
1075TEST(Str, CountChar)
1076{
1077 const char *pStr = "a bb ccc dddd eeeee";
1078 EXPECT_EQ(str_countchr(pStr, 'a'), 1);
1079 EXPECT_EQ(str_countchr(pStr, 'b'), 2);
1080 EXPECT_EQ(str_countchr(pStr, 'c'), 3);
1081 EXPECT_EQ(str_countchr(pStr, 'd'), 4);
1082 EXPECT_EQ(str_countchr(pStr, 'e'), 5);
1083 EXPECT_EQ(str_countchr(pStr, ' '), 10);
1084 EXPECT_EQ(str_countchr(pStr, '\0'), 0);
1085 EXPECT_EQ(str_countchr(pStr, 'y'), 0);
1086}
1087
1088TEST(Str, StrToInts)
1089{
1090 int aInts[8];
1091
1092 StrToInts(pInts: aInts, NumInts: 1, pStr: "a");
1093 EXPECT_EQ(aInts[0], 0xE1808000);
1094
1095 StrToInts(pInts: aInts, NumInts: 1, pStr: "ab");
1096 EXPECT_EQ(aInts[0], 0xE1E28000);
1097
1098 StrToInts(pInts: aInts, NumInts: 1, pStr: "abc");
1099 EXPECT_EQ(aInts[0], 0xE1E2E300);
1100
1101 StrToInts(pInts: aInts, NumInts: 2, pStr: "abcd");
1102 EXPECT_EQ(aInts[0], 0xE1E2E3E4);
1103 EXPECT_EQ(aInts[1], 0x80808000);
1104
1105 StrToInts(pInts: aInts, NumInts: 2, pStr: "abcde");
1106 EXPECT_EQ(aInts[0], 0xE1E2E3E4);
1107 EXPECT_EQ(aInts[1], 0xE5808000);
1108
1109 StrToInts(pInts: aInts, NumInts: 2, pStr: "abcdef");
1110 EXPECT_EQ(aInts[0], 0xE1E2E3E4);
1111 EXPECT_EQ(aInts[1], 0xE5E68000);
1112
1113 StrToInts(pInts: aInts, NumInts: 2, pStr: "abcdefg");
1114 EXPECT_EQ(aInts[0], 0xE1E2E3E4);
1115 EXPECT_EQ(aInts[1], 0xE5E6E700);
1116
1117 StrToInts(pInts: aInts, NumInts: 2, pStr: "öüä");
1118 EXPECT_EQ(aInts[0], 0x4336433C);
1119 EXPECT_EQ(aInts[1], 0x43248000);
1120
1121 StrToInts(pInts: aInts, NumInts: 3, pStr: "aβい🐘");
1122 EXPECT_EQ(aInts[0], 0xE14E3263);
1123 EXPECT_EQ(aInts[1], 0x0104701F);
1124 EXPECT_EQ(aInts[2], 0x10188000);
1125
1126 // long padding
1127 StrToInts(pInts: aInts, NumInts: 4, pStr: "abc");
1128 EXPECT_EQ(aInts[0], 0xE1E2E380);
1129 EXPECT_EQ(aInts[1], 0x80808080);
1130 EXPECT_EQ(aInts[2], 0x80808080);
1131 EXPECT_EQ(aInts[3], 0x80808000);
1132}
1133
1134TEST(Str, IntsToStr)
1135{
1136 int aInts[8];
1137 char aStr[sizeof(aInts)];
1138
1139 aInts[0] = 0xE1808000;
1140 EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1141 EXPECT_STREQ(aStr, "a");
1142
1143 aInts[0] = 0xE1E28000;
1144 EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1145 EXPECT_STREQ(aStr, "ab");
1146
1147 aInts[0] = 0xE1E2E300;
1148 EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1149 EXPECT_STREQ(aStr, "abc");
1150
1151 aInts[0] = 0xE1E2E3E4;
1152 aInts[1] = 0x80808000;
1153 EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
1154 EXPECT_STREQ(aStr, "abcd");
1155
1156 aInts[0] = 0xE1E2E3E4;
1157 aInts[1] = 0xE5808000;
1158 EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
1159 EXPECT_STREQ(aStr, "abcde");
1160
1161 aInts[0] = 0xE1E2E3E4;
1162 aInts[1] = 0xE5E68000;
1163 EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
1164 EXPECT_STREQ(aStr, "abcdef");
1165
1166 aInts[0] = 0xE1E2E3E4;
1167 aInts[1] = 0xE5E6E700;
1168 EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
1169 EXPECT_STREQ(aStr, "abcdefg");
1170
1171 aInts[0] = 0x4336433C;
1172 aInts[1] = 0x43248000;
1173 EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
1174 EXPECT_STREQ(aStr, "öüä");
1175
1176 aInts[0] = 0xE14E3263;
1177 aInts[1] = 0x0104701F;
1178 aInts[2] = 0x10188000;
1179 EXPECT_TRUE(IntsToStr(aInts, 3, aStr, std::size(aStr)));
1180 EXPECT_STREQ(aStr, "aβい🐘");
1181
1182 // long padding
1183 aInts[0] = 0xE1E2E380;
1184 aInts[1] = 0x80808080;
1185 aInts[2] = 0x80808080;
1186 aInts[3] = 0x80808000;
1187 EXPECT_TRUE(IntsToStr(aInts, 4, aStr, std::size(aStr)));
1188 EXPECT_STREQ(aStr, "abc");
1189
1190 // early null character (0x80)
1191 aInts[0] = 0xE1E2E380;
1192 aInts[1] = 0xE1E2E3E4;
1193 aInts[2] = 0xE1E2E3E4;
1194 aInts[3] = 0xE1E2E300;
1195 EXPECT_TRUE(IntsToStr(aInts, 4, aStr, std::size(aStr)));
1196 EXPECT_STREQ(aStr, "abc");
1197
1198 // invalid UTF-8
1199 aInts[0] = 0xE17FE200;
1200 EXPECT_FALSE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1201 EXPECT_STREQ(aStr, "");
1202
1203 // invalid UTF-8 (0x00 in string data, which is translated to '\x80')
1204 aInts[0] = 0xE100E200;
1205 EXPECT_FALSE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1206 EXPECT_STREQ(aStr, "");
1207
1208 // invalid UTF-8
1209 aInts[0] = 0xE1E2E36F;
1210 aInts[1] = 0x3F40E4E5;
1211 aInts[2] = 0xE67FE700;
1212 EXPECT_FALSE(IntsToStr(aInts, 3, aStr, std::size(aStr)));
1213 EXPECT_STREQ(aStr, "");
1214
1215 // invalid UTF-8 and missing null-terminator
1216 aInts[0] = 0x7F7F7F7F;
1217 EXPECT_FALSE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1218 EXPECT_STREQ(aStr, "");
1219
1220 // missing null-terminator at the end is ignored
1221 aInts[0] = 0xE1E2E3E4;
1222 EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
1223 EXPECT_STREQ(aStr, "abc");
1224
1225 // basic fuzzing: no input integer should result in invalid UTF-8 in the string
1226 for(int i = 0; i <= 0xFFFFFF; i += 7) // checking all values takes a bit too long
1227 {
1228 mem_zero(block: aStr, size: std::size(aStr));
1229 aInts[0] = 0xE1 << 24 | i;
1230 aInts[1] = i << 8 | 0xE2;
1231 aInts[2] = 0xE3 << 24 | i;
1232 const bool ConversionResult = IntsToStr(pInts: aInts, NumInts: 3, pStr: aStr, StrSize: std::size(aStr));
1233 // ensure null-termination before calling str_utf8_check
1234 ASSERT_TRUE(mem_has_null(aStr, std::size(aStr)));
1235 ASSERT_TRUE(str_utf8_check(aStr));
1236 ASSERT_TRUE(ConversionResult || aStr[0] == '\0');
1237 }
1238}
1239
1240#if defined(CONF_FAMILY_WINDOWS)
1241TEST(Str, WindowsUtf8WideConversion)
1242{
1243 const char *apUtf8Strings[] = {
1244 "",
1245 "abc",
1246 "a bb ccc dddd eeeee",
1247 "öüä",
1248 "привет Наташа",
1249 "ąçęįǫų",
1250 "DDNet最好了",
1251 "aβい🐘"};
1252 const wchar_t *apWideStrings[] = {
1253 L"",
1254 L"abc",
1255 L"a bb ccc dddd eeeee",
1256 L"öüä",
1257 L"привет Наташа",
1258 L"ąçęįǫų",
1259 L"DDNet最好了",
1260 L"aβい🐘"};
1261 static_assert(std::size(apUtf8Strings) == std::size(apWideStrings));
1262 for(size_t i = 0; i < std::size(apUtf8Strings); i++)
1263 {
1264 const std::optional<std::string> ConvertedUtf8 = windows_wide_to_utf8(apWideStrings[i]);
1265 const std::wstring ConvertedWide = windows_utf8_to_wide(apUtf8Strings[i]);
1266 ASSERT_TRUE(ConvertedUtf8.has_value());
1267 EXPECT_STREQ(ConvertedUtf8.value().c_str(), apUtf8Strings[i]);
1268 EXPECT_STREQ(ConvertedWide.c_str(), apWideStrings[i]);
1269 }
1270}
1271#endif
1272