1 /*
2 ***********************************************************************
3 * © 2016 and later: Unicode, Inc. and others.
4 * License & terms of use: http://www.unicode.org/copyright.html#License
5 ***********************************************************************
6 ***********************************************************************
7 * Copyright (c) 2002-2014, International Business Machines
8 * Corporation and others. All Rights Reserved.
9 ***********************************************************************
10 ***********************************************************************
11 */
12 #ifndef _CONVPERF_H
13 #define _CONVPERF_H
14
15 #include <mlang.h>
16 #include <objbase.h>
17 #include <stdlib.h>
18 #include "unicode/ucnv.h"
19 #include "unicode/uclean.h"
20 #include "unicode/ustring.h"
21 #include "cmemory.h" // for UPRV_LENGTHOF
22
23 #include "unicode/uperf.h"
24
25 #define CONVERSION_FLAGS (0) /*WC_DEFAULTCHAR WC_COMPOSITECHECK & WC_SEPCHARS*/
26 #define MAX_BUF_SIZE 3048
27
28 class ICUToUnicodePerfFunction : public UPerfFunction{
29 private:
30 UConverter* conv;
31 const char* src;
32 int32_t srcLen;
33 UChar* target;
34 UChar* targetLimit;
35
36 public:
ICUToUnicodePerfFunction(const char * name,const char * source,int32_t sourceLen,UErrorCode & status)37 ICUToUnicodePerfFunction(const char* name, const char* source, int32_t sourceLen, UErrorCode& status){
38 conv = ucnv_open(name,&status);
39 src = source;
40 srcLen = sourceLen;
41 if(U_FAILURE(status)){
42 conv = NULL;
43 return;
44 }
45 target = NULL;
46 targetLimit = NULL;
47 int32_t reqdLen = ucnv_toUChars(conv, target, 0,
48 source, srcLen, &status);
49 if(status==U_BUFFER_OVERFLOW_ERROR) {
50 status=U_ZERO_ERROR;
51 target=(UChar*)malloc((reqdLen) * U_SIZEOF_UCHAR*2);
52 targetLimit = target + reqdLen;
53 if(target == NULL){
54 status = U_MEMORY_ALLOCATION_ERROR;
55 return;
56 }
57 }
58 }
call(UErrorCode * status)59 virtual void call(UErrorCode* status){
60 const char* mySrc = src;
61 const char* sourceLimit = src + srcLen;
62 UChar* myTarget = target;
63 ucnv_toUnicode(conv, &myTarget, targetLimit, &mySrc, sourceLimit, NULL, TRUE, status);
64 }
getOperationsPerIteration(void)65 virtual long getOperationsPerIteration(void){
66 return srcLen;
67 }
~ICUToUnicodePerfFunction()68 ~ICUToUnicodePerfFunction(){
69 free(target);
70 ucnv_close(conv);
71 }
72 };
73 class ICUFromUnicodePerfFunction : public UPerfFunction{
74 private:
75 UConverter* conv;
76 const UChar* src;
77 int32_t srcLen;
78 char* target;
79 char* targetLimit;
80 const char* name;
81
82 public:
ICUFromUnicodePerfFunction(const char * name,const UChar * source,int32_t sourceLen,UErrorCode & status)83 ICUFromUnicodePerfFunction(const char* name, const UChar* source, int32_t sourceLen, UErrorCode& status){
84 conv = ucnv_open(name,&status);
85 src = source;
86 srcLen = sourceLen;
87 if(U_FAILURE(status)){
88 conv = NULL;
89 return;
90 }
91 target = NULL;
92 targetLimit = NULL;
93 int32_t reqdLen = ucnv_fromUChars(conv, target, 0,
94 source, srcLen, &status);
95 if(status==U_BUFFER_OVERFLOW_ERROR) {
96 status=U_ZERO_ERROR;
97 target=(char*)malloc((reqdLen*2));
98 targetLimit = target + reqdLen;
99 if(target == NULL){
100 status = U_MEMORY_ALLOCATION_ERROR;
101 return;
102 }
103 }
104 }
call(UErrorCode * status)105 virtual void call(UErrorCode* status){
106 const UChar* mySrc = src;
107 const UChar* sourceLimit = src + srcLen;
108 char* myTarget = target;
109 ucnv_fromUnicode(conv,&myTarget, targetLimit, &mySrc, sourceLimit, NULL, TRUE, status);
110 }
getOperationsPerIteration(void)111 virtual long getOperationsPerIteration(void){
112 return srcLen;
113 }
~ICUFromUnicodePerfFunction()114 ~ICUFromUnicodePerfFunction(){
115 free(target);
116 ucnv_close(conv);
117 }
118 };
119
120 class ICUOpenAllConvertersFunction : public UPerfFunction{
121 private:
122 UBool cleanup;
123 int32_t availableConverters;
124 const char **convNames;
125 public:
ICUOpenAllConvertersFunction(UBool callCleanup,UErrorCode & status)126 ICUOpenAllConvertersFunction(UBool callCleanup, UErrorCode& status){
127 int32_t idx;
128 cleanup = callCleanup;
129 availableConverters = ucnv_countAvailable();
130 convNames = new const char *[availableConverters];
131 for (idx = 0; idx < availableConverters; idx++) {
132 convNames[idx] = ucnv_getAvailableName(idx);
133 }
134 }
call(UErrorCode * status)135 virtual void call(UErrorCode* status){
136 int32_t idx;
137 if (cleanup) {
138 u_cleanup();
139 }
140 for (idx = 0; idx < availableConverters; idx++) {
141 ucnv_close(ucnv_open(convNames[idx], status));
142 }
143 }
getOperationsPerIteration(void)144 virtual long getOperationsPerIteration(void){
145 return availableConverters;
146 }
~ICUOpenAllConvertersFunction()147 ~ICUOpenAllConvertersFunction(){
148 delete []convNames;
149 }
150 };
151
152 class WinANSIToUnicodePerfFunction : public UPerfFunction{
153
154 private:
155 DWORD uiCodePage;
156 char* src;
157 UINT srcLen;
158 WCHAR dest[MAX_BUF_SIZE];
159 UINT dstLen;
160 const char* name;
161 public:
WinANSIToUnicodePerfFunction(const char * cpName,char * pszIn,UINT szLen,UErrorCode & status)162 WinANSIToUnicodePerfFunction(const char* cpName, char* pszIn,UINT szLen, UErrorCode& status){
163 name = cpName;
164 src = pszIn;
165 srcLen = szLen;
166 dstLen = UPRV_LENGTHOF(dest);
167 unsigned short bEnc[30]={'\0'};
168 const char* tenc=name;
169 for(int i=0;*tenc!='\0';i++){
170 bEnc[i]=*tenc;
171 tenc++;
172 }
173 LPMULTILANGUAGE2 pMulti;
174
175 CoInitialize(NULL);
176
177 /* create instance of converter object*/
178 CoCreateInstance(
179 __uuidof(CMultiLanguage),
180 NULL,
181 CLSCTX_SERVER,
182 __uuidof(IMultiLanguage2),
183 (void**)&pMulti
184 );
185
186
187
188 MIMECSETINFO mimeInfo;
189
190 mimeInfo.uiCodePage = 0;
191 mimeInfo.uiInternetEncoding =0;
192 /* get the charset info */
193 pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo);
194 uiCodePage = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding;
195 }
call(UErrorCode * status)196 virtual void call(UErrorCode* status){
197 int winSize =MultiByteToWideChar(uiCodePage,CONVERSION_FLAGS,src,srcLen,dest,dstLen);
198 }
getOperationsPerIteration(void)199 virtual long getOperationsPerIteration(void){
200 return srcLen;
201 }
202 };
203
204 class WinANSIFromUnicodePerfFunction : public UPerfFunction{
205
206 private:
207 DWORD uiCodePage;
208 WCHAR* src;
209 UINT srcLen;
210 char dest[MAX_BUF_SIZE];
211 UINT dstLen;
212 const char* name;
213 BOOL lpUsedDefaultChar;
214
215 public:
WinANSIFromUnicodePerfFunction(const char * cpName,WCHAR * pszIn,UINT szLen,UErrorCode & status)216 WinANSIFromUnicodePerfFunction(const char* cpName, WCHAR* pszIn,UINT szLen, UErrorCode& status){
217 name = cpName;
218 src = pszIn;
219 srcLen = szLen;
220 dstLen = UPRV_LENGTHOF(dest);
221 lpUsedDefaultChar=FALSE;
222 unsigned short bEnc[30]={'\0'};
223 const char* tenc=name;
224 for(int i=0;*tenc!='\0';i++){
225 bEnc[i]=*tenc;
226 tenc++;
227 }
228 LPMULTILANGUAGE2 pMulti;
229
230 CoInitialize(NULL);
231
232 /* create instance of converter object*/
233 CoCreateInstance(
234 __uuidof(CMultiLanguage),
235 NULL,
236 CLSCTX_SERVER,
237 __uuidof(IMultiLanguage2),
238 (void**)&pMulti
239 );
240
241
242
243 MIMECSETINFO mimeInfo;
244 mimeInfo.uiCodePage = 0;
245 mimeInfo.uiInternetEncoding =0;
246 /* get the charset info */
247 pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo);
248 uiCodePage = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding;
249 }
call(UErrorCode * status)250 virtual void call(UErrorCode* status){
251 BOOL* pUsedDefaultChar =(uiCodePage==CP_UTF8)?NULL:&lpUsedDefaultChar;
252 int winSize = WideCharToMultiByte(uiCodePage,CONVERSION_FLAGS,src,srcLen,dest,dstLen,NULL, pUsedDefaultChar);
253 }
getOperationsPerIteration(void)254 virtual long getOperationsPerIteration(void){
255 return srcLen;
256 }
257 };
getErr(HRESULT err,UErrorCode & status)258 static inline void getErr(HRESULT err, UErrorCode& status){
259
260 switch (err){
261
262 case S_OK:
263 //printf("Operation %s successful\n",operation);
264 break;
265 case S_FALSE:
266 status = U_INTERNAL_PROGRAM_ERROR;
267 break;
268 case E_FAIL:
269 status = U_ILLEGAL_CHAR_FOUND;
270 }
271 }
272 class WinIMultiLanguageToUnicodePerfFunction : public UPerfFunction{
273
274 private:
275 LPMULTILANGUAGE2 pMulti;
276 LPMLANGCONVERTCHARSET pConvToUni;
277 char* src;
278 UINT srcLen;
279 WCHAR dst[MAX_BUF_SIZE];
280 UINT dstLen;
281 const char* cpName;
282
283 public:
WinIMultiLanguageToUnicodePerfFunction(const char * name,char * source,UINT sourceLen,UErrorCode & status)284 WinIMultiLanguageToUnicodePerfFunction(const char* name,char* source, UINT sourceLen, UErrorCode& status){
285
286 CoInitialize(NULL);
287
288 /* create instance of converter object*/
289 CoCreateInstance(
290 __uuidof(CMultiLanguage),
291 NULL,
292 CLSCTX_SERVER,
293 __uuidof(IMultiLanguage2),
294 (void**)&pMulti
295 );
296
297
298
299 MIMECSETINFO mimeInfo;
300 mimeInfo.uiCodePage = 0;
301 mimeInfo.uiInternetEncoding =0;
302 HRESULT err=S_OK;
303 unsigned short bEnc[30]={'\0'};
304 const char* tenc=name;
305 for(int i=0;*tenc!='\0';i++){
306 bEnc[i]=*tenc;
307 tenc++;
308 }
309 /* get the charset info */
310 pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo);
311 pMulti->CreateConvertCharset(mimeInfo.uiCodePage, 1200 /*unicode*/, (DWORD)0,&pConvToUni);
312 getErr(err,status);
313 src = source;
314 srcLen = sourceLen;
315 dstLen = UPRV_LENGTHOF(dst);
316 cpName = name;
317 }
318
call(UErrorCode * status)319 virtual void call(UErrorCode* status){
320 HRESULT err= pConvToUni->DoConversionToUnicode(src,&srcLen,dst, &dstLen);
321 getErr(err,*status);
322 }
getOperationsPerIteration(void)323 virtual long getOperationsPerIteration(void){
324 return srcLen;
325 }
326 };
327
328 class WinIMultiLanguageFromUnicodePerfFunction : public UPerfFunction{
329
330 private:
331 LPMULTILANGUAGE2 pMulti;
332 LPMLANGCONVERTCHARSET pConvFromUni;
333 WCHAR* src;
334 UINT srcLen;
335 char dst[MAX_BUF_SIZE];
336 UINT dstLen;
337 const char* cpName;
338
339 public:
WinIMultiLanguageFromUnicodePerfFunction(const char * name,WCHAR * source,UINT sourceLen,UErrorCode & status)340 WinIMultiLanguageFromUnicodePerfFunction(const char* name,WCHAR* source, UINT sourceLen, UErrorCode& status){
341
342 CoInitialize(NULL);
343
344 /* create instance of converter object*/
345 CoCreateInstance(
346 __uuidof(CMultiLanguage),
347 NULL,
348 CLSCTX_SERVER,
349 __uuidof(IMultiLanguage2),
350 (void**)&pMulti
351 );
352
353
354
355 MIMECSETINFO mimeInfo;
356 mimeInfo.uiCodePage = 0;
357 mimeInfo.uiInternetEncoding =0;
358 HRESULT err=S_OK;
359 unsigned short bEnc[30]={'\0'};
360 const char* tenc=name;
361 for(int i=0;*tenc!='\0';i++){
362 bEnc[i]=*tenc;
363 tenc++;
364 }
365 /* get the charset info */
366 pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo);
367 pMulti->CreateConvertCharset(1200 /*unicode*/, mimeInfo.uiCodePage, (DWORD)0,&pConvFromUni);
368 getErr(err,status);
369 src = source;
370 srcLen = sourceLen;
371 dstLen = UPRV_LENGTHOF(dst);
372 cpName = name;
373
374 }
375
call(UErrorCode * status)376 virtual void call(UErrorCode* status){
377 HRESULT err= pConvFromUni->DoConversionFromUnicode(src,&srcLen,dst, &dstLen);
378 getErr(err,*status);
379 }
getOperationsPerIteration(void)380 virtual long getOperationsPerIteration(void){
381 return srcLen;
382 }
383 };
384
385 class WinIMultiLanguage2ToUnicodePerfFunction : public UPerfFunction{
386
387 private:
388 LPMULTILANGUAGE2 pMulti;
389 char* src;
390 UINT srcLen;
391 WCHAR dst[MAX_BUF_SIZE];
392 UINT dstLen;
393 const char* cpName;
394 DWORD dwEnc;
395 public:
WinIMultiLanguage2ToUnicodePerfFunction(const char * name,char * source,UINT sourceLen,UErrorCode & status)396 WinIMultiLanguage2ToUnicodePerfFunction(const char* name,char* source, UINT sourceLen, UErrorCode& status){
397
398 CoInitialize(NULL);
399
400 /* create instance of converter object*/
401 CoCreateInstance(
402 __uuidof(CMultiLanguage),
403 NULL,
404 CLSCTX_SERVER,
405 __uuidof(IMultiLanguage2),
406 (void**)&pMulti
407 );
408
409 src = source;
410 srcLen = sourceLen;
411 dstLen = UPRV_LENGTHOF(dst);
412 cpName = name;
413 unsigned short bEnc[30]={'\0'};
414 const char* tenc=name;
415 for(int i=0;*tenc!='\0';i++){
416 bEnc[i]=*tenc;
417 tenc++;
418 }
419 /* get the charset info */
420 MIMECSETINFO mimeInfo;
421 mimeInfo.uiCodePage = 0;
422 mimeInfo.uiInternetEncoding =0;
423 pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo);
424 dwEnc = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding;
425 }
426
call(UErrorCode * status)427 virtual void call(UErrorCode* status){
428 DWORD dwMode=0;
429 HRESULT err= pMulti->ConvertStringToUnicode(&dwMode,dwEnc,(char*)src,&srcLen,dst, &dstLen);
430 getErr(err,*status);
431 }
getOperationsPerIteration(void)432 virtual long getOperationsPerIteration(void){
433 return srcLen;
434 }
435 };
436
437 class WinIMultiLanguage2FromUnicodePerfFunction : public UPerfFunction{
438
439 private:
440 LPMULTILANGUAGE2 pMulti;
441 LPMLANGCONVERTCHARSET pConvFromUni;
442 WCHAR* src;
443 UINT srcLen;
444 char dst[MAX_BUF_SIZE];
445 UINT dstLen;
446 const char* cpName;
447 DWORD dwEnc;
448
449 public:
WinIMultiLanguage2FromUnicodePerfFunction(const char * name,WCHAR * source,UINT sourceLen,UErrorCode & status)450 WinIMultiLanguage2FromUnicodePerfFunction(const char* name,WCHAR* source, UINT sourceLen, UErrorCode& status){
451
452 CoInitialize(NULL);
453
454 /* create instance of converter object*/
455 CoCreateInstance(
456 __uuidof(CMultiLanguage),
457 NULL,
458 CLSCTX_SERVER,
459 __uuidof(IMultiLanguage2),
460 (void**)&pMulti
461 );
462
463
464 unsigned short bEnc[30]={'\0'};
465 const char* tenc=name;
466 for(int i=0;*tenc!='\0';i++){
467 bEnc[i]=*tenc;
468 tenc++;
469 }
470 src = source;
471 srcLen = sourceLen;
472 dstLen = UPRV_LENGTHOF(dst);
473 cpName = name;
474 /* get the charset info */
475 MIMECSETINFO mimeInfo;
476 mimeInfo.uiCodePage = 0;
477 mimeInfo.uiInternetEncoding =0;
478
479 pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo);
480 dwEnc = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding;
481 }
482
call(UErrorCode * status)483 virtual void call(UErrorCode* status){
484 DWORD dwMode=0;
485 HRESULT err= pMulti->ConvertStringFromUnicode(&dwMode,dwEnc,src,&srcLen,dst, &dstLen);
486 getErr(err,*status);
487 }
getOperationsPerIteration(void)488 virtual long getOperationsPerIteration(void){
489 return srcLen;
490 }
491 };
492
493 class ConverterPerformanceTest : public UPerfTest{
494
495 public:
496
497 ConverterPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status);
498 ~ConverterPerformanceTest();
499 virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par = NULL);
500
501 UPerfFunction* TestICU_CleanOpenAllConverters();
502 UPerfFunction* TestICU_OpenAllConverters();
503
504 UPerfFunction* TestICU_UTF8_ToUnicode();
505 UPerfFunction* TestICU_UTF8_FromUnicode();
506 UPerfFunction* TestWinANSI_UTF8_ToUnicode();
507 UPerfFunction* TestWinANSI_UTF8_FromUnicode();
508 UPerfFunction* TestWinIML2_UTF8_ToUnicode();
509 UPerfFunction* TestWinIML2_UTF8_FromUnicode();
510
511 UPerfFunction* TestICU_Latin1_ToUnicode();
512 UPerfFunction* TestICU_Latin1_FromUnicode();
513 UPerfFunction* TestWinANSI_Latin1_ToUnicode();
514 UPerfFunction* TestWinANSI_Latin1_FromUnicode();
515 UPerfFunction* TestWinIML2_Latin1_ToUnicode();
516 UPerfFunction* TestWinIML2_Latin1_FromUnicode();
517
518 UPerfFunction* TestICU_EBCDIC_Arabic_ToUnicode();
519 UPerfFunction* TestICU_EBCDIC_Arabic_FromUnicode();
520 UPerfFunction* TestWinANSI_EBCDIC_Arabic_ToUnicode();
521 UPerfFunction* TestWinANSI_EBCDIC_Arabic_FromUnicode();
522 UPerfFunction* TestWinIML2_EBCDIC_Arabic_ToUnicode();
523 UPerfFunction* TestWinIML2_EBCDIC_Arabic_FromUnicode();
524
525 UPerfFunction* TestICU_Latin8_ToUnicode();
526 UPerfFunction* TestICU_Latin8_FromUnicode();
527 UPerfFunction* TestWinANSI_Latin8_ToUnicode();
528 UPerfFunction* TestWinANSI_Latin8_FromUnicode();
529 UPerfFunction* TestWinIML2_Latin8_ToUnicode();
530 UPerfFunction* TestWinIML2_Latin8_FromUnicode();
531
532
533 UPerfFunction* TestICU_SJIS_ToUnicode();
534 UPerfFunction* TestICU_SJIS_FromUnicode();
535 UPerfFunction* TestWinANSI_SJIS_ToUnicode();
536 UPerfFunction* TestWinANSI_SJIS_FromUnicode();
537 UPerfFunction* TestWinIML2_SJIS_ToUnicode();
538 UPerfFunction* TestWinIML2_SJIS_FromUnicode();
539
540 UPerfFunction* TestICU_EUCJP_ToUnicode();
541 UPerfFunction* TestICU_EUCJP_FromUnicode();
542 UPerfFunction* TestWinANSI_EUCJP_ToUnicode();
543 UPerfFunction* TestWinANSI_EUCJP_FromUnicode();
544 UPerfFunction* TestWinIML2_EUCJP_ToUnicode();
545 UPerfFunction* TestWinIML2_EUCJP_FromUnicode();
546
547 UPerfFunction* TestICU_GB2312_ToUnicode();
548 UPerfFunction* TestICU_GB2312_FromUnicode();
549 UPerfFunction* TestWinANSI_GB2312_ToUnicode();
550 UPerfFunction* TestWinANSI_GB2312_FromUnicode();
551 UPerfFunction* TestWinIML2_GB2312_ToUnicode();
552 UPerfFunction* TestWinIML2_GB2312_FromUnicode();
553
554
555 UPerfFunction* TestICU_ISO2022KR_ToUnicode();
556 UPerfFunction* TestICU_ISO2022KR_FromUnicode();
557 UPerfFunction* TestWinANSI_ISO2022KR_ToUnicode();
558 UPerfFunction* TestWinANSI_ISO2022KR_FromUnicode();
559 UPerfFunction* TestWinIML2_ISO2022KR_ToUnicode();
560 UPerfFunction* TestWinIML2_ISO2022KR_FromUnicode();
561
562 UPerfFunction* TestICU_ISO2022JP_ToUnicode();
563 UPerfFunction* TestICU_ISO2022JP_FromUnicode();
564 UPerfFunction* TestWinANSI_ISO2022JP_ToUnicode();
565 UPerfFunction* TestWinANSI_ISO2022JP_FromUnicode();
566 UPerfFunction* TestWinIML2_ISO2022JP_ToUnicode();
567 UPerfFunction* TestWinIML2_ISO2022JP_FromUnicode();
568
569 };
570
571 #endif
572
573