#include <stdio.h>
#include "unicode/uperf.h"
#define INPUT_CAPACITY (1024*1024)
#define INTERMEDIATE_CAPACITY 4096
#define INTERMEDIATE_SMALL_CAPACITY 20
#define OUTPUT_CAPACITY INPUT_CAPACITY
static UChar input[INPUT_CAPACITY];
static UChar output[OUTPUT_CAPACITY];
static char intermediate[INTERMEDIATE_CAPACITY];
static int32_t inputLength, encodedLength, outputLength, countInputCodePoints;
class Command : public UPerfFunction {
private:
Command(const char * name, int32_t buf_cap):name(name),buf_cap(buf_cap){
errorCode=U_ZERO_ERROR;
cnv=ucnv_open(name, &errorCode);
}
public:
static UPerfFunction* get(const char * name, int32_t buf_cap){
Command * t = new Command(name, buf_cap);
if (U_SUCCESS(t->errorCode)){
return t;
} else {
delete t;
return NULL;
}
}
virtual ~Command(){
if(U_SUCCESS(errorCode)) {
ucnv_close(cnv);
}
}
virtual void call(UErrorCode* pErrorCode){
const UChar *pIn, *pInLimit;
UChar *pOut, *pOutLimit;
char *pInter, *pInterLimit;
const char *p;
UBool flush;
ucnv_reset(cnv);
pIn=input;
pInLimit=input+inputLength;
pOut=output;
pOutLimit=output+OUTPUT_CAPACITY;
pInterLimit=intermediate+buf_cap;
encodedLength=outputLength=0;
flush=FALSE;
while(pIn<pInLimit || !flush) {
pInter=intermediate;
flush=(UBool)(pIn==pInLimit);
ucnv_fromUnicode(cnv, &pInter, pInterLimit, &pIn, pInLimit, NULL, flush, pErrorCode);
encodedLength+=(int32_t)(pInter-intermediate);
if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
flush=FALSE;
*pErrorCode=U_ZERO_ERROR;
} else if(U_FAILURE(*pErrorCode)) {
return;
}
p=intermediate;
ucnv_toUnicode(cnv, &pOut, pOutLimit,&p, pInter,NULL, flush,pErrorCode);
if(U_FAILURE(*pErrorCode)) {
return;
}
}
outputLength=pOut-output;
if(inputLength!=outputLength) {
fprintf(stderr, "error: roundtrip failed, inputLength %d!=outputLength %d\n", inputLength, outputLength);
*pErrorCode=U_INTERNAL_PROGRAM_ERROR;
}
}
virtual long getOperationsPerIteration(){
return countInputCodePoints;
}
const char * name;
int32_t buf_cap;
UErrorCode errorCode;
UConverter *cnv;
};
class UtfPerformanceTest : public UPerfTest{
public:
UtfPerformanceTest(int32_t argc, const char *argv[], UErrorCode &status) :UPerfTest(argc,argv,status){
getBuffer(inputLength, status);
u_strncpy(input, buffer, inputLength);
countInputCodePoints = u_countChar32(input, inputLength);
}
virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ){
switch (index) {
case 0: name = "UTF_8"; if (exec) return Command::get("UTF-8", INTERMEDIATE_CAPACITY); break;
case 1: name = "UTF_8_SB"; if (exec) return Command::get("UTF-8",INTERMEDIATE_SMALL_CAPACITY); break;
case 2: name = "SCSU"; if (exec) return Command::get("SCSU", INTERMEDIATE_CAPACITY); break;
case 3: name = "SCSU_SB"; if (exec) return Command::get("SCSU", INTERMEDIATE_SMALL_CAPACITY); break;
case 4: name = "BOCU_1"; if (exec) return Command::get("BOCU-1", INTERMEDIATE_CAPACITY); break;
case 5: name = "BOCU_1_SB"; if (exec) return Command::get("BOCU-1",INTERMEDIATE_SMALL_CAPACITY); break;
default: name = ""; break;
}
return NULL;
}
};
int main(int argc, const char *argv[])
{
UErrorCode status = U_ZERO_ERROR;
UtfPerformanceTest test(argc, argv, status);
if (U_FAILURE(status)){
printf("The error is %s\n", u_errorName(status));
return status;
}
if (test.run() == FALSE){
fprintf(stderr, "FAILED: Tests could not be run please check the "
"arguments.\n");
return -1;
}
return 0;
}