1 /* 2 *********************************************************************** 3 * Copyright (C) 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: 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 } 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 } 65 virtual long getOperationsPerIteration(void){ 66 return srcLen; 67 } 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: 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 } 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 } 111 virtual long getOperationsPerIteration(void){ 112 return srcLen; 113 } 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: 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 } 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 } 144 virtual long getOperationsPerIteration(void){ 145 return availableConverters; 146 } 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: 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 } 196 virtual void call(UErrorCode* status){ 197 int winSize =MultiByteToWideChar(uiCodePage,CONVERSION_FLAGS,src,srcLen,dest,dstLen); 198 } 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: 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 } 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 } 254 virtual long getOperationsPerIteration(void){ 255 return srcLen; 256 } 257 }; 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: 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 319 virtual void call(UErrorCode* status){ 320 HRESULT err= pConvToUni->DoConversionToUnicode(src,&srcLen,dst, &dstLen); 321 getErr(err,*status); 322 } 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: 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 376 virtual void call(UErrorCode* status){ 377 HRESULT err= pConvFromUni->DoConversionFromUnicode(src,&srcLen,dst, &dstLen); 378 getErr(err,*status); 379 } 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: 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 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 } 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: 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 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 } 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