/*
**********************************************************************
* Copyright (c) 2002-2005, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
**********************************************************************
*/
#ifndef _CONVPERF_H
#define _CONVPERF_H
#include <mlang.h>
#include <objbase.h>
#include <stdlib.h>
#include "unicode/ucnv.h"
#include "unicode/uclean.h"
#include "unicode/ustring.h"
#include "unicode/uperf.h"
#define CONVERSION_FLAGS (0) /*WC_DEFAULTCHAR WC_COMPOSITECHECK & WC_SEPCHARS*/
#define MAX_BUF_SIZE 3048
#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
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 = 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 = 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 = 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 = 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 = 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 = 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