/*
**********************************************************************
* Copyright (c) 2002-2003, International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
**********************************************************************
*/
#ifndef _CONVPERF_H
#define _CONVPERF_H

#include "uperf.h"
#include "unicode/ucnv.h"
#include "unicode/ustring.h"
#include <mlang.h>
#include <objbase.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*)uprv_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(){
        uprv_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*)uprv_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(){
        uprv_free(target);
        ucnv_close(conv);
    }
};

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(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(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(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(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(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(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_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

