1 | // |
2 | // StringTest.cpp |
3 | // |
4 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "StringTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/CppUnit/TestSuite.h" |
14 | #include "Poco/String.h" |
15 | #include "Poco/JSONString.h" |
16 | #include "Poco/Format.h" |
17 | #include "Poco/MemoryStream.h" |
18 | #include "Poco/Stopwatch.h" |
19 | #include "Poco/FPEnvironment.h" |
20 | #include "Poco/Exception.h" |
21 | #include <iostream> |
22 | #include <sstream> |
23 | #include <iomanip> |
24 | #include <cstdio> |
25 | #include <climits> |
26 | #include <map> |
27 | #include <set> |
28 | |
29 | |
30 | using Poco::trimLeft; |
31 | using Poco::trimLeftInPlace; |
32 | using Poco::trimRight; |
33 | using Poco::trimRightInPlace; |
34 | using Poco::trim; |
35 | using Poco::trimInPlace; |
36 | using Poco::toUpper; |
37 | using Poco::toUpperInPlace; |
38 | using Poco::toLower; |
39 | using Poco::toLowerInPlace; |
40 | using Poco::icompare; |
41 | using Poco::istring; |
42 | using Poco::isubstr; |
43 | using Poco::translate; |
44 | using Poco::translateInPlace; |
45 | using Poco::replace; |
46 | using Poco::replaceInPlace; |
47 | using Poco::remove; |
48 | using Poco::removeInPlace; |
49 | using Poco::cat; |
50 | using Poco::startsWith; |
51 | using Poco::endsWith; |
52 | using Poco::strToInt; |
53 | using Poco::strToFloat; |
54 | using Poco::strToDouble; |
55 | using Poco::intToStr; |
56 | using Poco::uIntToStr; |
57 | using Poco::floatToStr; |
58 | using Poco::doubleToStr; |
59 | using Poco::thousandSeparator; |
60 | using Poco::decimalSeparator; |
61 | using Poco::format; |
62 | using Poco::toJSON; |
63 | using Poco::CILess; |
64 | using Poco::MemoryInputStream; |
65 | using Poco::Stopwatch; |
66 | using Poco::RangeException; |
67 | using Poco::isIntOverflow; |
68 | using Poco::isSafeIntCast; |
69 | using Poco::safeIntCast; |
70 | using Poco::FPEnvironment; |
71 | |
72 | |
73 | StringTest::StringTest(const std::string& rName): CppUnit::TestCase(rName) |
74 | { |
75 | } |
76 | |
77 | |
78 | StringTest::~StringTest() |
79 | { |
80 | } |
81 | |
82 | |
83 | void StringTest::testTrimLeft() |
84 | { |
85 | { |
86 | std::string s = "abc" ; |
87 | assertTrue (trimLeft(s) == "abc" ); |
88 | } |
89 | std::string s = " abc " ; |
90 | assertTrue (trimLeft(s) == "abc " ); |
91 | { |
92 | std::string s = " ab c " ; |
93 | assertTrue (trimLeft(s) == "ab c " ); |
94 | } |
95 | } |
96 | |
97 | |
98 | void StringTest::testTrimLeftInPlace() |
99 | { |
100 | { |
101 | std::string s = "abc" ; |
102 | assertTrue (trimLeftInPlace(s) == "abc" ); |
103 | } |
104 | { |
105 | std::string s = " abc " ; |
106 | assertTrue (trimLeftInPlace(s) == "abc " ); |
107 | } |
108 | { |
109 | std::string s = " ab c " ; |
110 | assertTrue (trimLeftInPlace(s) == "ab c " ); |
111 | } |
112 | } |
113 | |
114 | |
115 | void StringTest::testTrimRight() |
116 | { |
117 | { |
118 | std::string s = "abc" ; |
119 | assertTrue (trimRight(s) == "abc" ); |
120 | } |
121 | { |
122 | std::string s = " abc " ; |
123 | assertTrue (trimRight(s) == " abc" ); |
124 | } |
125 | { |
126 | std::string s = " ab c " ; |
127 | assertTrue (trimRight(s) == " ab c" ); |
128 | } |
129 | } |
130 | |
131 | |
132 | void StringTest::testTrimRightInPlace() |
133 | { |
134 | { |
135 | std::string s = "abc" ; |
136 | assertTrue (trimRightInPlace(s) == "abc" ); |
137 | } |
138 | { |
139 | std::string s = " abc " ; |
140 | assertTrue (trimRightInPlace(s) == " abc" ); |
141 | } |
142 | { |
143 | std::string s = " ab c " ; |
144 | assertTrue (trimRightInPlace(s) == " ab c" ); |
145 | } |
146 | } |
147 | |
148 | |
149 | void StringTest::testTrim() |
150 | { |
151 | { |
152 | std::string s = "abc" ; |
153 | assertTrue (trim(s) == "abc" ); |
154 | } |
155 | { |
156 | std::string s = "abc " ; |
157 | assertTrue (trim(s) == "abc" ); |
158 | } |
159 | { |
160 | std::string s = " ab c " ; |
161 | assertTrue (trim(s) == "ab c" ); |
162 | } |
163 | } |
164 | |
165 | |
166 | void StringTest::testTrimInPlace() |
167 | { |
168 | { |
169 | std::string s = "abc" ; |
170 | assertTrue (trimInPlace(s) == "abc" ); |
171 | } |
172 | { |
173 | std::string s = " abc " ; |
174 | assertTrue (trimInPlace(s) == "abc" ); |
175 | } |
176 | { |
177 | std::string s = " ab c " ; |
178 | assertTrue (trimInPlace(s) == "ab c" ); |
179 | } |
180 | } |
181 | |
182 | |
183 | void StringTest::testToUpper() |
184 | { |
185 | { |
186 | std::string s = "abc" ; |
187 | assertTrue (toUpper(s) == "ABC" ); |
188 | } |
189 | { |
190 | std::string s = "Abc" ; |
191 | assertTrue (toUpper(s) == "ABC" ); |
192 | } |
193 | { |
194 | std::string s = "abc" ; |
195 | assertTrue (toUpperInPlace(s) == "ABC" ); |
196 | } |
197 | { |
198 | std::string s = "Abc" ; |
199 | assertTrue (toUpperInPlace(s) == "ABC" ); |
200 | } |
201 | } |
202 | |
203 | |
204 | void StringTest::testToLower() |
205 | { |
206 | { |
207 | std::string s = "ABC" ; |
208 | assertTrue (toLower(s) == "abc" ); |
209 | } |
210 | { |
211 | std::string s = "aBC" ; |
212 | assertTrue (toLower(s) == "abc" ); |
213 | } |
214 | { |
215 | std::string s = "ABC" ; |
216 | assertTrue (toLowerInPlace(s) == "abc" ); |
217 | } |
218 | { |
219 | std::string s = "aBC" ; |
220 | assertTrue (toLowerInPlace(s) == "abc" ); |
221 | } |
222 | } |
223 | |
224 | |
225 | void StringTest::testIstring() |
226 | { |
227 | istring is1 = "AbC" ; |
228 | istring is2 = "aBc" ; |
229 | assertTrue (is1 == is2); |
230 | |
231 | const char c1[] = { 'G', 0, (char) 0xFC, 'n', 't', 'e', 'r', '\0' }; |
232 | const char c2[] = { 'g', 0, (char) 0xDC, 'N', 'T', 'E', 'R', '\0' }; |
233 | is1 = c1; |
234 | is2 = c2; |
235 | assertTrue (is1 == is2); |
236 | is1[0] = 'f'; |
237 | assertTrue (is1 < is2); |
238 | is1[0] = 'F'; |
239 | assertTrue (is1 < is2); |
240 | is1[0] = 'H'; |
241 | assertTrue (is1 > is2); |
242 | is1[0] = 'h'; |
243 | assertTrue (is1 > is2); |
244 | |
245 | is1 = "aAaBbBcCc" ; |
246 | is2 = "bbb" ; |
247 | assertTrue (isubstr(is1, is2) == 3); |
248 | is2 = "bC" ; |
249 | assertTrue (isubstr(is1, is2) == 5); |
250 | is2 = "xxx" ; |
251 | assertTrue (isubstr(is1, is2) == istring::npos); |
252 | } |
253 | |
254 | |
255 | void StringTest::testIcompare() |
256 | { |
257 | std::string s1 = "AAA" ; |
258 | std::string s2 = "aaa" ; |
259 | std::string s3 = "bbb" ; |
260 | std::string s4 = "cCcCc" ; |
261 | std::string s5; |
262 | assertTrue (icompare(s1, s2) == 0); |
263 | assertTrue (icompare(s1, s3) < 0); |
264 | assertTrue (icompare(s1, s4) < 0); |
265 | assertTrue (icompare(s3, s1) > 0); |
266 | assertTrue (icompare(s4, s2) > 0); |
267 | assertTrue (icompare(s2, s4) < 0); |
268 | assertTrue (icompare(s1, s5) > 0); |
269 | assertTrue (icompare(s5, s4) < 0); |
270 | |
271 | std::string ss1 = "xxAAAzz" ; |
272 | std::string ss2 = "YaaaX" ; |
273 | std::string ss3 = "YbbbX" ; |
274 | assertTrue (icompare(ss1, 2, 3, ss2, 1, 3) == 0); |
275 | assertTrue (icompare(ss1, 2, 3, ss3, 1, 3) < 0); |
276 | assertTrue (icompare(ss1, 2, 3, ss2, 1) == 0); |
277 | assertTrue (icompare(ss1, 2, 3, ss3, 1) < 0); |
278 | assertTrue (icompare(ss1, 2, 2, ss2, 1, 3) < 0); |
279 | assertTrue (icompare(ss1, 2, 2, ss2, 1, 2) == 0); |
280 | assertTrue (icompare(ss3, 1, 3, ss1, 2, 3) > 0); |
281 | |
282 | assertTrue (icompare(s1, s2.c_str()) == 0); |
283 | assertTrue (icompare(s1, s3.c_str()) < 0); |
284 | assertTrue (icompare(s1, s4.c_str()) < 0); |
285 | assertTrue (icompare(s3, s1.c_str()) > 0); |
286 | assertTrue (icompare(s4, s2.c_str()) > 0); |
287 | assertTrue (icompare(s2, s4.c_str()) < 0); |
288 | assertTrue (icompare(s1, s5.c_str()) > 0); |
289 | assertTrue (icompare(s5, s4.c_str()) < 0); |
290 | |
291 | assertTrue (icompare(ss1, 2, 3, "aaa" ) == 0); |
292 | assertTrue (icompare(ss1, 2, 2, "aaa" ) < 0); |
293 | assertTrue (icompare(ss1, 2, 3, "AAA" ) == 0); |
294 | assertTrue (icompare(ss1, 2, 2, "bb" ) < 0); |
295 | |
296 | assertTrue (icompare(ss1, 2, "aaa" ) > 0); |
297 | } |
298 | |
299 | |
300 | void StringTest::testCILessThan() |
301 | { |
302 | typedef std::map<std::string, int, CILess> CIMapType; |
303 | CIMapType ciMap; |
304 | |
305 | ciMap["z" ] = 1; |
306 | ciMap["b" ] = 2; |
307 | ciMap["A" ] = 3; |
308 | ciMap["Z" ] = 4; |
309 | |
310 | assertTrue (ciMap.size() == 3); |
311 | CIMapType::iterator it = ciMap.begin(); |
312 | assertTrue (it->first == "A" ); ++it; |
313 | assertTrue (it->first == "b" ); ++it; |
314 | assertTrue (it->first == "z" ); |
315 | assertTrue (it->second == 4); |
316 | |
317 | typedef std::set<std::string, CILess> CISetType; |
318 | |
319 | CISetType ciSet; |
320 | ciSet.insert("z" ); |
321 | ciSet.insert("b" ); |
322 | ciSet.insert("A" ); |
323 | ciSet.insert("Z" ); |
324 | |
325 | assertTrue (ciSet.size() == 3); |
326 | CISetType::iterator sIt = ciSet.begin(); |
327 | assertTrue (*sIt == "A" ); ++sIt; |
328 | assertTrue (*sIt == "b" ); ++sIt; |
329 | assertTrue (*sIt == "z" ); |
330 | } |
331 | |
332 | |
333 | void StringTest::testTranslate() |
334 | { |
335 | std::string s = "aabbccdd" ; |
336 | assertTrue (translate(s, "abc" , "ABC" ) == "AABBCCdd" ); |
337 | assertTrue (translate(s, "abc" , "AB" ) == "AABBdd" ); |
338 | assertTrue (translate(s, "abc" , "" ) == "dd" ); |
339 | assertTrue (translate(s, "cba" , "CB" ) == "BBCCdd" ); |
340 | assertTrue (translate(s, "" , "CB" ) == "aabbccdd" ); |
341 | } |
342 | |
343 | |
344 | void StringTest::testTranslateInPlace() |
345 | { |
346 | std::string s = "aabbccdd" ; |
347 | translateInPlace(s, "abc" , "ABC" ); |
348 | assertTrue (s == "AABBCCdd" ); |
349 | } |
350 | |
351 | |
352 | void StringTest::testReplace() |
353 | { |
354 | std::string s("aabbccdd" ); |
355 | |
356 | assertTrue (replace(s, std::string("aa" ), std::string("xx" )) == "xxbbccdd" ); |
357 | assertTrue (replace(s, std::string("bb" ), std::string("xx" )) == "aaxxccdd" ); |
358 | assertTrue (replace(s, std::string("dd" ), std::string("xx" )) == "aabbccxx" ); |
359 | assertTrue (replace(s, std::string("bbcc" ), std::string("xx" )) == "aaxxdd" ); |
360 | assertTrue (replace(s, std::string("b" ), std::string("xx" )) == "aaxxxxccdd" ); |
361 | assertTrue (replace(s, std::string("bb" ), std::string("" )) == "aaccdd" ); |
362 | assertTrue (replace(s, std::string("b" ), std::string("" )) == "aaccdd" ); |
363 | assertTrue (replace(s, std::string("ee" ), std::string("xx" )) == "aabbccdd" ); |
364 | assertTrue (replace(s, std::string("dd" ), std::string("" )) == "aabbcc" ); |
365 | |
366 | assertTrue (replace(s, "aa" , "xx" ) == "xxbbccdd" ); |
367 | assertTrue (replace(s, "bb" , "xx" ) == "aaxxccdd" ); |
368 | assertTrue (replace(s, "dd" , "xx" ) == "aabbccxx" ); |
369 | assertTrue (replace(s, "bbcc" , "xx" ) == "aaxxdd" ); |
370 | assertTrue (replace(s, "bb" , "" ) == "aaccdd" ); |
371 | assertTrue (replace(s, "b" , "" ) == "aaccdd" ); |
372 | assertTrue (replace(s, "ee" , "xx" ) == "aabbccdd" ); |
373 | assertTrue (replace(s, "dd" , "" ) == "aabbcc" ); |
374 | |
375 | s = "aabbaabb" ; |
376 | assertTrue (replace(s, std::string("aa" ), std::string("" )) == "bbbb" ); |
377 | assertTrue (replace(s, std::string("a" ), std::string("" )) == "bbbb" ); |
378 | assertTrue (replace(s, std::string("a" ), std::string("x" )) == "xxbbxxbb" ); |
379 | assertTrue (replace(s, std::string("a" ), std::string("xx" )) == "xxxxbbxxxxbb" ); |
380 | assertTrue (replace(s, std::string("aa" ), std::string("xxx" )) == "xxxbbxxxbb" ); |
381 | |
382 | assertTrue (replace(s, std::string("aa" ), std::string("xx" ), 2) == "aabbxxbb" ); |
383 | |
384 | assertTrue (replace(s, "aa" , "" ) == "bbbb" ); |
385 | assertTrue (replace(s, "a" , "" ) == "bbbb" ); |
386 | assertTrue (replace(s, "a" , "x" ) == "xxbbxxbb" ); |
387 | assertTrue (replace(s, "a" , "xx" ) == "xxxxbbxxxxbb" ); |
388 | assertTrue (replace(s, "aa" , "xxx" ) == "xxxbbxxxbb" ); |
389 | |
390 | assertTrue (replace(s, "aa" , "xx" , 2) == "aabbxxbb" ); |
391 | assertTrue (replace(s, 'a', 'x', 2) == "aabbxxbb" ); |
392 | assertTrue (remove(s, 'a', 2) == "aabbbb" ); |
393 | assertTrue (remove(s, 'a') == "bbbb" ); |
394 | assertTrue (remove(s, 'b', 2) == "aaaa" ); |
395 | } |
396 | |
397 | |
398 | void StringTest::testReplaceInPlace() |
399 | { |
400 | std::string s("aabbccdd" ); |
401 | |
402 | replaceInPlace(s, std::string("aa" ), std::string("xx" )); |
403 | assertTrue (s == "xxbbccdd" ); |
404 | |
405 | s = "aabbccdd" ; |
406 | replaceInPlace(s, 'a', 'x'); |
407 | assertTrue (s == "xxbbccdd" ); |
408 | replaceInPlace(s, 'x'); |
409 | assertTrue (s == "bbccdd" ); |
410 | removeInPlace(s, 'b', 1); |
411 | assertTrue (s == "bccdd" ); |
412 | removeInPlace(s, 'd'); |
413 | assertTrue (s == "bcc" ); |
414 | } |
415 | |
416 | |
417 | void StringTest::testCat() |
418 | { |
419 | std::string s1("one" ); |
420 | std::string s2("two" ); |
421 | std::string s3("three" ); |
422 | std::string s4("four" ); |
423 | std::string s5("five" ); |
424 | std::string s6("six" ); |
425 | |
426 | assertTrue (cat(s1, s2) == "onetwo" ); |
427 | assertTrue (cat(s1, s2, s3) == "onetwothree" ); |
428 | assertTrue (cat(s1, s2, s3, s4) == "onetwothreefour" ); |
429 | assertTrue (cat(s1, s2, s3, s4, s5) == "onetwothreefourfive" ); |
430 | assertTrue (cat(s1, s2, s3, s4, s5, s6) == "onetwothreefourfivesix" ); |
431 | |
432 | std::vector<std::string> vec; |
433 | assertTrue (cat(std::string(), vec.begin(), vec.end()) == "" ); |
434 | assertTrue (cat(std::string("," ), vec.begin(), vec.end()) == "" ); |
435 | vec.push_back(s1); |
436 | assertTrue (cat(std::string("," ), vec.begin(), vec.end()) == "one" ); |
437 | vec.push_back(s2); |
438 | assertTrue (cat(std::string("," ), vec.begin(), vec.end()) == "one,two" ); |
439 | vec.push_back(s3); |
440 | assertTrue (cat(std::string("," ), vec.begin(), vec.end()) == "one,two,three" ); |
441 | } |
442 | |
443 | |
444 | void StringTest::testStartsWith() |
445 | { |
446 | std::string s1("o" ); |
447 | |
448 | assertTrue (startsWith(s1, std::string("o" ))); |
449 | assertTrue (startsWith(s1, std::string("" ))); |
450 | |
451 | assertTrue (!startsWith(s1, std::string("O" ))); |
452 | assertTrue (!startsWith(s1, std::string("1" ))); |
453 | |
454 | std::string s2("" ); |
455 | |
456 | assertTrue (startsWith(s2, std::string("" ))); |
457 | |
458 | assertTrue (!startsWith(s2, std::string("o" ))); |
459 | |
460 | std::string s3("oO" ); |
461 | |
462 | assertTrue (startsWith(s3, std::string("o" ))); |
463 | |
464 | assertTrue (!startsWith(s3, std::string(" o" ))); |
465 | } |
466 | |
467 | |
468 | void StringTest::testEndsWith() |
469 | { |
470 | std::string s1("o" ); |
471 | |
472 | assertTrue (endsWith(s1, std::string("o" ))); |
473 | assertTrue (endsWith(s1, std::string("" ))); |
474 | |
475 | assertTrue (!endsWith(s1, std::string("O" ))); |
476 | assertTrue (!endsWith(s1, std::string("1" ))); |
477 | |
478 | |
479 | std::string s2("" ); |
480 | |
481 | assertTrue (endsWith(s2, std::string("" ))); |
482 | |
483 | assertTrue (!endsWith(s2, std::string("o" ))); |
484 | |
485 | std::string s3("Oo" ); |
486 | |
487 | assertTrue (endsWith(s3, std::string("o" ))); |
488 | |
489 | assertTrue (!endsWith(s3, std::string("o " ))); |
490 | } |
491 | |
492 | |
493 | void StringTest::testStringToInt() |
494 | { |
495 | //gcc on Mac emits warnings that cannot be suppressed |
496 | #ifndef POCO_OS_FAMILY_BSD |
497 | stringToInt<Poco::Int8>(); |
498 | stringToInt<Poco::UInt8>(); |
499 | stringToInt<Poco::Int16>(); |
500 | stringToInt<Poco::UInt16>(); |
501 | #endif |
502 | stringToInt<Poco::Int32>(); |
503 | stringToInt<Poco::UInt32>(); |
504 | #if defined(POCO_HAVE_INT64) |
505 | stringToInt<Poco::Int64>(); |
506 | stringToInt<Poco::UInt64>(); |
507 | #endif |
508 | } |
509 | |
510 | |
511 | void StringTest::testStringToFloat() |
512 | { |
513 | float result; |
514 | std::string sep(".," ); |
515 | |
516 | for (int i = 0; i < 2; ++i) |
517 | { |
518 | char ds = sep[i]; |
519 | for (int j = 0; j < 2; ++j) |
520 | { |
521 | char ts = sep[j]; |
522 | if (ts == ds) continue; |
523 | |
524 | assertTrue (strToFloat("1" , result, ds, ts)); |
525 | assertEqualDelta(1.0, result, 0.01); |
526 | assertTrue (strToFloat(format("%c1" , ds), result, ds, ts)); |
527 | assertEqualDelta(.1, result, 0.01); |
528 | assertTrue (strToFloat(format("1%c" , ds), result, ds, ts)); |
529 | assertEqualDelta(1., result, 0.01); |
530 | assertTrue (strToFloat("0" , result, ds, ts)); |
531 | assertEqualDelta(0.0, result, 0.01); |
532 | assertTrue (strToFloat(format("0%c" , ds), result, ds, ts)); |
533 | assertEqualDelta(0.0, result, 0.01); |
534 | assertTrue (strToFloat(format("%c0" , ds), result, ds, ts)); |
535 | assertEqualDelta(0.0, result, 0.01); |
536 | assertTrue (strToFloat(format("0%c0" , ds), result, ds, ts)); |
537 | assertEqualDelta(0.0, result, 0.01); |
538 | assertTrue (strToFloat(format("0%c0" , ds), result, ds, ts)); |
539 | assertEqualDelta(0., result, 0.01); |
540 | assertTrue (strToFloat(format("0%c0" , ds), result, ds, ts)); |
541 | assertEqualDelta(.0, result, 0.01); |
542 | assertTrue (strToFloat(format("12%c34" , ds), result, ds, ts)); |
543 | assertEqualDelta(12.34, result, 0.01); |
544 | assertTrue (strToFloat(format("12%c34" , ds), result, ds, ts)); |
545 | assertEqualDelta(12.34, result, 0.01); |
546 | assertTrue (strToFloat(format("-12%c34" , ds), result, ds, ts)); |
547 | assertEqualDelta(-12.34, result, 0.01); |
548 | assertTrue (strToFloat(format("%c34" , ds), result, ds, ts)); |
549 | assertEqualDelta(.34, result, 0.01); |
550 | assertTrue (strToFloat(format("-%c34" , ds), result, ds, ts)); |
551 | assertEqualDelta(-.34, result, 0.01); |
552 | assertTrue (strToFloat(format("12%c" , ds), result, ds, ts)); |
553 | assertEqualDelta(12., result, 0.01); |
554 | assertTrue (strToFloat(format("-12%c" , ds), result, ds, ts)); |
555 | assertEqualDelta(-12., result, 0.01); |
556 | assertTrue (strToFloat("12" , result, ds, ts)); |
557 | assertEqualDelta(12, result, 0.01); |
558 | assertTrue (strToFloat("-12" , result, ds, ts)); |
559 | assertEqualDelta(-12, result, 0.01); |
560 | assertTrue (strToFloat(format("12%c34" , ds), result, ds, ts)); |
561 | assertEqualDelta(12.34, result, 0.01); |
562 | |
563 | assertTrue (strToFloat(format("1%c234%c34" , ts, ds), result, ds, ts)); |
564 | assertEqualDelta(1234.34, result, 0.01); |
565 | assertTrue (strToFloat(format("12%c345%c34" , ts, ds), result, ds, ts)); |
566 | assertEqualDelta(12345.34, result, 0.01); |
567 | assertTrue (strToFloat(format("123%c456%c34" , ts, ds), result, ds, ts)); |
568 | assertEqualDelta(123456.34, result, 0.01); |
569 | assertTrue (strToFloat(format("1%c234%c567%c34" , ts, ts, ds), result, ds, ts)); |
570 | |
571 | if ((std::numeric_limits<double>::max() / 10) < 1.23456e10) |
572 | fail ("test value larger than max value for this platform" ); |
573 | else |
574 | { |
575 | float d = 12e34f; |
576 | assertTrue (strToFloat(format("12e34" , ds), result, ds, ts)); |
577 | assertEqualDelta(d, result, 0.01e34); |
578 | |
579 | d = 1.234e30f; |
580 | assertTrue (strToFloat(format("1%c234e30" , ds), result, ds, ts)); |
581 | assertEqualDelta(d, result, 0.01); |
582 | assertTrue (strToFloat(format("1%c234E+30" , ds), result, ds, ts)); |
583 | assertEqualDelta(d, result, 0.01); |
584 | } |
585 | |
586 | float d = 12.34e-10f; |
587 | assertTrue (strToFloat(format("12%c34e-10" , ds), result, ds, ts)); |
588 | assertEqualDelta(d, result, 0.01); |
589 | assertTrue (strToFloat(format("-12%c34" , ds), result, ds, ts)); |
590 | assertEqualDelta(-12.34, result, 0.01); |
591 | |
592 | assertTrue (strToFloat(format(" 12%c34" , ds), result, ds, ts)); |
593 | assertEqualDelta(12.34, result, 0.01); |
594 | assertTrue (strToFloat(format("12%c34 " , ds), result, ds, ts)); |
595 | assertEqualDelta(12.34, result, 0.01); |
596 | assertTrue (strToFloat(format(" 12%c34 " , ds), result, ds, ts)); |
597 | assertEqualDelta(12.34, result, 0.01); |
598 | } |
599 | } |
600 | |
601 | assertTrue (std::isnan(strToFloat("nan" ))); |
602 | assertTrue (std::isnan(strToFloat("xNaNy" ))); |
603 | assertTrue (!std::isnan(strToFloat("inf" ))); |
604 | assertTrue (!std::isnan(strToFloat("-inf" ))); |
605 | assertTrue (std::isnan(strToFloat("infinity" ))); |
606 | assertTrue (!std::isnan(strToFloat("infinity" , "infinity" ))); |
607 | assertTrue (!std::isnan(strToFloat("-infinity" , "infinity" ))); |
608 | assertTrue (std::isnan(strToFloat("Inf" ))); |
609 | assertTrue (!std::isnan(strToFloat("Inf" , "Inf" ))); |
610 | |
611 | assertTrue (std::isinf(strToFloat("inf" ))); |
612 | assertTrue (std::isinf(strToFloat("-inf" ))); |
613 | assertTrue (std::isinf(strToFloat("infinity" , "infinity" ))); |
614 | assertTrue (std::isinf(strToFloat("-infinity" , "infinity" ))); |
615 | assertTrue (!std::isinf(strToFloat("Inf" ))); |
616 | assertTrue (std::isinf(strToFloat("Inf" , "Inf" ))); |
617 | |
618 | assertTrue (FPEnvironment::isNaN(strToFloat("nan" ))); |
619 | assertTrue (FPEnvironment::isNaN(strToFloat("xNaNy" ))); |
620 | assertTrue (!FPEnvironment::isNaN(strToFloat("inf" ))); |
621 | assertTrue (!FPEnvironment::isNaN(strToFloat("-inf" ))); |
622 | assertTrue (FPEnvironment::isNaN(strToFloat("infinity" ))); |
623 | assertTrue (!FPEnvironment::isNaN(strToFloat("infinity" , "infinity" ))); |
624 | assertTrue (!FPEnvironment::isNaN(strToFloat("-infinity" , "infinity" ))); |
625 | assertTrue (!FPEnvironment::isNaN(strToFloat("1.23" ))); |
626 | assertTrue (FPEnvironment::isNaN(strToFloat("Inf" ))); |
627 | assertTrue (!FPEnvironment::isNaN(strToFloat("Inf" , "Inf" ))); |
628 | |
629 | assertTrue (FPEnvironment::isInfinite(strToFloat("inf" ))); |
630 | assertTrue (FPEnvironment::isInfinite(strToFloat("-inf" ))); |
631 | assertTrue (FPEnvironment::isInfinite(strToFloat("infinity" , "infinity" ))); |
632 | assertTrue (FPEnvironment::isInfinite(strToFloat("-infinity" , "infinity" ))); |
633 | assertTrue (!FPEnvironment::isInfinite(strToFloat("1.23" ))); |
634 | assertTrue (!FPEnvironment::isInfinite(strToFloat("abc" ))); |
635 | assertTrue (FPEnvironment::isInfinite(strToFloat("Inf" , "Inf" ))); |
636 | } |
637 | |
638 | |
639 | void StringTest::testStringToDouble() |
640 | { |
641 | double result; |
642 | std::string sep(".," ); |
643 | |
644 | for (int i = 0; i < 2; ++i) |
645 | { |
646 | char ds = sep[i]; |
647 | for (int j = 0; j < 2; ++j) |
648 | { |
649 | char ts = sep[j]; |
650 | if (ts == ds) continue; |
651 | |
652 | assertTrue (strToDouble("1" , result, ds, ts)); |
653 | assertEqualDelta(1.0, result, 0.01); |
654 | assertTrue (strToDouble(format("%c1" , ds), result, ds, ts)); |
655 | assertEqualDelta(.1, result, 0.01); |
656 | assertTrue (strToDouble(format("1%c" , ds), result, ds, ts)); |
657 | assertEqualDelta(1., result, 0.01); |
658 | assertTrue (strToDouble("0" , result, ds, ts)); |
659 | assertEqualDelta(0.0, result, 0.01); |
660 | assertTrue (strToDouble(format("0%c" , ds), result, ds, ts)); |
661 | assertEqualDelta(0.0, result, 0.01); |
662 | assertTrue (strToDouble(format("%c0" , ds), result, ds, ts)); |
663 | assertEqualDelta(0.0, result, 0.01); |
664 | assertTrue (strToDouble(format("0%c0" , ds), result, ds, ts)); |
665 | assertEqualDelta(0.0, result, 0.01); |
666 | assertTrue (strToDouble(format("0%c0" , ds), result, ds, ts)); |
667 | assertEqualDelta(0., result, 0.01); |
668 | assertTrue (strToDouble(format("0%c0" , ds), result, ds, ts)); |
669 | assertEqualDelta(.0, result, 0.01); |
670 | assertTrue (strToDouble(format("12%c34" , ds), result, ds, ts)); |
671 | assertEqualDelta(12.34, result, 0.01); |
672 | assertTrue (strToDouble(format("12%c34" , ds), result, ds, ts)); |
673 | assertEqualDelta(12.34, result, 0.01); |
674 | assertTrue (strToDouble(format("-12%c34" , ds), result, ds, ts)); |
675 | assertEqualDelta(-12.34, result, 0.01); |
676 | assertTrue (strToDouble(format("%c34" , ds), result, ds, ts)); |
677 | assertEqualDelta(.34, result, 0.01); |
678 | assertTrue (strToDouble(format("-%c34" , ds), result, ds, ts)); |
679 | assertEqualDelta(-.34, result, 0.01); |
680 | assertTrue (strToDouble(format("12%c" , ds), result, ds, ts)); |
681 | assertEqualDelta(12., result, 0.01); |
682 | assertTrue (strToDouble(format("-12%c" , ds), result, ds, ts)); |
683 | assertEqualDelta(-12., result, 0.01); |
684 | assertTrue (strToDouble("12" , result, ds, ts)); |
685 | assertEqualDelta(12, result, 0.01); |
686 | assertTrue (strToDouble("-12" , result, ds, ts)); |
687 | assertEqualDelta(-12, result, 0.01); |
688 | assertTrue (strToDouble(format("12%c3456789012345678901234567890" , ds), result, ds, ts)); |
689 | assertEqualDelta(12.34, result, 0.01); |
690 | |
691 | assertTrue (strToDouble("1234345" , result, ds, ts)); |
692 | assertEqualDelta(1234345, result, 0.00000001); |
693 | assertTrue (strToDouble(format("1%c234%c345" , ts, ts), result, ds, ts)); |
694 | assertEqualDelta(1234345, result, 0.00000001); |
695 | assertTrue (strToDouble(format("1%c234%c3456789012345678901234567890" , ts, ds), result, ds, ts)); |
696 | assertEqualDelta(1234.3456789, result, 0.00000001); |
697 | assertTrue (strToDouble(format("12%c345%c3456789012345678901234567890" , ts, ds), result, ds, ts)); |
698 | assertEqualDelta(12345.3456789, result, 0.00000001); |
699 | assertTrue (strToDouble(format("123%c456%c3456789012345678901234567890" , ts, ds), result, ds, ts)); |
700 | assertEqualDelta(123456.3456789, result, 0.00000001); |
701 | assertTrue (strToDouble(format("1%c234%c567%c3456789012345678901234567890" , ts, ts, ds), result, ds, ts)); |
702 | assertEqualDelta(1234567.3456789, result, 0.00000001); |
703 | assertTrue (strToDouble(format("12%c345%c678%c3456789012345678901234567890" , ts, ts, ds), result, ds, ts)); |
704 | assertEqualDelta(12345678.3456789, result, 0.00000001); |
705 | assertTrue (strToDouble(format("123%c456%c789%c3456789012345678901234567890" , ts, ts, ds), result, ds, ts)); |
706 | assertEqualDelta(123456789.3456789, result, 0.00000001); |
707 | |
708 | if ((std::numeric_limits<double>::max() / 10) < 1.23456e10) |
709 | fail ("test value larger than max value for this platform" ); |
710 | else |
711 | { |
712 | double d = 12e34; |
713 | assertTrue (strToDouble(format("12e34" , ds), result, ds, ts)); |
714 | assertEqualDelta(d, result, 0.01e34); |
715 | |
716 | d = 1.234e100; |
717 | assertTrue (strToDouble(format("1%c234e100" , ds), result, ds, ts)); |
718 | assertEqualDelta(d, result, 0.01); |
719 | assertTrue (strToDouble(format("1%c234E+100" , ds), result, ds, ts)); |
720 | assertEqualDelta(d, result, 0.01); |
721 | |
722 | d = 1.234e-100; |
723 | assertTrue (strToDouble(format("1%c234E-100" , ds), result, ds, ts)); |
724 | assertEqualDelta(d, result, 0.01); |
725 | |
726 | d = -1.234e100; |
727 | assertTrue (strToDouble(format("-1%c234e+100" , ds), result, ds, ts)); |
728 | assertEqualDelta(d, result, 0.01); |
729 | assertTrue (strToDouble(format("-1%c234E100" , ds), result, ds, ts)); |
730 | assertEqualDelta(d, result, 0.01); |
731 | |
732 | d = 1.234e-100; |
733 | assertTrue (strToDouble(format(" 1%c234e-100 " , ds), result, ds, ts)); |
734 | assertEqualDelta(d, result, 0.01); |
735 | assertTrue (strToDouble(format(" 1%c234e-100 " , ds), result, ds, ts)); |
736 | assertEqualDelta(d, result, 0.01); |
737 | assertTrue (strToDouble(format(" 1%c234e-100 " , ds), result, ds, ts)); |
738 | assertEqualDelta(d, result, 0.01); |
739 | |
740 | d = 1234.234e-100; |
741 | assertTrue (strToDouble(format(" 1%c234%c234e-100 " , ts, ds), result, ds, ts)); |
742 | assertEqualDelta(d, result, 0.01); |
743 | d = 12345.234e-100; |
744 | assertTrue (strToDouble(format(" 12%c345%c234e-100 " , ts, ds), result, ds, ts)); |
745 | assertEqualDelta(d, result, 0.01); |
746 | d = 123456.234e-100; |
747 | assertTrue (strToDouble(format(" 123%c456%c234e-100 " , ts, ds), result, ds, ts)); |
748 | assertEqualDelta(d, result, 0.01); |
749 | |
750 | d = -1234.234e-100; |
751 | assertTrue (strToDouble(format(" -1%c234%c234e-100 " , ts, ds), result, ds, ts)); |
752 | assertEqualDelta(d, result, 0.01); |
753 | d = -12345.234e-100; |
754 | assertTrue (strToDouble(format(" -12%c345%c234e-100 " , ts, ds), result, ds, ts)); |
755 | assertEqualDelta(d, result, 0.01); |
756 | d = -123456.234e-100; |
757 | char ou = 0; |
758 | assertTrue (strToDouble(format(" -123%c456%c234e-100 " , ts, ds), result, ds, ts)); |
759 | assertEqualDelta(d, result, 0.01); |
760 | assertTrue (ou == 0); |
761 | } |
762 | |
763 | double d = 12.34e-10; |
764 | assertTrue (strToDouble(format("12%c34e-10" , ds), result, ds, ts)); |
765 | assertEqualDelta(d, result, 0.01); |
766 | assertTrue (strToDouble(format("-12%c34" , ds), result, ds, ts)); |
767 | assertEqualDelta(-12.34, result, 0.01); |
768 | |
769 | assertTrue (strToDouble(format(" 12%c34" , ds), result, ds, ts)); |
770 | assertEqualDelta(12.34, result, 0.01); |
771 | assertTrue (strToDouble(format("12%c34 " , ds), result, ds, ts)); |
772 | assertEqualDelta(12.34, result, 0.01); |
773 | assertTrue (strToDouble(format(" 12%c34 " , ds), result, ds, ts)); |
774 | assertEqualDelta(12.34, result, 0.01); |
775 | } |
776 | } |
777 | |
778 | assertTrue (std::isnan(strToDouble("nan" ))); |
779 | assertTrue (std::isnan(strToDouble("xNaNy" ))); |
780 | assertTrue (!std::isnan(strToDouble("inf" ))); |
781 | assertTrue (!std::isnan(strToDouble("-inf" ))); |
782 | assertTrue (std::isnan(strToDouble("infinity" ))); |
783 | assertTrue (!std::isnan(strToDouble("infinity" , "infinity" ))); |
784 | assertTrue (!std::isnan(strToDouble("-infinity" , "infinity" ))); |
785 | assertTrue (std::isnan(strToDouble("Inf" ))); |
786 | assertTrue (!std::isnan(strToDouble("Inf" , "Inf" ))); |
787 | |
788 | assertTrue (std::isinf(strToDouble("inf" ))); |
789 | assertTrue (std::isinf(strToDouble("-inf" ))); |
790 | assertTrue (std::isinf(strToDouble("infinity" , "infinity" ))); |
791 | assertTrue (std::isinf(strToDouble("-infinity" , "infinity" ))); |
792 | assertTrue (!std::isinf(strToDouble("Inf" ))); |
793 | assertTrue (std::isinf(strToDouble("Inf" , "Inf" ))); |
794 | |
795 | assertTrue (FPEnvironment::isNaN(strToDouble("nan" ))); |
796 | assertTrue (FPEnvironment::isNaN(strToDouble("xNaNy" ))); |
797 | assertTrue (!FPEnvironment::isNaN(strToDouble("inf" ))); |
798 | assertTrue (!FPEnvironment::isNaN(strToDouble("-inf" ))); |
799 | assertTrue (FPEnvironment::isNaN(strToDouble("infinity" ))); |
800 | assertTrue (!FPEnvironment::isNaN(strToDouble("infinity" , "infinity" ))); |
801 | assertTrue (!FPEnvironment::isNaN(strToDouble("-infinity" , "infinity" ))); |
802 | assertTrue (!FPEnvironment::isNaN(strToDouble("1.23" ))); |
803 | assertTrue (FPEnvironment::isNaN(strToDouble("Inf" ))); |
804 | assertTrue (!FPEnvironment::isNaN(strToDouble("Inf" , "Inf" ))); |
805 | |
806 | assertTrue (FPEnvironment::isInfinite(strToDouble("inf" ))); |
807 | assertTrue (FPEnvironment::isInfinite(strToDouble("-inf" ))); |
808 | assertTrue (FPEnvironment::isInfinite(strToDouble("infinity" , "infinity" ))); |
809 | assertTrue (FPEnvironment::isInfinite(strToDouble("-infinity" , "infinity" ))); |
810 | assertTrue (!FPEnvironment::isInfinite(strToDouble("1.23" ))); |
811 | assertTrue (!FPEnvironment::isInfinite(strToDouble("abc" ))); |
812 | assertTrue (FPEnvironment::isInfinite(strToDouble("Inf" , "Inf" ))); |
813 | } |
814 | |
815 | |
816 | void StringTest::testNumericStringPadding() |
817 | { |
818 | std::string str; |
819 | assertTrue (floatToStr(str, 0.999f, 2, 4) == "1.00" ); |
820 | assertTrue (floatToStr(str, 0.945f, 2, 4) == "0.95" ); |
821 | assertTrue (floatToStr(str, 0.944f, 2, 4) == "0.94" ); |
822 | assertTrue (floatToStr(str, 12.45f, 2, 5) == "12.45" ); |
823 | assertTrue (floatToStr(str, 12.45f, 1, 4) == "12.5" ); |
824 | assertTrue (floatToStr(str, 12.45f, 2, 6) == " 12.45" ); |
825 | assertTrue (floatToStr(str, 12.455f, 3, 7) == " 12.455" ); |
826 | assertTrue (floatToStr(str, 12.455f, 2, 6) == " 12.46" ); |
827 | assertTrue (floatToStr(str, 1.23556E-16f, 2, 6) == "1.24e-16" ); |
828 | |
829 | assertTrue (doubleToStr(str, 0.999, 2, 4) == "1.00" ); |
830 | assertTrue (doubleToStr(str, 0.945, 2, 4) == "0.95" ); |
831 | assertTrue (doubleToStr(str, 0.944, 2, 4) == "0.94" ); |
832 | assertTrue (doubleToStr(str, 12.45, 2, 5) == "12.45" ); |
833 | assertTrue (doubleToStr(str, 12.45, 1, 4) == "12.5" ); |
834 | assertTrue (doubleToStr(str, 12.45, 2, 6) == " 12.45" ); |
835 | assertTrue (doubleToStr(str, 12.455, 3, 7) == " 12.455" ); |
836 | assertTrue (doubleToStr(str, 12.455, 2, 6) == " 12.46" ); |
837 | assertTrue (doubleToStr(str, 1.23556E-16, 2, 6) == "1.24e-16" ); |
838 | } |
839 | |
840 | void StringTest::testStringToFloatError() |
841 | { |
842 | char ds = decimalSeparator(); |
843 | if (ds == 0) ds = '.'; |
844 | char ts = thousandSeparator(); |
845 | if (ts == 0) ts = ','; |
846 | assertTrue (ds != ts); |
847 | |
848 | double result = 0.0; |
849 | assertTrue (!strToDouble(format("a12%c3" , ds), result)); |
850 | assertTrue (!strToDouble(format("1b2%c3" , ds), result)); |
851 | assertTrue (!strToDouble(format("12c%c3" , ds), result)); |
852 | assertTrue (!strToDouble(format("12%cx3" , ds), result)); |
853 | |
854 | assertTrue (!strToDouble(format("123%c456%c234e1000000" , ts, ds), result)); |
855 | assertTrue (!strToDouble(format("123%c456%c234e+1000000" , ts, ds), result)); |
856 | //assertTrue (!strToDouble(0, result, ou)); // strToDouble is resilient to null pointers |
857 | assertTrue (!strToDouble("" , result)); |
858 | } |
859 | |
860 | |
861 | void StringTest::testNumericLocale() |
862 | { |
863 | #if !defined(POCO_NO_LOCALE) && POCO_OS == POCO_OS_WINDOWS_NT |
864 | try |
865 | { |
866 | char buffer[POCO_MAX_FLT_STRING_LEN]; |
867 | |
868 | char dp = decimalSeparator(); |
869 | char ts = thousandSeparator(); |
870 | std::locale loc; |
871 | std::cout << "Original locale: '" << loc.name() << '\'' << std::endl; |
872 | std::cout << "Decimal point: '" << decimalSeparator() << '\'' << std::endl; |
873 | std::cout << "Thousand separator: '" << ts << '\'' << std::endl; |
874 | doubleToStr(buffer, POCO_MAX_FLT_STRING_LEN, 1.23); |
875 | assertTrue (std::strncmp(buffer, "1.23" , 4) == 0); |
876 | std::cout << "1.23 == '" << buffer << '\'' << std::endl; |
877 | |
878 | std::locale::global(std::locale("German" )); |
879 | std::locale locGerman; |
880 | assertTrue (',' == decimalSeparator()); |
881 | assertTrue ('.' == thousandSeparator()); |
882 | std::cout << "New locale: '" << locGerman.name() << '\'' << std::endl; |
883 | std::cout << "Decimal point: '" << decimalSeparator() << '\'' << std::endl; |
884 | std::cout << "Thousand separator: '" << thousandSeparator() << '\'' << std::endl; |
885 | doubleToStr(buffer, POCO_MAX_FLT_STRING_LEN, 1.23); |
886 | assertTrue (std::strncmp(buffer, "1.23" , 4) == 0); |
887 | std::cout << "1.23 == '" << buffer << '\'' << std::endl; |
888 | |
889 | std::locale::global(std::locale("US" )); |
890 | std::locale locUS; |
891 | assertTrue ('.' == decimalSeparator()); |
892 | assertTrue (',' == thousandSeparator()); |
893 | std::cout << "New locale: '" << locUS.name() << '\'' << std::endl; |
894 | std::cout << "Decimal point: '" << decimalSeparator() << '\'' << std::endl; |
895 | std::cout << "Thousand separator: '" << thousandSeparator() << '\'' << std::endl; |
896 | doubleToStr(buffer, POCO_MAX_FLT_STRING_LEN, 1.23); |
897 | assertTrue (std::strncmp(buffer, "1.23" , 4) == 0); |
898 | std::cout << "1.23 == '" << buffer << '\'' << std::endl; |
899 | |
900 | std::locale::global(loc); |
901 | dp = decimalSeparator(); |
902 | ts = thousandSeparator(); |
903 | std::cout << "Final locale: '" << loc.name() << '\'' << std::endl; |
904 | std::cout << "Decimal point: '" << decimalSeparator() << '\'' << std::endl; |
905 | std::cout << "Thousand separator: '" << thousandSeparator() << '\'' << std::endl; |
906 | doubleToStr(buffer, POCO_MAX_FLT_STRING_LEN, 1.23); |
907 | assertTrue (std::strncmp(buffer, "1.23" , 4) == 0); |
908 | std::cout << "1.23 == '" << buffer << '\'' << std::endl; |
909 | |
910 | assertTrue (dp == decimalSeparator()); |
911 | assertTrue (ts == thousandSeparator()); |
912 | } catch (std::runtime_error& ex) |
913 | { |
914 | std::cout << ex.what() << std::endl; |
915 | warnmsg ("Locale not found, skipping test" ); |
916 | } |
917 | #endif |
918 | } |
919 | |
920 | |
921 | void StringTest::benchmarkStrToInt() |
922 | { |
923 | Poco::Stopwatch sw; |
924 | std::string num = "123456789" ; |
925 | int res; |
926 | sw.start(); |
927 | for (int i = 0; i < 1000000; ++i) parseStream(num, res); |
928 | sw.stop(); |
929 | std::cout << "parseStream Number: " << res << std::endl; |
930 | double timeStream = sw.elapsed() / 1000.0; |
931 | |
932 | char* pC = 0; |
933 | sw.restart(); |
934 | for (int i = 0; i < 1000000; ++i) res = std::strtol(num.c_str(), &pC, 10); |
935 | sw.stop(); |
936 | std::cout << "std::strtol Number: " << res << std::endl; |
937 | double timeStrtol = sw.elapsed() / 1000.0; |
938 | |
939 | sw.restart(); |
940 | for (int i = 0; i < 1000000; ++i) strToInt(num.c_str(), res, 10); |
941 | sw.stop(); |
942 | std::cout << "strToInt Number: " << res << std::endl; |
943 | double timeStrToInt = sw.elapsed() / 1000.0; |
944 | |
945 | sw.restart(); |
946 | for (int i = 0; i < 1000000; ++i) std::sscanf(num.c_str(), "%d" , &res); |
947 | sw.stop(); |
948 | std::cout << "sscanf Number: " << res << std::endl; |
949 | double timeScanf = sw.elapsed() / 1000.0; |
950 | |
951 | int graph; |
952 | std::cout << std::endl << "Timing and speedup relative to I/O stream:" << std::endl << std::endl; |
953 | std::cout << std::setw(14) << "Stream:\t" << std::setw(10) << std::setfill(' ') << timeStream << "[ms]" << std::endl; |
954 | |
955 | std::cout << std::setw(14) << "std::strtol:\t" << std::setw(10) << std::setfill(' ') << timeStrtol << "[ms]" << |
956 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeStrtol) << '\t' ; |
957 | graph = (int) (timeStream / timeStrtol); for (int i = 0; i < graph; ++i) std::cout << '|'; |
958 | |
959 | std::cout << std::endl << std::setw(14) << "strToInt:\t" << std::setw(10) << std::setfill(' ') << timeStrToInt << "[ms]" << |
960 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeStrToInt) << '\t' ; |
961 | graph = (int) (timeStream / timeStrToInt); for (int i = 0; i < graph; ++i) std::cout << '|'; |
962 | |
963 | std::cout << std::endl << std::setw(14) << "std::sscanf:\t" << std::setw(10) << std::setfill(' ') << timeScanf << "[ms]" << |
964 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeScanf) << '\t' ; |
965 | graph = (int) (timeStream / timeScanf); for (int i = 0; i < graph; ++i) std::cout << '|'; |
966 | std::cout << std::endl; |
967 | } |
968 | |
969 | |
970 | void StringTest::benchmarkStrToFloat() |
971 | { |
972 | Poco::Stopwatch sw; |
973 | std::string num = "1.0372157551632929e-112" ; |
974 | std::cout << "The Number: " << num << std::endl; |
975 | double res; |
976 | sw.start(); |
977 | for (int i = 0; i < 1000000; ++i) parseStream(num, res); |
978 | sw.stop(); |
979 | std::cout << "parseStream Number: " << std::setprecision(std::numeric_limits<double>::digits10) << res << std::endl; |
980 | double timeStream = sw.elapsed() / 1000.0; |
981 | |
982 | // standard strtod |
983 | char* pC = 0; |
984 | sw.restart(); |
985 | for (int i = 0; i < 1000000; ++i) res = std::strtod(num.c_str(), &pC); |
986 | sw.stop(); |
987 | std::cout << "std::strtod Number: " << res << std::endl; |
988 | double timeStdStrtod = sw.elapsed() / 1000.0; |
989 | |
990 | // POCO Way |
991 | sw.restart(); |
992 | char ou = 0; |
993 | for (int i = 0; i < 1000000; ++i) strToDouble(num, res, ou); |
994 | sw.stop(); |
995 | std::cout << "strToDouble Number: " << res << std::endl; |
996 | double timeStrToDouble = sw.elapsed() / 1000.0; |
997 | |
998 | // standard sscanf |
999 | sw.restart(); |
1000 | for (int i = 0; i < 1000000; ++i) std::sscanf(num.c_str(), "%lf" , &res); |
1001 | sw.stop(); |
1002 | std::cout << "sscanf Number: " << res << std::endl; |
1003 | double timeScanf = sw.elapsed() / 1000.0; |
1004 | |
1005 | // double-conversion Strtod |
1006 | sw.restart(); |
1007 | for (int i = 0; i < 1000000; ++i) strToDouble(num.c_str()); |
1008 | sw.stop(); |
1009 | std::cout << "Strtod Number: " << res << std::endl; |
1010 | double timeStrtod = sw.elapsed() / 1000.0; |
1011 | |
1012 | int graph; |
1013 | std::cout << std::endl << "Timing and speedup relative to I/O stream:" << std::endl << std::endl; |
1014 | std::cout << std::setw(14) << "Stream:\t" << std::setw(10) << std::setfill(' ') << std::setprecision(4) << timeStream << "[ms]" << std::endl; |
1015 | |
1016 | std::cout << std::setw(14) << "std::strtod:\t" << std::setw(10) << std::setfill(' ') << timeStdStrtod << "[ms]" << |
1017 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeStdStrtod) << '\t' ; |
1018 | graph = (int) (timeStream / timeStdStrtod); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1019 | |
1020 | std::cout << std::endl << std::setw(14) << "strToDouble:\t" << std::setw(10) << std::setfill(' ') << timeStrToDouble << "[ms]" << |
1021 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeStrToDouble) << '\t' ; |
1022 | graph = (int) (timeStream / timeStrToDouble); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1023 | |
1024 | std::cout << std::endl << std::setw(14) << "std::sscanf:\t" << std::setw(10) << std::setfill(' ') << timeScanf << "[ms]" << |
1025 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeScanf) << '\t' ; |
1026 | graph = (int) (timeStream / timeScanf); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1027 | |
1028 | std::cout << std::endl << std::setw(14) << "StrtoD:\t" << std::setw(10) << std::setfill(' ') << timeScanf << "[ms]" << |
1029 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeStrtod) << '\t' ; |
1030 | graph = (int) (timeStream / timeStrtod); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1031 | |
1032 | std::cout << std::endl; |
1033 | } |
1034 | |
1035 | |
1036 | void StringTest::testIntToString() |
1037 | { |
1038 | //intToStr(T number, unsigned short base, std::string& result, bool prefix = false, int width = -1, char fill = ' ', char thSep = 0) |
1039 | |
1040 | // decimal |
1041 | std::string result; |
1042 | result = intToStr(0, 10); |
1043 | assertTrue (result == "0" ); |
1044 | result.clear(); |
1045 | result = intToStr(0, 10, false, 10, '0'); |
1046 | assertTrue (result == "0000000000" ); |
1047 | result.clear(); |
1048 | result = intToStr(1234567890, 10); |
1049 | assertTrue (result == "1234567890" ); |
1050 | result.clear(); |
1051 | result = intToStr(-1234567890, 10); |
1052 | assertTrue (result == "-1234567890" ); |
1053 | result.clear(); |
1054 | result = intToStr(-1234567890, 10, false, 15, '0'); |
1055 | assertTrue (result == "-00001234567890" ); |
1056 | result.clear(); |
1057 | result = intToStr(-1234567890, 10, false, 15); |
1058 | assertTrue (result == " -1234567890" ); |
1059 | result.clear(); |
1060 | result = intToStr(-1234567890, 10, false, 0, 0, ','); |
1061 | assertTrue (result == "-1,234,567,890" ); |
1062 | result.clear(); |
1063 | |
1064 | // binary |
1065 | result = intToStr(1234567890, 2); |
1066 | assertTrue (result == "1001001100101100000001011010010" ); |
1067 | result.clear(); |
1068 | result = intToStr(1234567890, 2, true); |
1069 | assertTrue (result == "1001001100101100000001011010010" ); |
1070 | result.clear(); |
1071 | result = intToStr(1234567890, 2, true, 35, '0'); |
1072 | assertTrue (result == "00001001001100101100000001011010010" ); |
1073 | result.clear(); |
1074 | result = uIntToStr(0xFF, 2); |
1075 | assertTrue (result == "11111111" ); |
1076 | result.clear(); |
1077 | result = uIntToStr(0x0F, 2, false, 8, '0'); |
1078 | assertTrue (result == "00001111" ); |
1079 | result.clear(); |
1080 | result = uIntToStr(0x0F, 2); |
1081 | assertTrue (result == "1111" ); |
1082 | result.clear(); |
1083 | result = uIntToStr(0xF0, 2); |
1084 | assertTrue (result == "11110000" ); |
1085 | result.clear(); |
1086 | result = uIntToStr(0xFFFF, 2); |
1087 | assertTrue (result == "1111111111111111" ); |
1088 | result.clear(); |
1089 | result = uIntToStr(0xFF00, 2); |
1090 | assertTrue (result == "1111111100000000" ); |
1091 | result.clear(); |
1092 | result = uIntToStr(0xFFFFFFFF, 2); |
1093 | assertTrue (result == "11111111111111111111111111111111" ); |
1094 | result.clear(); |
1095 | result = uIntToStr(0xFF00FF00, 2); |
1096 | assertTrue (result == "11111111000000001111111100000000" ); |
1097 | result.clear(); |
1098 | result = uIntToStr(0xF0F0F0F0, 2); |
1099 | assertTrue (result == "11110000111100001111000011110000" ); |
1100 | result.clear(); |
1101 | #if defined(POCO_HAVE_INT64) |
1102 | result = uIntToStr(0xFFFFFFFFFFFFFFFF, 2); |
1103 | assertTrue (result == "1111111111111111111111111111111111111111111111111111111111111111" ); |
1104 | result.clear(); |
1105 | result = uIntToStr(0xFF00000FF00000FF, 2); |
1106 | assertTrue (result == "1111111100000000000000000000111111110000000000000000000011111111" ); |
1107 | result.clear(); |
1108 | #endif |
1109 | |
1110 | // octal |
1111 | result = uIntToStr(1234567890, 010); |
1112 | assertTrue (result == "11145401322" ); |
1113 | result.clear(); |
1114 | result = uIntToStr(1234567890, 010, true); |
1115 | assertTrue (result == "011145401322" ); |
1116 | result.clear(); |
1117 | result = uIntToStr(1234567890, 010, true, 15, '0'); |
1118 | assertTrue (result == "000011145401322" ); |
1119 | result.clear(); |
1120 | result = uIntToStr(012345670, 010, true); |
1121 | assertTrue (result == "012345670" ); |
1122 | result.clear(); |
1123 | result = uIntToStr(012345670, 010); |
1124 | assertTrue (result == "12345670" ); |
1125 | result.clear(); |
1126 | |
1127 | // hexadecimal |
1128 | result = uIntToStr(0, 0x10, true); |
1129 | assertTrue (result == "0x0" ); |
1130 | result.clear(); |
1131 | result = uIntToStr(0, 0x10, true, 4, '0'); |
1132 | assertTrue (result == "0x00" ); |
1133 | result.clear(); |
1134 | result = uIntToStr(0, 0x10, false, 4, '0'); |
1135 | assertTrue (result == "0000" ); |
1136 | result.clear(); |
1137 | result = uIntToStr(1234567890, 0x10); |
1138 | assertTrue (result == "499602D2" ); |
1139 | result.clear(); |
1140 | result = uIntToStr(1234567890, 0x10, true); |
1141 | assertTrue (result == "0x499602D2" ); |
1142 | result.clear(); |
1143 | result = uIntToStr(1234567890, 0x10, true, 15, '0'); |
1144 | assertTrue (result == "0x00000499602D2" ); |
1145 | result.clear(); |
1146 | result = uIntToStr(0x1234567890ABCDEF, 0x10, true); |
1147 | assertTrue (result == "0x1234567890ABCDEF" ); |
1148 | result.clear(); |
1149 | result = uIntToStr(0xDEADBEEF, 0x10); |
1150 | assertTrue (result == "DEADBEEF" ); |
1151 | result.clear(); |
1152 | #if defined(POCO_HAVE_INT64) |
1153 | result = uIntToStr(0xFFFFFFFFFFFFFFFF, 0x10); |
1154 | assertTrue (result == "FFFFFFFFFFFFFFFF" ); |
1155 | result.clear(); |
1156 | result = uIntToStr(0xFFFFFFFFFFFFFFFF, 0x10, true); |
1157 | assertTrue (result == "0xFFFFFFFFFFFFFFFF" ); |
1158 | result.clear(); |
1159 | #endif |
1160 | |
1161 | try |
1162 | { |
1163 | char pResult[POCO_MAX_INT_STRING_LEN]; |
1164 | std::size_t sz = POCO_MAX_INT_STRING_LEN; |
1165 | intToStr(0, 10, pResult, sz, false, (int) sz + 1, ' '); |
1166 | fail ("must throw RangeException" ); |
1167 | } catch (RangeException&) { } |
1168 | } |
1169 | |
1170 | |
1171 | void StringTest::testFloatToString() |
1172 | { |
1173 | double val = 1.03721575516329e-112; |
1174 | std::string str; |
1175 | |
1176 | assertTrue (doubleToStr(str, val, 14, 21) == "1.03721575516329e-112" ); |
1177 | assertTrue (doubleToStr(str, val, 14, 22) == " 1.03721575516329e-112" ); |
1178 | val = -val; |
1179 | assertTrue (doubleToStr(str, val, 14, 22) == "-1.03721575516329e-112" ); |
1180 | assertTrue (doubleToStr(str, val, 14, 23) == " -1.03721575516329e-112" ); |
1181 | |
1182 | val = -10372157551632.9; |
1183 | assertTrue (doubleToStr(str, val, 1, 21, ',') == "-10,372,157,551,632.9" ); |
1184 | assertTrue (doubleToStr(str, val, 1, 22, ',') == " -10,372,157,551,632.9" ); |
1185 | assertTrue (doubleToStr(str, val, 2, 22, ',') == "-10,372,157,551,632.90" ); |
1186 | assertTrue (doubleToStr(str, val, 2, 22, '.', ',') == "-10.372.157.551.632,90" ); |
1187 | assertTrue (doubleToStr(str, val, 2, 22, ' ', ',') == "-10 372 157 551 632,90" ); |
1188 | |
1189 | int ival = 1234567890; |
1190 | assertTrue (doubleToStr(str, ival, 1, 15, ',') == "1,234,567,890.0" ); |
1191 | ival = -123456789; |
1192 | assertTrue (doubleToStr(str, ival, 1, 14, ',') == "-123,456,789.0" ); |
1193 | } |
1194 | |
1195 | |
1196 | void StringTest::testNumericStringLimit() |
1197 | { |
1198 | char c = 0, t = -1; |
1199 | assertTrue(!isIntOverflow<char>(c)); |
1200 | assertTrue(safeIntCast<char>(c, t) == c); |
1201 | assertTrue(t == c); |
1202 | |
1203 | short s = SHRT_MAX; |
1204 | assertTrue(isIntOverflow<char>(s)); |
1205 | try |
1206 | { |
1207 | safeIntCast(s, t); |
1208 | fail("cast must fail" ); |
1209 | } |
1210 | catch(Poco::BadCastException&){} |
1211 | |
1212 | s = SHRT_MIN; |
1213 | assertTrue(isIntOverflow<char>(s)); |
1214 | try |
1215 | { |
1216 | safeIntCast(s, t); |
1217 | fail("short => char cast must fail" ); |
1218 | } |
1219 | catch(Poco::BadCastException&){} |
1220 | |
1221 | signed char sc = 0, st = -1; |
1222 | assertTrue(!isIntOverflow<signed char>(sc)); |
1223 | assertTrue(safeIntCast<char>(sc, st) == sc); |
1224 | assertTrue(st == sc); |
1225 | |
1226 | short ss = SHRT_MAX; |
1227 | assertTrue(isIntOverflow<signed char>(ss)); |
1228 | assertTrue(isIntOverflow<char>(ss)); |
1229 | try |
1230 | { |
1231 | safeIntCast(ss, st); |
1232 | fail("short => signed char cast must fail" ); |
1233 | } |
1234 | catch(Poco::BadCastException&){} |
1235 | |
1236 | ss = SHRT_MIN; |
1237 | assertTrue(isIntOverflow<signed char>(ss)); |
1238 | assertTrue(isIntOverflow<char>(ss)); |
1239 | try |
1240 | { |
1241 | safeIntCast(ss, st); |
1242 | fail("short => signed char cast must fail" ); |
1243 | } |
1244 | catch(Poco::BadCastException&){} |
1245 | |
1246 | assertTrue(safeIntCast<signed char>(sc, st) == c); |
1247 | assertTrue(st == sc); |
1248 | |
1249 | unsigned char uc = 0, ut = -1; |
1250 | assertTrue(!isIntOverflow<unsigned char>(uc)); |
1251 | assertTrue(safeIntCast<char>(uc, ut) == uc); |
1252 | assertTrue(ut == uc); |
1253 | |
1254 | ss = SHRT_MAX; |
1255 | assertTrue(isIntOverflow<unsigned char>(ss)); |
1256 | try |
1257 | { |
1258 | safeIntCast(ss, st); |
1259 | fail("cast must fail" ); |
1260 | } |
1261 | catch(Poco::BadCastException&){} |
1262 | |
1263 | ss = -1; |
1264 | assertTrue(isIntOverflow<unsigned char>(ss)); |
1265 | try |
1266 | { |
1267 | safeIntCast(ss, uc); |
1268 | fail("unsigned short => unsigned char cast must fail" ); |
1269 | } |
1270 | catch(Poco::BadCastException&){} |
1271 | |
1272 | int i = 0; |
1273 | assertTrue(!isIntOverflow<int>(i)); |
1274 | assertTrue(!isIntOverflow<unsigned>(i)); |
1275 | i = -1; |
1276 | unsigned int ti = -1; |
1277 | assertTrue(isIntOverflow<unsigned>(i)); |
1278 | try |
1279 | { |
1280 | safeIntCast(i, ti); |
1281 | fail("unsigned int => int cast must fail" ); |
1282 | } |
1283 | catch(Poco::BadCastException&){} |
1284 | |
1285 | if (sizeof(long) > sizeof(int)) |
1286 | { |
1287 | long l = LONG_MAX; |
1288 | assertTrue(isIntOverflow<int>(l)); |
1289 | l = -1L; |
1290 | assertTrue(isIntOverflow<unsigned>(l)); |
1291 | i = -1; |
1292 | assertTrue(!isIntOverflow<long>(i)); |
1293 | long tl = 0; |
1294 | assertTrue(safeIntCast(i, tl) == i); |
1295 | unsigned long ul = ULONG_MAX, tul = 0; |
1296 | assertTrue(isIntOverflow<long>(ul)); |
1297 | try |
1298 | { |
1299 | safeIntCast(ul, tl); |
1300 | fail("unsigned long => long cast must fail" ); |
1301 | } |
1302 | catch(Poco::BadCastException&){} |
1303 | assertTrue(!isIntOverflow<unsigned long>(ul)); |
1304 | tl = 0; |
1305 | assertTrue(safeIntCast(ul, tul) == ul); |
1306 | l = LONG_MIN; |
1307 | assertTrue(isIntOverflow<unsigned long>(l)); |
1308 | try |
1309 | { |
1310 | safeIntCast(l, ul); |
1311 | fail("unsigned long => long cast must fail" ); |
1312 | } |
1313 | catch(Poco::BadCastException&){} |
1314 | ul = LONG_MAX; |
1315 | assertTrue(!isIntOverflow<long>(ul)); |
1316 | assertTrue(safeIntCast(ul, l) == ul); |
1317 | } |
1318 | |
1319 | numericStringLimitSameSign<unsigned short, unsigned char>(); |
1320 | numericStringLimitSameSign<short, char>(); |
1321 | numericStringLimitSameSign<unsigned int, unsigned short>(); |
1322 | numericStringLimitSameSign<int, short>(); |
1323 | |
1324 | if (sizeof(long) > sizeof(int)) |
1325 | { |
1326 | numericStringLimitSameSign<unsigned long, unsigned int>(); |
1327 | numericStringLimitSameSign<long, int>(); |
1328 | } |
1329 | |
1330 | numericStringLowerLimit<short, char>(); |
1331 | numericStringLowerLimit<int, short>(); |
1332 | |
1333 | if (sizeof(long) > sizeof(int)) |
1334 | { |
1335 | numericStringLowerLimit<int64_t, int32_t>(); |
1336 | } |
1337 | |
1338 | #ifdef POCO_ENABLE_CPP11 |
1339 | assertTrue(!isIntOverflow<int8_t>(0)); |
1340 | assertTrue(isIntOverflow<int8_t>(std::numeric_limits<int16_t>::max())); |
1341 | assertTrue(isIntOverflow<int8_t>(std::numeric_limits<int16_t>::min())); |
1342 | assertTrue(!isIntOverflow<uint8_t>(0)); |
1343 | assertTrue(isIntOverflow<uint8_t>(std::numeric_limits<int16_t>::max())); |
1344 | assertTrue(isIntOverflow<uint8_t>(-1)); |
1345 | assertTrue(!isIntOverflow<int32_t>(0)); |
1346 | assertTrue(isIntOverflow<int32_t>(std::numeric_limits<int64_t>::max())); |
1347 | assertTrue(!isIntOverflow<uint32_t>(0)); |
1348 | assertTrue(isIntOverflow<uint32_t>(-1)); |
1349 | assertTrue(isIntOverflow<uint32_t>(-1L)); |
1350 | assertTrue(isIntOverflow<uint32_t>(-1LL)); |
1351 | assertTrue(!isIntOverflow<int64_t>(-1)); |
1352 | assertTrue(isIntOverflow<int64_t>(std::numeric_limits<uint64_t>::max())); |
1353 | assertTrue(!isIntOverflow<uint64_t>(std::numeric_limits<uint64_t>::max())); |
1354 | assertTrue(isIntOverflow<uint64_t>(std::numeric_limits<int64_t>::min())); |
1355 | assertTrue(!isIntOverflow<uint64_t>(std::numeric_limits<uint64_t>::min())); |
1356 | assertTrue(!isIntOverflow<int64_t>(std::numeric_limits<int64_t>::max())); |
1357 | |
1358 | numericStringLimitSameSign<uint16_t, uint8_t>(); |
1359 | numericStringLimitSameSign<int16_t, int8_t>(); |
1360 | numericStringLimitSameSign<uint32_t, uint16_t>(); |
1361 | numericStringLimitSameSign<int32_t, int16_t>(); |
1362 | numericStringLimitSameSign<uint64_t, uint32_t>(); |
1363 | numericStringLimitSameSign<int64_t, int32_t>(); |
1364 | |
1365 | numericStringLowerLimit<int16_t, int8_t>(); |
1366 | numericStringLowerLimit<int32_t, int16_t>(); |
1367 | numericStringLowerLimit<int64_t, int32_t>(); |
1368 | #endif |
1369 | } |
1370 | |
1371 | |
1372 | void (double value, std::string& str) |
1373 | { |
1374 | char buffer[128]; |
1375 | Poco::MemoryOutputStream ostr(buffer, sizeof(buffer)); |
1376 | #if !defined(POCO_NO_LOCALE) |
1377 | ostr.imbue(std::locale::classic()); |
1378 | #endif |
1379 | ostr << std::setprecision(16) << value; |
1380 | str.assign(buffer, static_cast<std::string::size_type>(ostr.charsWritten())); |
1381 | } |
1382 | |
1383 | |
1384 | void (double value, std::string& str) |
1385 | { |
1386 | char buffer[128]; |
1387 | std::sprintf(buffer, "%.*g" , 16, value); |
1388 | str = buffer; |
1389 | } |
1390 | |
1391 | |
1392 | void StringTest::benchmarkFloatToStr() |
1393 | { |
1394 | Poco::Stopwatch sw; |
1395 | double val = 1.0372157551632929e-112; |
1396 | std::cout << "The Number: " << std::setprecision(std::numeric_limits<double>::digits10) << val << std::endl; |
1397 | std::string str; |
1398 | sw.start(); |
1399 | for (int i = 0; i < 1000000; ++i) formatStream(val, str); |
1400 | sw.stop(); |
1401 | std::cout << "formatStream Number: " << str << std::endl; |
1402 | double timeStream = sw.elapsed() / 1000.0; |
1403 | |
1404 | // standard sprintf |
1405 | str = "" ; |
1406 | sw.restart(); |
1407 | for (int i = 0; i < 1000000; ++i) formatSprintf(val, str); |
1408 | sw.stop(); |
1409 | std::cout << "std::sprintf Number: " << str << std::endl; |
1410 | double timeSprintf = sw.elapsed() / 1000.0; |
1411 | |
1412 | // POCO Way (via double-conversion) |
1413 | // no padding |
1414 | sw.restart(); |
1415 | char buffer[POCO_MAX_FLT_STRING_LEN]; |
1416 | for (int i = 0; i < 1000000; ++i) doubleToStr(buffer, POCO_MAX_FLT_STRING_LEN, val); |
1417 | sw.stop(); |
1418 | std::cout << "doubleToStr(char) Number: " << buffer << std::endl; |
1419 | double timeDoubleToStrChar = sw.elapsed() / 1000.0; |
1420 | |
1421 | // with padding |
1422 | str = "" ; |
1423 | sw.restart(); |
1424 | for (int i = 0; i < 1000000; ++i) doubleToStr(str, val); |
1425 | sw.stop(); |
1426 | std::cout << "doubleToStr(std::string) Number: " << str << std::endl; |
1427 | double timeDoubleToStrString = sw.elapsed() / 1000.0; |
1428 | |
1429 | int graph; |
1430 | std::cout << std::endl << "Timing and speedup relative to I/O stream:" << std::endl << std::endl; |
1431 | std::cout << std::setw(14) << "Stream:\t" << std::setw(10) << std::setfill(' ') << std::setprecision(4) << timeStream << "[ms]" << std::endl; |
1432 | |
1433 | std::cout << std::setw(14) << "sprintf:\t" << std::setw(10) << std::setfill(' ') << timeSprintf << "[ms]" << |
1434 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeSprintf) << '\t' ; |
1435 | graph = (int) (timeStream / timeSprintf); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1436 | |
1437 | std::cout << std::endl << std::setw(14) << "doubleToChar:\t" << std::setw(10) << std::setfill(' ') << timeDoubleToStrChar << "[ms]" << |
1438 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeDoubleToStrChar) << '\t' ; |
1439 | graph = (int) (timeStream / timeDoubleToStrChar); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1440 | |
1441 | std::cout << std::endl << std::setw(14) << "doubleToString:\t" << std::setw(10) << std::setfill(' ') << timeDoubleToStrString << "[ms]" << |
1442 | std::setw(10) << std::setfill(' ') << "Speedup: " << (timeStream / timeDoubleToStrString) << '\t' ; |
1443 | graph = (int) (timeStream / timeDoubleToStrString); for (int i = 0; i < graph; ++i) std::cout << '#'; |
1444 | |
1445 | std::cout << std::endl; |
1446 | } |
1447 | |
1448 | |
1449 | void StringTest::testJSONString() |
1450 | { |
1451 | assertTrue (toJSON("\\" , false) == "\\\\" ); |
1452 | assertTrue (toJSON("\"" , false) == "\\\"" ); |
1453 | assertTrue (toJSON("/" , false) == "\\/" ); |
1454 | assertTrue (toJSON("\a" , false) == "\\u0007" ); |
1455 | assertTrue (toJSON("\b" , false) == "\\b" ); |
1456 | assertTrue (toJSON("\f" , false) == "\\f" ); |
1457 | assertTrue (toJSON("\n" , false) == "\\n" ); |
1458 | assertTrue (toJSON("\r" , false) == "\\r" ); |
1459 | assertTrue (toJSON("\t" , false) == "\\t" ); |
1460 | assertTrue (toJSON("\v" , false) == "\\u000B" ); |
1461 | assertTrue (toJSON("a" , false) == "a" ); |
1462 | assertTrue (toJSON("\xD0\x82" , 0) == "\xD0\x82" ); |
1463 | assertTrue (toJSON("\xD0\x82" , Poco::JSON_ESCAPE_UNICODE) == "\\u0402" ); |
1464 | |
1465 | // ??? on MSVC, the assert macro expansion |
1466 | // fails to compile when this string is inline ??? |
1467 | std::string str = "\"foo\\\\\"" ; |
1468 | assertTrue (toJSON("foo\\" ) == str); |
1469 | |
1470 | assertTrue (toJSON("bar/" ) == "\"bar\\/\"" ); |
1471 | assertTrue (toJSON("baz" ) == "\"baz\"" ); |
1472 | assertTrue (toJSON("q\"uote\"d" ) == "\"q\\\"uote\\\"d\"" ); |
1473 | assertTrue (toJSON("bs\b" ) == "\"bs\\b\"" ); |
1474 | assertTrue (toJSON("nl\n" ) == "\"nl\\n\"" ); |
1475 | assertTrue (toJSON("tb\t" ) == "\"tb\\t\"" ); |
1476 | assertTrue (toJSON("\xD0\x82" ) == "\"\xD0\x82\"" ); |
1477 | assertTrue (toJSON("\xD0\x82" , Poco::JSON_WRAP_STRINGS) == "\"\xD0\x82\"" ); |
1478 | assertTrue (toJSON("\xD0\x82" , |
1479 | Poco::JSON_WRAP_STRINGS | Poco::JSON_ESCAPE_UNICODE) == "\"\\u0402\"" ); |
1480 | |
1481 | std::ostringstream ostr; |
1482 | toJSON("foo\\" , ostr); |
1483 | assertTrue (ostr.str() == str); |
1484 | ostr.str("" ); |
1485 | |
1486 | toJSON("foo\\" , ostr); |
1487 | assertTrue (toJSON("bar/" ) == "\"bar\\/\"" ); |
1488 | ostr.str("" ); |
1489 | toJSON("baz" , ostr); |
1490 | assertTrue (ostr.str() == "\"baz\"" ); |
1491 | ostr.str("" ); |
1492 | toJSON("q\"uote\"d" , ostr); |
1493 | assertTrue (ostr.str() == "\"q\\\"uote\\\"d\"" ); |
1494 | ostr.str("" ); |
1495 | toJSON("bs\b" , ostr); |
1496 | assertTrue (ostr.str() == "\"bs\\b\"" ); |
1497 | ostr.str("" ); |
1498 | toJSON("nl\n" , ostr); |
1499 | assertTrue (ostr.str() == "\"nl\\n\"" ); |
1500 | ostr.str("" ); |
1501 | toJSON("tb\t" , ostr); |
1502 | assertTrue (ostr.str() == "\"tb\\t\"" ); |
1503 | ostr.str("" ); |
1504 | toJSON("\xD0\x82" , ostr); |
1505 | assertTrue (ostr.str() == "\"\xD0\x82\"" ); |
1506 | ostr.str("" ); |
1507 | toJSON("\xD0\x82" , ostr, Poco::JSON_WRAP_STRINGS); |
1508 | assertTrue (ostr.str() == "\"\xD0\x82\"" ); |
1509 | ostr.str("" ); |
1510 | toJSON("\xD0\x82" , ostr, Poco::JSON_WRAP_STRINGS | Poco::JSON_ESCAPE_UNICODE); |
1511 | assertTrue (ostr.str() == "\"\\u0402\"" ); |
1512 | ostr.str("" ); |
1513 | } |
1514 | |
1515 | |
1516 | void StringTest::setUp() |
1517 | { |
1518 | } |
1519 | |
1520 | |
1521 | void StringTest::tearDown() |
1522 | { |
1523 | } |
1524 | |
1525 | |
1526 | CppUnit::Test* StringTest::suite() |
1527 | { |
1528 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("StringTest" ); |
1529 | |
1530 | CppUnit_addTest(pSuite, StringTest, testTrimLeft); |
1531 | CppUnit_addTest(pSuite, StringTest, testTrimLeftInPlace); |
1532 | CppUnit_addTest(pSuite, StringTest, testTrimRight); |
1533 | CppUnit_addTest(pSuite, StringTest, testTrimInPlace); |
1534 | CppUnit_addTest(pSuite, StringTest, testTrim); |
1535 | CppUnit_addTest(pSuite, StringTest, testTrimRightInPlace); |
1536 | CppUnit_addTest(pSuite, StringTest, testToUpper); |
1537 | CppUnit_addTest(pSuite, StringTest, testToLower); |
1538 | CppUnit_addTest(pSuite, StringTest, testIstring); |
1539 | CppUnit_addTest(pSuite, StringTest, testIcompare); |
1540 | CppUnit_addTest(pSuite, StringTest, testCILessThan); |
1541 | CppUnit_addTest(pSuite, StringTest, testTranslate); |
1542 | CppUnit_addTest(pSuite, StringTest, testTranslateInPlace); |
1543 | CppUnit_addTest(pSuite, StringTest, testReplace); |
1544 | CppUnit_addTest(pSuite, StringTest, testReplaceInPlace); |
1545 | CppUnit_addTest(pSuite, StringTest, testCat); |
1546 | CppUnit_addTest(pSuite, StringTest, testStartsWith); |
1547 | CppUnit_addTest(pSuite, StringTest, testEndsWith); |
1548 | CppUnit_addTest(pSuite, StringTest, testStringToInt); |
1549 | CppUnit_addTest(pSuite, StringTest, testStringToFloat); |
1550 | CppUnit_addTest(pSuite, StringTest, testStringToDouble); |
1551 | CppUnit_addTest(pSuite, StringTest, testNumericStringPadding); |
1552 | CppUnit_addTest(pSuite, StringTest, testNumericStringLimit); |
1553 | CppUnit_addTest(pSuite, StringTest, testStringToFloatError); |
1554 | CppUnit_addTest(pSuite, StringTest, testNumericLocale); |
1555 | //CppUnit_addTest(pSuite, StringTest, benchmarkStrToFloat); |
1556 | //CppUnit_addTest(pSuite, StringTest, benchmarkStrToInt); |
1557 | CppUnit_addTest(pSuite, StringTest, testIntToString); |
1558 | CppUnit_addTest(pSuite, StringTest, testFloatToString); |
1559 | //CppUnit_addTest(pSuite, StringTest, benchmarkFloatToStr); |
1560 | CppUnit_addTest(pSuite, StringTest, testJSONString); |
1561 | |
1562 | return pSuite; |
1563 | } |
1564 | |