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