Home | History | Annotate | Download | only in convperf
      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:
     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