/* *********************************************************************** * © 2016 and later: Unicode, Inc. and others. * License & terms of use: http://www.unicode.org/copyright.html *********************************************************************** *********************************************************************** * Copyright (c) 2002-2014, International Business Machines * Corporation and others. All Rights Reserved. *********************************************************************** *********************************************************************** */ #ifndef _CONVPERF_H #define _CONVPERF_H #include #include #include #include "unicode/ucnv.h" #include "unicode/uclean.h" #include "unicode/ustring.h" #include "cmemory.h" // for UPRV_LENGTHOF #include "unicode/uperf.h" #define CONVERSION_FLAGS (0) /*WC_DEFAULTCHAR WC_COMPOSITECHECK & WC_SEPCHARS*/ #define MAX_BUF_SIZE 3048 class ICUToUnicodePerfFunction : public UPerfFunction{ private: UConverter* conv; const char* src; int32_t srcLen; UChar* target; UChar* targetLimit; public: ICUToUnicodePerfFunction(const char* name, const char* source, int32_t sourceLen, UErrorCode& status){ conv = ucnv_open(name,&status); src = source; srcLen = sourceLen; if(U_FAILURE(status)){ conv = NULL; return; } target = NULL; targetLimit = NULL; int32_t reqdLen = ucnv_toUChars(conv, target, 0, source, srcLen, &status); if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; target=(UChar*)malloc((reqdLen) * U_SIZEOF_UCHAR*2); targetLimit = target + reqdLen; if(target == NULL){ status = U_MEMORY_ALLOCATION_ERROR; return; } } } virtual void call(UErrorCode* status){ const char* mySrc = src; const char* sourceLimit = src + srcLen; UChar* myTarget = target; ucnv_toUnicode(conv, &myTarget, targetLimit, &mySrc, sourceLimit, NULL, TRUE, status); } virtual long getOperationsPerIteration(void){ return srcLen; } ~ICUToUnicodePerfFunction(){ free(target); ucnv_close(conv); } }; class ICUFromUnicodePerfFunction : public UPerfFunction{ private: UConverter* conv; const UChar* src; int32_t srcLen; char* target; char* targetLimit; const char* name; public: ICUFromUnicodePerfFunction(const char* name, const UChar* source, int32_t sourceLen, UErrorCode& status){ conv = ucnv_open(name,&status); src = source; srcLen = sourceLen; if(U_FAILURE(status)){ conv = NULL; return; } target = NULL; targetLimit = NULL; int32_t reqdLen = ucnv_fromUChars(conv, target, 0, source, srcLen, &status); if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; target=(char*)malloc((reqdLen*2)); targetLimit = target + reqdLen; if(target == NULL){ status = U_MEMORY_ALLOCATION_ERROR; return; } } } virtual void call(UErrorCode* status){ const UChar* mySrc = src; const UChar* sourceLimit = src + srcLen; char* myTarget = target; ucnv_fromUnicode(conv,&myTarget, targetLimit, &mySrc, sourceLimit, NULL, TRUE, status); } virtual long getOperationsPerIteration(void){ return srcLen; } ~ICUFromUnicodePerfFunction(){ free(target); ucnv_close(conv); } }; class ICUOpenAllConvertersFunction : public UPerfFunction{ private: UBool cleanup; int32_t availableConverters; const char **convNames; public: ICUOpenAllConvertersFunction(UBool callCleanup, UErrorCode& status){ int32_t idx; cleanup = callCleanup; availableConverters = ucnv_countAvailable(); convNames = new const char *[availableConverters]; for (idx = 0; idx < availableConverters; idx++) { convNames[idx] = ucnv_getAvailableName(idx); } } virtual void call(UErrorCode* status){ int32_t idx; if (cleanup) { u_cleanup(); } for (idx = 0; idx < availableConverters; idx++) { ucnv_close(ucnv_open(convNames[idx], status)); } } virtual long getOperationsPerIteration(void){ return availableConverters; } ~ICUOpenAllConvertersFunction(){ delete []convNames; } }; class WinANSIToUnicodePerfFunction : public UPerfFunction{ private: DWORD uiCodePage; char* src; UINT srcLen; WCHAR dest[MAX_BUF_SIZE]; UINT dstLen; const char* name; public: WinANSIToUnicodePerfFunction(const char* cpName, char* pszIn,UINT szLen, UErrorCode& status){ name = cpName; src = pszIn; srcLen = szLen; dstLen = UPRV_LENGTHOF(dest); unsigned short bEnc[30]={'\0'}; const char* tenc=name; for(int i=0;*tenc!='\0';i++){ bEnc[i]=*tenc; tenc++; } LPMULTILANGUAGE2 pMulti; CoInitialize(NULL); /* create instance of converter object*/ CoCreateInstance( __uuidof(CMultiLanguage), NULL, CLSCTX_SERVER, __uuidof(IMultiLanguage2), (void**)&pMulti ); MIMECSETINFO mimeInfo; mimeInfo.uiCodePage = 0; mimeInfo.uiInternetEncoding =0; /* get the charset info */ pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo); uiCodePage = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding; } virtual void call(UErrorCode* status){ int winSize =MultiByteToWideChar(uiCodePage,CONVERSION_FLAGS,src,srcLen,dest,dstLen); } virtual long getOperationsPerIteration(void){ return srcLen; } }; class WinANSIFromUnicodePerfFunction : public UPerfFunction{ private: DWORD uiCodePage; WCHAR* src; UINT srcLen; char dest[MAX_BUF_SIZE]; UINT dstLen; const char* name; BOOL lpUsedDefaultChar; public: WinANSIFromUnicodePerfFunction(const char* cpName, WCHAR* pszIn,UINT szLen, UErrorCode& status){ name = cpName; src = pszIn; srcLen = szLen; dstLen = UPRV_LENGTHOF(dest); lpUsedDefaultChar=FALSE; unsigned short bEnc[30]={'\0'}; const char* tenc=name; for(int i=0;*tenc!='\0';i++){ bEnc[i]=*tenc; tenc++; } LPMULTILANGUAGE2 pMulti; CoInitialize(NULL); /* create instance of converter object*/ CoCreateInstance( __uuidof(CMultiLanguage), NULL, CLSCTX_SERVER, __uuidof(IMultiLanguage2), (void**)&pMulti ); MIMECSETINFO mimeInfo; mimeInfo.uiCodePage = 0; mimeInfo.uiInternetEncoding =0; /* get the charset info */ pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo); uiCodePage = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding; } virtual void call(UErrorCode* status){ BOOL* pUsedDefaultChar =(uiCodePage==CP_UTF8)?NULL:&lpUsedDefaultChar; int winSize = WideCharToMultiByte(uiCodePage,CONVERSION_FLAGS,src,srcLen,dest,dstLen,NULL, pUsedDefaultChar); } virtual long getOperationsPerIteration(void){ return srcLen; } }; static inline void getErr(HRESULT err, UErrorCode& status){ switch (err){ case S_OK: //printf("Operation %s successful\n",operation); break; case S_FALSE: status = U_INTERNAL_PROGRAM_ERROR; break; case E_FAIL: status = U_ILLEGAL_CHAR_FOUND; } } class WinIMultiLanguageToUnicodePerfFunction : public UPerfFunction{ private: LPMULTILANGUAGE2 pMulti; LPMLANGCONVERTCHARSET pConvToUni; char* src; UINT srcLen; WCHAR dst[MAX_BUF_SIZE]; UINT dstLen; const char* cpName; public: WinIMultiLanguageToUnicodePerfFunction(const char* name,char* source, UINT sourceLen, UErrorCode& status){ CoInitialize(NULL); /* create instance of converter object*/ CoCreateInstance( __uuidof(CMultiLanguage), NULL, CLSCTX_SERVER, __uuidof(IMultiLanguage2), (void**)&pMulti ); MIMECSETINFO mimeInfo; mimeInfo.uiCodePage = 0; mimeInfo.uiInternetEncoding =0; HRESULT err=S_OK; unsigned short bEnc[30]={'\0'}; const char* tenc=name; for(int i=0;*tenc!='\0';i++){ bEnc[i]=*tenc; tenc++; } /* get the charset info */ pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo); pMulti->CreateConvertCharset(mimeInfo.uiCodePage, 1200 /*unicode*/, (DWORD)0,&pConvToUni); getErr(err,status); src = source; srcLen = sourceLen; dstLen = UPRV_LENGTHOF(dst); cpName = name; } virtual void call(UErrorCode* status){ HRESULT err= pConvToUni->DoConversionToUnicode(src,&srcLen,dst, &dstLen); getErr(err,*status); } virtual long getOperationsPerIteration(void){ return srcLen; } }; class WinIMultiLanguageFromUnicodePerfFunction : public UPerfFunction{ private: LPMULTILANGUAGE2 pMulti; LPMLANGCONVERTCHARSET pConvFromUni; WCHAR* src; UINT srcLen; char dst[MAX_BUF_SIZE]; UINT dstLen; const char* cpName; public: WinIMultiLanguageFromUnicodePerfFunction(const char* name,WCHAR* source, UINT sourceLen, UErrorCode& status){ CoInitialize(NULL); /* create instance of converter object*/ CoCreateInstance( __uuidof(CMultiLanguage), NULL, CLSCTX_SERVER, __uuidof(IMultiLanguage2), (void**)&pMulti ); MIMECSETINFO mimeInfo; mimeInfo.uiCodePage = 0; mimeInfo.uiInternetEncoding =0; HRESULT err=S_OK; unsigned short bEnc[30]={'\0'}; const char* tenc=name; for(int i=0;*tenc!='\0';i++){ bEnc[i]=*tenc; tenc++; } /* get the charset info */ pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo); pMulti->CreateConvertCharset(1200 /*unicode*/, mimeInfo.uiCodePage, (DWORD)0,&pConvFromUni); getErr(err,status); src = source; srcLen = sourceLen; dstLen = UPRV_LENGTHOF(dst); cpName = name; } virtual void call(UErrorCode* status){ HRESULT err= pConvFromUni->DoConversionFromUnicode(src,&srcLen,dst, &dstLen); getErr(err,*status); } virtual long getOperationsPerIteration(void){ return srcLen; } }; class WinIMultiLanguage2ToUnicodePerfFunction : public UPerfFunction{ private: LPMULTILANGUAGE2 pMulti; char* src; UINT srcLen; WCHAR dst[MAX_BUF_SIZE]; UINT dstLen; const char* cpName; DWORD dwEnc; public: WinIMultiLanguage2ToUnicodePerfFunction(const char* name,char* source, UINT sourceLen, UErrorCode& status){ CoInitialize(NULL); /* create instance of converter object*/ CoCreateInstance( __uuidof(CMultiLanguage), NULL, CLSCTX_SERVER, __uuidof(IMultiLanguage2), (void**)&pMulti ); src = source; srcLen = sourceLen; dstLen = UPRV_LENGTHOF(dst); cpName = name; unsigned short bEnc[30]={'\0'}; const char* tenc=name; for(int i=0;*tenc!='\0';i++){ bEnc[i]=*tenc; tenc++; } /* get the charset info */ MIMECSETINFO mimeInfo; mimeInfo.uiCodePage = 0; mimeInfo.uiInternetEncoding =0; pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo); dwEnc = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding; } virtual void call(UErrorCode* status){ DWORD dwMode=0; HRESULT err= pMulti->ConvertStringToUnicode(&dwMode,dwEnc,(char*)src,&srcLen,dst, &dstLen); getErr(err,*status); } virtual long getOperationsPerIteration(void){ return srcLen; } }; class WinIMultiLanguage2FromUnicodePerfFunction : public UPerfFunction{ private: LPMULTILANGUAGE2 pMulti; LPMLANGCONVERTCHARSET pConvFromUni; WCHAR* src; UINT srcLen; char dst[MAX_BUF_SIZE]; UINT dstLen; const char* cpName; DWORD dwEnc; public: WinIMultiLanguage2FromUnicodePerfFunction(const char* name,WCHAR* source, UINT sourceLen, UErrorCode& status){ CoInitialize(NULL); /* create instance of converter object*/ CoCreateInstance( __uuidof(CMultiLanguage), NULL, CLSCTX_SERVER, __uuidof(IMultiLanguage2), (void**)&pMulti ); unsigned short bEnc[30]={'\0'}; const char* tenc=name; for(int i=0;*tenc!='\0';i++){ bEnc[i]=*tenc; tenc++; } src = source; srcLen = sourceLen; dstLen = UPRV_LENGTHOF(dst); cpName = name; /* get the charset info */ MIMECSETINFO mimeInfo; mimeInfo.uiCodePage = 0; mimeInfo.uiInternetEncoding =0; pMulti->GetCharsetInfo((wchar_t *)bEnc,&mimeInfo); dwEnc = (mimeInfo.uiInternetEncoding==0)?mimeInfo.uiCodePage:mimeInfo.uiInternetEncoding; } virtual void call(UErrorCode* status){ DWORD dwMode=0; HRESULT err= pMulti->ConvertStringFromUnicode(&dwMode,dwEnc,src,&srcLen,dst, &dstLen); getErr(err,*status); } virtual long getOperationsPerIteration(void){ return srcLen; } }; class ConverterPerformanceTest : public UPerfTest{ public: ConverterPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status); ~ConverterPerformanceTest(); virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par = NULL); UPerfFunction* TestICU_CleanOpenAllConverters(); UPerfFunction* TestICU_OpenAllConverters(); UPerfFunction* TestICU_UTF8_ToUnicode(); UPerfFunction* TestICU_UTF8_FromUnicode(); UPerfFunction* TestWinANSI_UTF8_ToUnicode(); UPerfFunction* TestWinANSI_UTF8_FromUnicode(); UPerfFunction* TestWinIML2_UTF8_ToUnicode(); UPerfFunction* TestWinIML2_UTF8_FromUnicode(); UPerfFunction* TestICU_Latin1_ToUnicode(); UPerfFunction* TestICU_Latin1_FromUnicode(); UPerfFunction* TestWinANSI_Latin1_ToUnicode(); UPerfFunction* TestWinANSI_Latin1_FromUnicode(); UPerfFunction* TestWinIML2_Latin1_ToUnicode(); UPerfFunction* TestWinIML2_Latin1_FromUnicode(); UPerfFunction* TestICU_EBCDIC_Arabic_ToUnicode(); UPerfFunction* TestICU_EBCDIC_Arabic_FromUnicode(); UPerfFunction* TestWinANSI_EBCDIC_Arabic_ToUnicode(); UPerfFunction* TestWinANSI_EBCDIC_Arabic_FromUnicode(); UPerfFunction* TestWinIML2_EBCDIC_Arabic_ToUnicode(); UPerfFunction* TestWinIML2_EBCDIC_Arabic_FromUnicode(); UPerfFunction* TestICU_Latin8_ToUnicode(); UPerfFunction* TestICU_Latin8_FromUnicode(); UPerfFunction* TestWinANSI_Latin8_ToUnicode(); UPerfFunction* TestWinANSI_Latin8_FromUnicode(); UPerfFunction* TestWinIML2_Latin8_ToUnicode(); UPerfFunction* TestWinIML2_Latin8_FromUnicode(); UPerfFunction* TestICU_SJIS_ToUnicode(); UPerfFunction* TestICU_SJIS_FromUnicode(); UPerfFunction* TestWinANSI_SJIS_ToUnicode(); UPerfFunction* TestWinANSI_SJIS_FromUnicode(); UPerfFunction* TestWinIML2_SJIS_ToUnicode(); UPerfFunction* TestWinIML2_SJIS_FromUnicode(); UPerfFunction* TestICU_EUCJP_ToUnicode(); UPerfFunction* TestICU_EUCJP_FromUnicode(); UPerfFunction* TestWinANSI_EUCJP_ToUnicode(); UPerfFunction* TestWinANSI_EUCJP_FromUnicode(); UPerfFunction* TestWinIML2_EUCJP_ToUnicode(); UPerfFunction* TestWinIML2_EUCJP_FromUnicode(); UPerfFunction* TestICU_GB2312_ToUnicode(); UPerfFunction* TestICU_GB2312_FromUnicode(); UPerfFunction* TestWinANSI_GB2312_ToUnicode(); UPerfFunction* TestWinANSI_GB2312_FromUnicode(); UPerfFunction* TestWinIML2_GB2312_ToUnicode(); UPerfFunction* TestWinIML2_GB2312_FromUnicode(); UPerfFunction* TestICU_ISO2022KR_ToUnicode(); UPerfFunction* TestICU_ISO2022KR_FromUnicode(); UPerfFunction* TestWinANSI_ISO2022KR_ToUnicode(); UPerfFunction* TestWinANSI_ISO2022KR_FromUnicode(); UPerfFunction* TestWinIML2_ISO2022KR_ToUnicode(); UPerfFunction* TestWinIML2_ISO2022KR_FromUnicode(); UPerfFunction* TestICU_ISO2022JP_ToUnicode(); UPerfFunction* TestICU_ISO2022JP_FromUnicode(); UPerfFunction* TestWinANSI_ISO2022JP_ToUnicode(); UPerfFunction* TestWinANSI_ISO2022JP_FromUnicode(); UPerfFunction* TestWinIML2_ISO2022JP_ToUnicode(); UPerfFunction* TestWinIML2_ISO2022JP_FromUnicode(); }; #endif