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