blob: d83538bdbced7651739273e202b8169955cd0aa8 [file] [log] [blame]
/*
**********************************************************************
* Copyright (C) 2002-2005, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* file name: utfperf.cpp
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2005Nov17
* created by: Raymond Yang
*
* Ported from utfper.c created by Markus W. Scherer
* Performance test program for Unicode converters
*/
#include <stdio.h>
#include "unicode/uperf.h"
/* definitions and text buffers */
#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 {
//fprintf(stderr, "error opening converter for \"%s\" - %s\n", name, u_errorName(errorCode));
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) {
/* convert a block of [pIn..pInLimit[ to the encoding in intermediate[] */
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) {
/* in case flush was TRUE make sure that we convert once more to really flush */
flush=FALSE;
*pErrorCode=U_ZERO_ERROR;
} else if(U_FAILURE(*pErrorCode)) {
return;
}
/* convert the block [intermediate..pInter[ back to UTF-16 */
p=intermediate;
ucnv_toUnicode(cnv, &pOut, pOutLimit,&p, pInter,NULL, flush,pErrorCode);
if(U_FAILURE(*pErrorCode)) {
return;
}
/* intermediate must have been consumed (p==pInter) because of the converter semantics */
}
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;
}