/********************************************************************
 * COPYRIGHT:
 * Copyright (C) 2002-2004 IBM, Inc.   All Rights Reserved.
 *
 ********************************************************************/
/*****************************************************************************
* File stringperf.cpp
*
* Modification History:
* Name                     Description
* Doug Wang				   Second version
* Doug Wang                First Version
******************************************************************************
*/

/** 
 * This program tests UnicodeString performance.
 * APIs tested: UnicodeString
 * ICU4C 
 * Windows 2000/XP
 */

#include "stringperf.h"
#include "uoptions.h"


int main(int argc, const char *argv[])
{
    UErrorCode status = U_ZERO_ERROR;

	bCatenatePrealloc=true;
	if (bCatenatePrealloc) {
		int to_alloc = LOOPS * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN);
		catICU = new UnicodeString(to_alloc,'a',0);

		catStd = new stlstring();
		catStd -> reserve(LOOPS * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN));
	} else {
		catICU = new UnicodeString();
		catStd = new stlstring();
	}

    StringPerformanceTest test(argc, argv, status);
	if (U_FAILURE(status)){
        return status;
    }
    if (test.run() == FALSE){
        fprintf(stderr, "FAILED: Tests could not be run please check the "
			            "arguments.\n");
        return -1;
    }

	delete catICU;
	delete catStd;
    return 0;
}

StringPerformanceTest::StringPerformanceTest(int32_t argc, const char *argv[],
										 UErrorCode &status)
										: UPerfTest(argc, argv, status)
{
	filelines_=NULL;
	StrBuffer=NULL;
	StrBufferLen=0;

	int32_t len =0;

	if (status== U_ILLEGAL_ARGUMENT_ERROR){
       fprintf(stderr,gUsageString, "stringperf");
       return;
    }
    if (U_FAILURE(status)){
        fprintf(stderr, "FAILED to create UPerfTest object. Error: %s\n", 
			    u_errorName(status));
        return;
    }


    if(line_mode){
        ULine* filelines = getLines(status);
        if(U_FAILURE(status)){
            fprintf(stderr, "FAILED to read lines from file and create UPerfTest object. Error: %s\n", u_errorName(status));
            return;
        }
		
		filelines_ = new ULine[numLines];
		for (int i =0; i < numLines; i++) {
			len = filelines[i].len;
			filelines_[i].name  = new UChar[len];
            filelines_[i].len   = len;
			memcpy(filelines_[i].name, filelines[i].name, len * U_SIZEOF_UCHAR);
		}
        
    }else if(bulk_mode){
        int32_t srcLen = 0;
        const UChar* src = getBuffer(srcLen,status);
        if(U_FAILURE(status)){
            fprintf(stderr, "FAILED to read buffer from file and create UPerfTest object. Error: %s\n", u_errorName(status));
            return;
        }
		
		StrBuffer = new UChar[srcLen];
		StrBufferLen = srcLen;
		memcpy(StrBuffer, src, srcLen * U_SIZEOF_UCHAR);

    }
}

StringPerformanceTest::~StringPerformanceTest()
{
	delete[] filelines_;
	delete[] StrBuffer;
}

UPerfFunction* StringPerformanceTest::runIndexedTest(int32_t index, UBool exec,
												   const char *&name, 
												   char* par) 
{
    switch (index) {
        TESTCASE(0, TestCtor);
		TESTCASE(1, TestCtor1);
		TESTCASE(2, TestCtor2);
		TESTCASE(3, TestCtor3);
		TESTCASE(4, TestAssign);
		TESTCASE(5, TestAssign1);
		TESTCASE(6, TestAssign2);
		TESTCASE(7, TestGetch);
		TESTCASE(8, TestCatenate);
		TESTCASE(9, TestScan);
		TESTCASE(10, TestScan1);
		TESTCASE(11, TestScan2);

		TESTCASE(12, TestStdLibCtor);
		TESTCASE(13, TestStdLibCtor1);
		TESTCASE(14, TestStdLibCtor2);
		TESTCASE(15, TestStdLibCtor3);
		TESTCASE(16, TestStdLibAssign);
		TESTCASE(17, TestStdLibAssign1);
		TESTCASE(18, TestStdLibAssign2);
		TESTCASE(19, TestStdLibGetch);
		TESTCASE(20, TestStdLibCatenate);
		TESTCASE(21, TestStdLibScan);
		TESTCASE(22, TestStdLibScan1);
		TESTCASE(23, TestStdLibScan2);

        default: 
            name = ""; 
            return NULL;
    }
    return NULL;
}

UPerfFunction* StringPerformanceTest::TestCtor()
{
	if (line_mode) {
		return new StringPerfFunction(ctor, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(ctor, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestCtor1()
{
	if (line_mode) {
		return new StringPerfFunction(ctor1, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(ctor1, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestCtor2()
{
	if (line_mode) {
		return new StringPerfFunction(ctor2, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(ctor2, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestCtor3()
{
	if (line_mode) {
		return new StringPerfFunction(ctor3, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(ctor3, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestAssign()
{
	if (line_mode) {
		return new StringPerfFunction(assign, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(assign, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestAssign1()
{
	if (line_mode) {
		return new StringPerfFunction(assign1, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(assign1, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestAssign2()
{
	if (line_mode) {
		return new StringPerfFunction(assign2, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(assign2, StrBuffer, StrBufferLen, uselen);
	}
}


UPerfFunction* StringPerformanceTest::TestGetch()
{
	if (line_mode) {
		return new StringPerfFunction(getch, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(getch, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestCatenate()
{
	if (line_mode) {
		return new StringPerfFunction(catenate, filelines_, numLines, uselen);
	} else {
		//return new StringPerfFunction(catenate, buffer, bufferLen, uselen);
		return new StringPerfFunction(catenate, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestScan()
{
	if (line_mode) {
		return new StringPerfFunction(scan, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(scan, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestScan1()
{
	if (line_mode) {
		return new StringPerfFunction(scan1, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(scan1, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestScan2()
{
	if (line_mode) {
		return new StringPerfFunction(scan2, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(scan2, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibCtor()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibCtor, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibCtor, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibCtor1()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibCtor1, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibCtor1, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibCtor2()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibCtor2, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibCtor2, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibCtor3()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibCtor3, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibCtor3, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibAssign()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibAssign, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibAssign, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibAssign1()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibAssign1, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibAssign1, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibAssign2()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibAssign2, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibAssign2, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibGetch()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibGetch, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibGetch, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibCatenate()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibCatenate, filelines_, numLines, uselen);
	} else {
		//return new StringPerfFunction(StdLibCatenate, buffer, bufferLen, uselen);
		return new StringPerfFunction(StdLibCatenate, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibScan()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibScan, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibScan, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibScan1()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibScan1, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibScan1, StrBuffer, StrBufferLen, uselen);
	}
}

UPerfFunction* StringPerformanceTest::TestStdLibScan2()
{
	if (line_mode) {
		return new StringPerfFunction(StdLibScan2, filelines_, numLines, uselen);
	} else {
		return new StringPerfFunction(StdLibScan2, StrBuffer, StrBufferLen, uselen);
	}
}