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
28class ICUToUnicodePerfFunction : public UPerfFunction{
29private:
30    UConverter* conv;
31    const char* src;
32    int32_t srcLen;
33    UChar* target;
34    UChar* targetLimit;
35
36public:
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};
73class ICUFromUnicodePerfFunction : public UPerfFunction{
74private:
75    UConverter* conv;
76    const UChar* src;
77    int32_t srcLen;
78    char* target;
79    char* targetLimit;
80    const char* name;
81
82public:
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
120class ICUOpenAllConvertersFunction : public UPerfFunction{
121private:
122    UBool cleanup;
123    int32_t availableConverters;
124    const char **convNames;
125public:
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
152class WinANSIToUnicodePerfFunction : public UPerfFunction{
153
154private:
155    DWORD uiCodePage;
156    char* src;
157    UINT  srcLen;
158    WCHAR dest[MAX_BUF_SIZE];
159    UINT  dstLen;
160    const char* name;
161public:
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
204class WinANSIFromUnicodePerfFunction : public UPerfFunction{
205
206private:
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
215public:
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};
258static 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}
272class WinIMultiLanguageToUnicodePerfFunction : public UPerfFunction{
273
274private:
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
283public:
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
328class WinIMultiLanguageFromUnicodePerfFunction : public UPerfFunction{
329
330private:
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
339public:
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
385class WinIMultiLanguage2ToUnicodePerfFunction : public UPerfFunction{
386
387private:
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;
395public:
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
437class WinIMultiLanguage2FromUnicodePerfFunction : public UPerfFunction{
438
439private:
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
449public:
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
493class  ConverterPerformanceTest : public UPerfTest{
494
495public:
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