2 **********************************************************************
3 * Copyright (c) 2002-2011,International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 **********************************************************************
10 #define _DATEFMTPERF_H
13 #include "unicode/stringpiece.h"
14 #include "unicode/unistr.h"
15 #include "unicode/uperf.h"
17 #include "unicode/utypes.h"
18 #include "unicode/datefmt.h"
19 #include "unicode/calendar.h"
20 #include "unicode/uclean.h"
21 #include "unicode/brkiter.h"
22 #include "unicode/numfmt.h"
23 #include "unicode/coll.h"
27 #include "breakdata.h"
28 #include "collationdata.h"
38 // Stubs for Windows API functions when building on UNIXes.
40 #if U_PLATFORM_USES_ONLY_WIN32_API
45 inline int FoldStringW(DWORD dwMapFlags
, const UChar
* lpSrcStr
,int cchSrc
, UChar
* lpDestStr
,int cchDest
);
48 class BreakItFunction
: public UPerfFunction
56 BreakItFunction(){num
= -1;}
57 BreakItFunction(int a
, bool b
){num
= a
; wordIteration
= b
;}
59 virtual void call(UErrorCode
*status
)
61 BreakIterator
* boundary
;
65 for(int i
= 0; i
< num
; i
++)
67 boundary
= BreakIterator::createWordInstance("en", *status
);
68 boundary
->setText(str
);
70 int32_t start
= boundary
->first();
71 for (int32_t end
= boundary
->next();
72 end
!= BreakIterator::DONE
;
73 start
= end
, end
= boundary
->next())
75 printTextRange( *boundary
, start
, end
);
80 else // character iteration
82 for(int i
= 0; i
< num
; i
++)
84 boundary
= BreakIterator::createCharacterInstance(Locale::getUS(), *status
);
85 boundary
->setText(str
);
87 int32_t start
= boundary
->first();
88 for (int32_t end
= boundary
->next();
89 end
!= BreakIterator::DONE
;
90 start
= end
, end
= boundary
->next())
92 printTextRange( *boundary
, start
, end
);
100 virtual long getOperationsPerIteration()
102 if(wordIteration
) return 125*num
;
106 void printUnicodeString(const UnicodeString
&s
) {
108 s
.extract(0, s
.length(), charBuf
, sizeof(charBuf
)-1, 0);
109 charBuf
[sizeof(charBuf
)-1] = 0;
110 printf("%s", charBuf
);
114 void printTextRange( BreakIterator
& iterator
,
115 int32_t start
, int32_t end
)
117 CharacterIterator
*strIter
= iterator
.getText().clone();
120 //printUnicodeString(UnicodeString(s, start, end-start));
125 // Print the given string to stdout (for debugging purposes)
126 void uprintf(const UnicodeString
&str
) {
128 int32_t len
= str
.length();
129 int32_t bufLen
= len
+ 16;
131 buf
= new char[bufLen
+ 1];
132 actualLen
= str
.extract(0, len
, buf
/*, bufLen*/); // Default codepage conversion
140 class DateFmtFunction
: public UPerfFunction
153 DateFmtFunction(int a
, const char* loc
)
159 virtual void call(UErrorCode
* status
)
162 UErrorCode status2
= U_ZERO_ERROR
;
168 cal
= Calendar::createInstance(status2
);
169 check(status2
, "Calendar::createInstance");
170 zone
= TimeZone::createTimeZone("GMT"); // Create a GMT zone
171 cal
->adoptTimeZone(zone
);
175 fmt
= DateFormat::createDateTimeInstance(
176 DateFormat::kShort
, DateFormat::kFull
, loc
);
179 // (dates are imported from datedata.h)
180 for(int j
= 0; j
< num
; j
++)
181 for(int i
= 0; i
< NUM_DATES
; i
++)
184 cal
->set(years
[i
], months
[i
], days
[i
]);
185 date
= cal
->getTime(status2
);
186 check(status2
, "Calendar::getTime");
188 fmt
->setCalendar(*cal
);
192 fmt
->format(date
, str
, status2
);
195 // Display the formatted date string
206 virtual long getOperationsPerIteration()
208 return NUM_DATES
* num
;
211 // Print the given string to stdout (for debugging purposes)
212 void uprintf(const UnicodeString
&str
) {
214 int32_t len
= str
.length();
215 int32_t bufLen
= len
+ 16;
217 buf
= new char[bufLen
+ 1];
218 actualLen
= str
.extract(0, len
, buf
/*, bufLen*/); // Default codepage conversion
224 // Verify that a UErrorCode is successful; exit(1) if not
225 void check(UErrorCode
& status
, const char* msg
) {
226 if (U_FAILURE(status
)) {
227 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
234 class NumFmtFunction
: public UPerfFunction
247 NumFmtFunction(int a
, const char* loc
)
253 virtual void call(UErrorCode
* status2
)
256 UErrorCode status
= U_ZERO_ERROR
;
258 // Create a number formatter for the locale
259 NumberFormat
*fmt
= NumberFormat::createInstance(loc
, status
);
261 // Parse a string. The string uses the digits '0' through '9'
262 // and the decimal separator '.', standard in the US locale
264 for(int i
= 0; i
< num
; i
++)
266 UnicodeString
str("9876543210.123");
268 fmt
->parse(str
, result
, status
);
270 //uprintf(formattableToString(result));
273 // Take the number parsed above, and use the formatter to
275 str
.remove(); // format() will APPEND to this string
276 fmt
->format(result
, str
, status
);
282 delete fmt
; // Release the storage used by the formatter
289 U_LEFT_SQUARE_BRACKET
=0x5b,
291 U_RIGHT_SQUARE_BRACKET
=0x5d,
295 // Create a display string for a formattable
296 UnicodeString
formattableToString(const Formattable
& f
) {
297 switch (f
.getType()) {
298 case Formattable::kDate
:
299 // TODO: Finish implementing this
300 return UNICODE_STRING_SIMPLE("Formattable_DATE_TBD");
301 case Formattable::kDouble
:
304 sprintf(buf
, "%gD", f
.getDouble());
305 return UnicodeString(buf
, "");
307 case Formattable::kLong
:
308 case Formattable::kInt64
:
311 sprintf(buf
, "%ldL", f
.getLong());
312 return UnicodeString(buf
, "");
314 case Formattable::kString
:
315 return UnicodeString((UChar
)U_DQUOTE
).append(f
.getString()).append((UChar
)U_DQUOTE
);
316 case Formattable::kArray
:
319 const Formattable
* array
= f
.getArray(count
);
320 UnicodeString
result((UChar
)U_LEFT_SQUARE_BRACKET
);
321 for (i
=0; i
<count
; ++i
) {
323 (result
+= (UChar
)U_COMMA
) += (UChar
)U_SPACE
;
325 result
+= formattableToString(array
[i
]);
327 result
+= (UChar
)U_RIGHT_SQUARE_BRACKET
;
331 return UNICODE_STRING_SIMPLE("INVALID_Formattable");
335 virtual long getOperationsPerIteration()
340 // Print the given string to stdout using the UTF-8 converter (for debugging purposes only)
341 void uprintf(const UnicodeString
&str
) {
342 char stackBuffer
[100];
345 int32_t bufLen
= str
.extract(0, 0x7fffffff, stackBuffer
, sizeof(stackBuffer
), "UTF-8");
346 if(bufLen
< sizeof(stackBuffer
)) {
349 buf
= new char[bufLen
+ 1];
350 bufLen
= str
.extract(0, 0x7fffffff, buf
, bufLen
+ 1, "UTF-8");
353 if(buf
!= stackBuffer
) {
361 #define NUM_STRING "9876543210.123"
362 #define NUM_NUM 9876543210.123
363 class StdioNumFmtFunction
: public UPerfFunction
371 StdioNumFmtFunction()
376 StdioNumFmtFunction(int a
, const char* loc
)
382 virtual void call(UErrorCode
* status2
)
385 UErrorCode status
= U_ZERO_ERROR
;
387 // Parse a string. The string uses the digits '0' through '9'
388 // and the decimal separator '.', standard in the US locale
392 const char *str
= NUM_STRING
;
394 for(int i
= 0; i
< num
; i
++)
396 if(sscanf(str
, "%lg", &result
)!=1) {
397 cout
<< "Failed Stdio: failed to sscanf" << endl
;
398 *status2
= U_PARSE_ERROR
;
402 sprintf(outbuf
, "%lg", result
);
405 if(result
!=NUM_NUM
) {
406 cout
<< "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM
<< " got " << result
<< endl
;
407 *status2
= U_PARSE_ERROR
;
409 if(strcmp(str
,NUM_STRING
)) {
410 cout
<< "Failed Stdio: sprintf got wrong result, expected " << NUM_STRING
<< " got " << str
<< endl
;
411 *status2
= U_PARSE_ERROR
;
415 virtual long getOperationsPerIteration()
422 class CollationFunction
: public UPerfFunction
428 UnicodeString
*collation_strings
;
431 * Unescape the strings
434 uint32_t listSize
= sizeof(collation_strings_escaped
)/sizeof(collation_strings_escaped
[0]);
435 collation_strings
= new UnicodeString
[listSize
];
436 for(uint32_t k
=0;k
<listSize
;k
++) {
437 collation_strings
[k
] = collation_strings_escaped
[k
].unescape();
439 UnicodeString
shorty((UChar32
)0x12345);
450 ~CollationFunction() {
451 delete [] collation_strings
;
454 CollationFunction(int a
, const char* loc
)
461 virtual void call(UErrorCode
* status2
)
463 uint32_t listSize
= sizeof(collation_strings_escaped
)/sizeof(collation_strings_escaped
[0]);
464 UErrorCode status
= U_ZERO_ERROR
;
465 Collator
*coll
= Collator::createInstance(Locale(locale
), status
);
467 for(int k
= 0; k
< num
; k
++)
470 for(i
=listSize
-1; i
>=1; i
--) {
472 if(coll
->compare(collation_strings
[j
], collation_strings
[j
+1]) == UCOL_LESS
) {
473 //cout << "Success!" << endl;
481 virtual long getOperationsPerIteration()
487 class DateFormatPerfTest
: public UPerfTest
493 DateFormatPerfTest(int32_t argc
, const char* argv
[], UErrorCode
& status
);
494 ~DateFormatPerfTest();
495 virtual UPerfFunction
* runIndexedTest(int32_t index
, UBool exec
,const char* &name
, char* par
);
497 UPerfFunction
* DateFmt250();
498 UPerfFunction
* DateFmt10000();
499 UPerfFunction
* DateFmt100000();
500 UPerfFunction
* BreakItWord250();
501 UPerfFunction
* BreakItWord10000();
502 UPerfFunction
* BreakItChar250();
503 UPerfFunction
* BreakItChar10000();
504 UPerfFunction
* NumFmt10000();
505 UPerfFunction
* NumFmt100000();
506 UPerfFunction
* Collation10000();
507 UPerfFunction
* Collation100000();
510 #endif // DateFmtPerf