--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/legacyminidomparser/xmlparser/test/t_smiltranslatortest.cpp Mon Sep 13 13:16:40 2010 +0530
@@ -0,0 +1,1219 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This file contains the Console Test Harness for testing the SMILTranslator .dll
+// It carries this out by searching for all files of a certain type (as specified by
+// KWildName) that reside in a given set of directories (as specified by KInputPathList)
+// It then passes each file through a Parser object, picks up the resultant Document
+// object and passes this straight back to the composer object. Output is a new XML
+// file of the same name but different directory (same as initial directory but with
+// KTestFindStr replaced by KTestReplaceStr & KTestReplaceStr2) - these directories are
+// created automatically. The application then reports any errors for each file before
+// moving onto the next one. These error reports are copied to the console screen (but
+// usually too fast to read); to the output window in developer studio; and to a flat
+// file (named and located as specified in KErrorFileName)
+// There are 3 types of test that may be run. The Basic test merely
+// translates all input files to output files. The Performance test does the same thing
+// multiple times (as specified by KPerformanceTestIterations), although the log file
+// output will only relate to the last run. Finally the Memory test utilises the Heap
+// Allocation Failure tool to incrementally run and progressively fail at each and every
+// attempt to allocate memory, it's finally run should complete successfully to prove
+// that no memory leaks have occurred in spite of X hundreds of previously failed runs.
+// Note that this finally test should be done with a much reduced number of files
+// residing in the input directories.
+// The application can test ASCII or Unicode input and output (4 combinations possible).
+// To vary the input you must manually add ASCII or Unicode files to the input
+// directories.
+// The tests can be run automatically or interactively:
+// For interactive tests, run with '-i as follows:
+// SMILTRANSLATORTEST.EXE -i
+// To run with out user interaction, please see the following examples:
+// SMILTRANSLATORTEST.EXE -h # show command line help
+// SMILTRANSLATORTEST.EXE # runs with default options
+// SMILTRANSLATORTEST.EXE -file_type ascii -data_mode file -test_type basic # same as above
+// SMILTRANSLATORTEST.EXE -use_file_handles # msgapi2 only
+// SMILTRANSLATORTEST.EXE -use_full_paths # msgapi2 only
+// SMILTRANSLATORTEST.EXE -test_type performance -performance_iteratons 3 # performance test with 3 iterations
+//
+//
+
+/**
+ @file
+*/
+
+//#define DEBUG_SMILTRANSLATORTEST_
+
+#include <e32test.h>
+#include <e32std.h>
+#include <f32file.h>
+#include <txtetext.h>
+#include <gmxmlparser.h>
+#include <gmxmlcomposer.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "t_smildtdenum.h"
+#endif
+#include "t_SmilDtd.h"
+#include <bacline.h>
+
+// Constants
+_LIT(KErrorFileName,"c:\\legacyminidomparsertest\\SMIL_Test_Files\\ErrorLog.txt");
+_LIT(KParseError," Parse File error = ");
+_LIT(KComposeError," Compose File error = ");
+_LIT(KOutputNewLine,"\r\n");
+_LIT(KStartFile,"Starting test of file ");
+_LIT(KTxtAsciiOrUnicode,"Unicode (F1), Ascii (F2) or Utf-8 (F3) output?");
+_LIT(KTxtBufferOrFile,"\nTest file API (F1), test buffer API (F2)");
+_LIT(KTxtChooseTest,"\nPress:\nF1 (or any other key) for Basic test\nF2 for Performance test\nF3 for Memory Allocation test");
+_LIT(KSmilTranslatorTest,"Smil Translator");
+_LIT(KInputPathList, "c:\\legacyminidomparsertest\\SMIL_Test_Files\\SMIL_Input\\Valid\\;c:\\legacyminidomparsertest\\SMIL_Test_Files\\MMS_Input\\Valid\\;c:\\legacyminidomparsertest\\SMIL_Test_Files\\SMIL_Input\\Invalid\\;c:\\legacyminidomparsertest\\SMIL_Test_Files\\MMS_Input\\Invalid\\;");
+_LIT(KTestFindStr, "_Input\\");
+_LIT(KTestReplaceStr, "_Output\\");
+_LIT(KWildName, "*.txt"); // read all file that match *.txt
+_LIT(KOptionI, "-i"); // unary: interactive mode
+_LIT(KOptionH, "-h");
+// note: traditional style args "--file-type" don't work with the CCommandLineArguments class
+_LIT(KOptionFileType, "-file_type"); // binary: ascii, utf8, unicode
+_LIT(KOptionDataMode, "-data_mode"); // binary: buffer, file
+_LIT(KOptionTestType, "-test_type"); // binary: basic, performance, memory
+_LIT(KOptionPerformanceIterations, "-performance_iterations"); // binary: <number of iterations>
+_LIT(KOptionUseFileHandles, "-use_file_handles"); // unary: use file handles as input
+_LIT(KOptionUseFullPaths, "-use_full_paths"); // unary: use full paths as input
+_LIT(KTxtChooseFileInput, "Choose input file type: Using file path (F1), Using file handle (F2)?");
+
+// Globals
+LOCAL_D CTrapCleanup* theCleanup;
+LOCAL_D CActiveScheduler* scheduler;
+LOCAL_D RTest test(KSmilTranslatorTest);
+LOCAL_D RFs fileSystem;
+class CTestConfig;
+LOCAL_D CTestConfig* testConfig;
+
+//
+// TestConfig
+class CTestConfig : public CBase
+ {
+public:
+ typedef enum {EBasic, EPerformance, EMemory} TTestType;
+ typedef enum {EFileData, EBufferData} TXMLDataMode;
+ static CTestConfig* NewLC();
+ ~CTestConfig() {}
+
+ TInt ProcessCommandLineL();
+ void InteractiveMode();
+
+ // accessors
+ TBool NeedsHelp() const {return iNeedsHelp; }
+ TBool IsInteractive() const {return iIsInteractive; }
+ TXMLFileType FileType() const {return iFileType; }
+ TXMLDataMode DataMode() const {return iDataMode; }
+ TTestType TestType() const {return iTestType; }
+ TInt PerformanceTestIterations() const {return iPerformanceTestIterations; }
+
+ // display
+ void DisplayHelp();
+ void UseageErr();
+ void Dump();
+
+ TBool UseFileHandles() const {return iUseFileHandles; }
+
+
+private:
+ void ConstructL();
+ TBool UnaryArgPresent(CCommandLineArguments* aArgs,TInt aArgCount, const TDesC& aOption);
+ TInt ExtractBinaryArg(CCommandLineArguments* aArgs,TInt aArgCount, const TDesC& aOption,TBuf<32>& aBuf);
+
+ TBool FileTypeFromStr(const TBuf<32>& aFileType);
+ TBool DataModeFromStr(const TBuf<32>& aDataMode);
+ TBool TestTypeFromStr(const TBuf<32>& aTestType);
+private:
+ TBool iNeedsHelp;
+ TBool iIsInteractive;
+ TXMLFileType iFileType;
+ TTestType iTestType;
+ TXMLDataMode iDataMode;
+ TInt iPerformanceTestIterations;
+ TBool iUseFileHandles;
+ };
+
+void CTestConfig::ConstructL()
+ {
+ iNeedsHelp=EFalse;
+ iIsInteractive=EFalse;
+ iFileType=EAscii;
+ iTestType=EBasic;
+ iDataMode=EFileData;
+ iPerformanceTestIterations=100;
+ iUseFileHandles = EFalse;
+ }
+
+CTestConfig* CTestConfig::NewLC()
+ {
+ CTestConfig* self=new(ELeave)CTestConfig();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+TBool CTestConfig::FileTypeFromStr(const TBuf<32>& aFileType)
+ {
+ TBool found=ETrue;
+ if(aFileType.Compare(_L("ascii"))==0)
+ {
+ iFileType=EAscii;
+ }
+ else if(aFileType.Compare(_L("utf8"))==0)
+ {
+ iFileType=EUtf8;
+ }
+ else if (aFileType.Compare(_L("unicode"))==0)
+ {
+ iFileType=EUnicode;
+ }
+ else
+ {
+ found=EFalse;
+ }
+ return found;
+ }
+
+TBool CTestConfig::DataModeFromStr(const TBuf<32>& aDataMode)
+ {
+ TBool found=ETrue;
+ if(aDataMode.Compare(_L("buffer"))==0)
+ {
+ iDataMode=EBufferData;
+ }
+ else if(aDataMode.Compare(_L("file"))==0)
+ {
+ iDataMode=EFileData;
+ }
+ else
+ {
+ found=EFalse;
+ }
+ return found;
+ }
+
+TBool CTestConfig::TestTypeFromStr(const TBuf<32>& aTestType)
+ {
+ TBool found=ETrue;
+ if (aTestType.Compare(_L("basic"))==0)
+ {
+ iTestType=EBasic;
+ }
+ else if (aTestType.Compare(_L("performance"))==0)
+ {
+ iTestType=EPerformance;
+ }
+ else if (aTestType.Compare(_L("memory"))==0)
+ {
+ iTestType=EMemory;
+ }
+ else
+ {
+ found=EFalse;
+ }
+ return found;
+ }
+
+void CTestConfig::DisplayHelp()
+ {
+ test.Printf(KOptionH);
+ test.Printf(_L("\thelp\r\n"));
+ test.Printf(KOptionI);
+ test.Printf(_L("\tinteractive mode\r\n"));
+ test.Printf(KOptionFileType);
+ test.Printf(_L("\tascii|utf8|unicode\r\n"));
+ test.Printf(KOptionDataMode);
+ test.Printf(_L("\tbuffer-data|file-data\r\n"));
+ test.Printf(KOptionTestType);
+ test.Printf(_L("\tbasic|performance|memory\r\n"));
+ test.Printf(KOptionPerformanceIterations);
+ test.Printf(_L(" N\tthe number of iterations to perform\r\n"));
+ test.Printf(KOptionUseFileHandles);
+ test.Printf(_L("\tuse file handles for the test\r\n"));
+ test.Printf(KOptionUseFullPaths);
+ test.Printf(_L("\tuse file paths for the test\r\n"));
+ }
+
+void CTestConfig::UseageErr()
+ {
+ test.Printf(_L("\r\nUseage Err:\r\n"));
+ DisplayHelp();
+ }
+
+void CTestConfig::Dump()
+ {
+ RDebug::Print(_L("\r\n"));
+ RDebug::Print(_L("SMILTRANSLATORTEST Config Settings:\r\n"));
+ RDebug::Print(_L("===================================\r\n"));
+ RDebug::Print(_L("iNeedsHelp = %d\r\n"),iNeedsHelp);
+ RDebug::Print(_L("iIsInteractive = %d\r\n"),iIsInteractive);
+ RDebug::Print(_L("iFiletype = %d\r\n"),iFileType);
+ RDebug::Print(_L("iTestType = %d\r\n"),iTestType);
+ RDebug::Print(_L("iDataMode = %d\r\n"),iDataMode);
+ RDebug::Print(_L("iPerformanceTestIterations = %d\r\n"),iPerformanceTestIterations);
+ RDebug::Print(_L("iUseFileHanldes = %d\r\n"),iUseFileHandles);
+ }
+
+TBool CTestConfig::UnaryArgPresent(CCommandLineArguments *aArgs, TInt aArgCount, const TDesC& aOption)
+ {
+ TInt i = 1;
+ while ((i<aArgCount)&&aArgs->Arg(i).Compare(aOption))
+ {
+ ++i;
+ }
+ return i<aArgCount;
+ }
+
+TInt CTestConfig::ExtractBinaryArg(CCommandLineArguments *aArgs, TInt aArgCount, const TDesC& aOption,TBuf<32>& aBuf)
+ {
+ TInt err=KErrNotFound;
+ TInt i=0;
+
+ while ((i<aArgCount)&&aArgs->Arg(i).Compare(aOption))
+ {
+ ++i;
+ }
+ if (i<aArgCount)
+ {
+ if (++i<aArgCount)
+ {
+ err=KErrNone;
+ aBuf=aArgs->Arg(i);
+ }
+ else
+ {
+ err=KErrArgument;
+ }
+ }
+ return err;
+ }
+
+void CTestConfig::InteractiveMode()
+ {
+ TKeyCode choice;
+
+ test.Printf(KTxtAsciiOrUnicode);
+ choice=test.Getch();
+
+ if(choice==EKeyHelp)
+ {
+ iFileType=EAscii;
+ }
+ else if(choice==EKeyDial)
+ {
+ iFileType=EUtf8;
+ }
+ else
+ {
+ iFileType=EUnicode;
+ }
+ test.Printf(KTxtBufferOrFile);
+ choice=test.Getch();
+ if(choice==EKeyHelp)
+ {
+ iDataMode=EBufferData;
+ }
+ else
+ {
+ iDataMode=EFileData;
+ }
+
+ // Get user's input on whether to use file paths or file handles for the input files
+ test.Printf(KOutputNewLine());
+ test.Printf(KTxtChooseFileInput());
+ choice=test.Getch();
+ iUseFileHandles=EFalse;
+ if(choice==EKeyHelp) // F2
+ {
+ iUseFileHandles = ETrue;
+ }
+
+ test.Printf(KTxtChooseTest);
+ choice=test.Getch();
+ if(choice==EKeyHelp) // F2
+ {
+ iTestType=EPerformance;
+ }
+ else if (choice==EKeyDial) // F3
+ {
+ iTestType=EMemory;
+ }
+ else // any key
+ {
+ iTestType=EBasic;
+ }
+ }
+
+TInt CTestConfig::ProcessCommandLineL()
+ {
+ // Handle command line arguments
+ CCommandLineArguments* args=CCommandLineArguments::NewLC();
+
+ TInt argCount=args->Count();
+
+ // Search for: "-h"/help parameter
+ if (UnaryArgPresent(args,argCount,KOptionH))
+ {
+ iNeedsHelp = ETrue;
+ CleanupStack::Pop(args);
+ delete args;
+ return KErrNone;
+ }
+
+ // Search for: "-i"/interactive parameter
+ if(UnaryArgPresent(args,argCount,KOptionI))
+ {
+ if (argCount==2)
+ {
+ iIsInteractive=ETrue;
+ }
+ else
+ {
+ UseageErr();
+ }
+ }
+ // Search for: "-usefilehandles" parameter
+ if(UnaryArgPresent(args,argCount,KOptionUseFileHandles))
+ {
+ iUseFileHandles=ETrue;
+ }
+ // Search for: "-usefullpaths" parameter
+ if(UnaryArgPresent(args,argCount,KOptionUseFullPaths))
+ {
+ iUseFileHandles=EFalse;
+ }
+
+ // Search for: --file-type, --data-mode, --test-type
+ TBuf<32> buf;
+ TInt err;
+ if (((err=ExtractBinaryArg(args,argCount,KOptionFileType,buf))==KErrNone)&&(!FileTypeFromStr(buf))||
+ err==KErrArgument)
+ {
+ UseageErr();
+ CleanupStack::PopAndDestroy(args);
+ return KErrArgument;
+ }
+ if (((err=ExtractBinaryArg(args,argCount,KOptionDataMode,buf))==KErrNone)&&(!DataModeFromStr(buf))||
+ err==KErrArgument)
+ {
+ UseageErr();
+ CleanupStack::PopAndDestroy(args);
+ return KErrArgument;
+ }
+ if (((err=ExtractBinaryArg(args,argCount,KOptionTestType,buf))==KErrNone)&&(!TestTypeFromStr(buf))||
+ err==KErrArgument)
+ {
+ UseageErr();
+ CleanupStack::PopAndDestroy(args);
+ return KErrArgument;
+ }
+ if (((err=ExtractBinaryArg(args,argCount,KOptionPerformanceIterations,buf))==KErrNone))
+ {
+ TLex16 lexer(buf.Ptr());
+ TInt iterations;
+ lexer.Val(iterations);
+ iPerformanceTestIterations = iterations;
+ }
+ else if (err==KErrArgument)
+ {
+ UseageErr();
+ CleanupStack::PopAndDestroy(args);
+ return KErrArgument;
+ }
+ CleanupStack::PopAndDestroy(args);
+ return KErrNone;
+ }
+
+//
+
+class CTestDataSupplier : public CBase, public MMDXMLParserDataProvider
+ {
+public:
+ static CTestDataSupplier* NewL(RFs &aRFs, const TDesC& aFileName);
+ ~CTestDataSupplier();
+
+ // From MMDXMLParserDataProvided
+ void GetData(TPtrC8 &aPtr, TRequestStatus &aStatus);
+ void Disconnect();
+
+private:
+ void ConstructL(RFs &aRFs, const TDesC& aFileName);
+
+private:
+ HBufC8* iCurrentChunk;
+ RFile iFile;
+ TInt iChunkSize; // Start at 1, then increment for subsequent chunk
+ };
+
+
+CTestDataSupplier* CTestDataSupplier::NewL(RFs &aRFs, const TDesC& aFileName)
+ {
+ CTestDataSupplier* self = new (ELeave) CTestDataSupplier();
+ CleanupStack::PushL(self);
+ self->ConstructL(aRFs, aFileName);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestDataSupplier::~CTestDataSupplier()
+ {
+ iFile.Close();
+ delete iCurrentChunk;
+ }
+
+// From MMDXMLParserDataProvided
+// TODO: Should GetData be a leaving function? Allows more flexibility to implementations of this funtion?
+void CTestDataSupplier::GetData(TPtrC8 &aPtr, TRequestStatus &aStatus)
+ {
+ // Read the data into the descriptor
+ delete iCurrentChunk;
+ iCurrentChunk = NULL;
+ iCurrentChunk = HBufC8::NewL(iChunkSize);
+ TPtr8 chunk = iCurrentChunk->Des();
+ iFile.Read(chunk, iChunkSize); // Ignore the error code, assume end of file if we haven't read any data.
+
+ TDataProviderResults result;
+
+ if (iCurrentChunk->Length() != 0)
+ {
+ aPtr.Set(*iCurrentChunk);
+ result = KMoreData;
+ }
+ else
+ {
+ // Assume that if we haven't got any data then we're at the end of the stream.
+ result = KDataStreamEnd;
+ }
+
+// iChunkSize++;
+ TRequestStatus *s = &aStatus;
+ User::RequestComplete(s, (TInt)result);
+ return;
+ }
+
+void CTestDataSupplier::Disconnect()
+ {
+ // Don't need to do anything here.
+ }
+
+void CTestDataSupplier::ConstructL(RFs &aRFs, const TDesC& aFileName)
+ {
+ iChunkSize = 1;
+
+ // Open the file that will supply the data
+ User::LeaveIfError(iFile.Open(aRFs, aFileName, EFileRead));
+ }
+
+
+//
+// CSmilTranslatorTestUtils declaration
+//
+
+class CSmilTranslatorTestUtils : public CActive, public MMDXMLParserObserver, public MMDXMLComposerObserver
+ {
+public:
+ static CSmilTranslatorTestUtils* NewLC();
+ ~CSmilTranslatorTestUtils();
+ void ConstructL();
+ void RunTestL();
+ TInt FilesProcessed() const {return iFilesProcessed; }
+
+public: // from CActive
+ void DoCancel();
+ void RunL();
+
+public: // from MMDXMLParserObserver
+ void ParseFileCompleteL();
+
+public: // from MMDXMLComposerObserver
+ void ComposeFileCompleteL();
+
+private:
+ CSmilTranslatorTestUtils();
+ void SetOutputFileName();
+ void AppendErrorStr(TInt aError, TDes& aOutputMsg);
+ void AppendSeverityStr(TInt aSeverity, TDes& aOutputMsg);
+
+private:
+ enum TComposerState
+ {
+ EComposing,
+ ESizing
+ };
+
+ RFs iSession;
+ CMDXMLDocument* iXMLDoc;
+
+
+ CMDXMLParser* iParser;
+ CMDXMLComposer* iComposer;
+ TBuf<255> iInputFileName;
+ TBuf<255> iOutputFileName;
+ TComposerState iComposerState;
+ TInt iSize;
+ RFile iErrorFile;
+ CTestDataSupplier* iDataSupplier;
+
+ // return list of found files used by TFileFinder class
+ CDir* iFileList;
+
+ // buffer for composing the error messages for output to the screen and error file
+ TBuf<255> iOutputMsg;
+
+ TFindFile *iFileFinder;
+
+ TInt iState;
+ TInt iErr;
+ TInt iIndex;
+
+ enum TSmilTestStates
+ {
+ KInit = 0x00,
+ KParseFile,
+ KCheckResults,
+ KEnd
+ };
+
+ TTime iStartTime;
+ TTime iStartComposeTime;
+ TInt64 iComposeTime;
+ TInt iFilesProcessed;
+
+ TBool iUseFileHandle;
+ };
+
+//===================================================================================
+
+//
+// CSmilTranslatorTestUtils definition
+//
+
+CSmilTranslatorTestUtils* CSmilTranslatorTestUtils::NewLC()
+ {
+ CSmilTranslatorTestUtils* self = new (ELeave) CSmilTranslatorTestUtils();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+//===================================================================================
+
+CSmilTranslatorTestUtils::~CSmilTranslatorTestUtils()
+ {
+ delete iFileList;
+ delete iXMLDoc;
+ delete iParser;
+ delete iComposer;
+ iSession.Close();
+ }
+
+//===================================================================================
+
+CSmilTranslatorTestUtils::CSmilTranslatorTestUtils() : CActive(EPriorityStandard), iFileFinder()
+ {
+ }
+
+//===================================================================================
+
+void CSmilTranslatorTestUtils::ConstructL()
+ {
+
+ iSession.Connect();
+ iComposer = CMDXMLComposer::NewL(this);
+#define VALIDATE
+#ifndef VALIDATE
+ iParser = CMDXMLParser::NewL(this);
+#else
+ CSMILDtd* smil = CSMILDtd::NewLC();
+ iParser = CMDXMLParser::NewL(this, smil);
+ CleanupStack::Pop(smil);
+#endif
+
+ iUseFileHandle = testConfig->UseFileHandles();
+
+ iState = KInit;
+ iErr = KErrNone;
+ iStartTime.UniversalTime();
+ iFilesProcessed = 0;
+
+ CActiveScheduler::Add(this);
+
+ TRequestStatus *s = &iStatus;
+ User::RequestComplete(s, KErrNone);
+ SetActive();
+ }
+
+//===================================================================================
+
+void CSmilTranslatorTestUtils::RunL()
+ {
+ RunTestL();
+ }
+
+//===================================================================================
+
+void CSmilTranslatorTestUtils::DoCancel()
+ {
+ }
+
+//===================================================================================
+
+#define DES_AS_8_BIT(str) (TPtrC8((TText8*)((str).Ptr()), (str).Size()))
+
+void CSmilTranslatorTestUtils::RunTestL()
+ {
+ TRequestStatus *s = &iStatus;
+
+ // used to generate a leave if an out of memory error was encountered, specifically
+ // during the memory test loop in E32Main(). This is necessary because leaves in
+ // the .dll Active Object RunL() functions do not return to this application, so
+ // have to be Trapped in the Active objects and translated into an error code.
+ TBool memoryError = EFalse;
+
+ switch(iState)
+ {
+ case KInit:
+ {
+ // Utility class for file manipulation
+ iFileFinder = new TFindFile(iSession);
+
+ TPtrC errorFileName(KErrorFileName);
+
+ // create err dir if doesn't exist - this api ignores the file name (ignores everything after final '/')
+ fileSystem.MkDirAll(KErrorFileName);
+
+ // overwrite any existing file of this name
+ iErr = iErrorFile.Replace(iSession, errorFileName, EFileWrite | EFileStreamText);
+
+ if(iErr == KErrNone)
+ {
+ TBuf<1> bom;
+ bom.Append(CEditableText::EByteOrderMark);
+ iErrorFile.Write(DES_AS_8_BIT(bom));
+ // will search multiple directories, but halt after completing current directory
+ // if at least one match is made. Remembers which directories have been searched
+ // in order to continue search using .FindWild() function later
+ iErr = iFileFinder->FindWildByPath(KWildName, &KInputPathList, iFileList);
+ iIndex = 0;
+ }
+
+ if(iErr == KErrNone)
+ {
+ iState = KParseFile;
+ }
+ else
+ {
+ iState = KEnd;
+ }
+ User::RequestComplete(s, KErrNone);
+ SetActive();
+ }
+ break;
+
+ case KParseFile:
+ {
+ ++iFilesProcessed;
+ iErr = KErrNone;
+
+ TParse fullEntry;
+ fullEntry.Set((*iFileList)[iIndex++].iName,& iFileFinder->File(),NULL);
+ iInputFileName = fullEntry.FullName(); // extract individual path + name from list
+ SetOutputFileName(); // output name is based on input one
+
+ iOutputMsg = KStartFile;
+ iOutputMsg.Append(iInputFileName); // display full path
+ test.Start(iOutputMsg); // print to console
+
+ // test console automatically places output on a new line, for output
+ // to error file we need to add white space ready for next line
+ iOutputMsg.Append(KOutputNewLine);
+ iErrorFile.Write(DES_AS_8_BIT(iOutputMsg)); // print to error file
+
+ // schedule Parser active object for call to it's RunL function
+ if (testConfig->DataMode() == CTestConfig::EBufferData)
+ {
+ // We're testing the buffering API...
+ // Create a data supplier object and pass it in to the parser
+ delete iDataSupplier;
+ iDataSupplier = NULL;
+ iDataSupplier = CTestDataSupplier::NewL(iSession, iInputFileName);
+ iParser->ParseSource(iDataSupplier);
+ }
+ else
+ {
+ if( iUseFileHandle )
+ {
+ RFile file;
+ User::LeaveIfError(file.Open(iSession, iInputFileName, EFileRead | EFileShareReadersOnly));
+ // No function declaration of ParseFile() that take RFile Object parameter
+ // iParser->ParseFile(file);
+ iParser->ParseFile(iSession, iInputFileName);
+ }
+ else
+ {
+ // We're testing the file mode so parse the file.
+ iParser->ParseFile(iSession, iInputFileName);
+ }
+ }
+
+ iState = KCheckResults;
+ iStatus = KRequestPending;
+ SetActive();
+ }
+ break;
+
+ case KCheckResults:
+ {
+ // when execution begins again one parse followed by a compose would have
+ // completed for the current file, handle any error messages generated here
+ iErr = iParser->Error();
+ TInt severity = iParser->ErrorSeverity();
+ if(iErr != KErrNone)
+ {
+ iOutputMsg = KParseError;
+ AppendErrorStr(iErr, iOutputMsg);
+ AppendSeverityStr(severity, iOutputMsg);
+ iOutputMsg.Append(KOutputNewLine);
+
+ // IF there are no more errors for this file bung in an
+ // extra line to make output more prominent
+ if(iComposer->Error() == KErrNone)
+ {
+ iOutputMsg.Append(KOutputNewLine);
+ }
+ test.Printf(iOutputMsg); // print to console
+ iErrorFile.Write(DES_AS_8_BIT(iOutputMsg)); // print to error file
+
+ if(iErr == KErrNoMemory)
+ {
+ memoryError = ETrue;
+ }
+ }
+
+ iErr = iComposer->Error();
+ severity = iComposer->ErrorSeverity();
+ if(iErr != KErrNone)
+ {
+ iOutputMsg = KComposeError;
+ AppendErrorStr(iErr, iOutputMsg);
+ AppendSeverityStr(severity, iOutputMsg);
+ iOutputMsg.Append(KOutputNewLine);
+ iOutputMsg.Append(KOutputNewLine);
+ test.Printf(iOutputMsg);
+ iErrorFile.Write(DES_AS_8_BIT(iOutputMsg));
+
+ if(iErr == KErrNoMemory)
+ {
+ memoryError = ETrue;
+ }
+ }
+
+ test.End();
+
+ // if the OOM condition occured during Parsing or Composing
+ if(memoryError)
+ {
+ User::Leave(KErrNoMemory);
+ }
+
+ iState = KParseFile;
+
+ if(iIndex >= iFileList->Count())
+ {
+ // fileList must be deleted after each loop prior to being passed
+ // back to fileFinder (unnecessary after KErrNotFound)
+ delete iFileList;
+ iFileList = 0; // Just in case it doesn't get set in the FindWild
+
+ // continue wildcard search for next directory in list
+ iErr = iFileFinder->FindWild(iFileList);
+ iIndex = 0;
+ if(iErr != KErrNone)
+ iState = KEnd;
+ }
+
+ SetActive();
+ User::RequestComplete(s, KErrNone);
+ }
+ break;
+
+ default:
+ case KEnd:
+ {
+ TTime endTime;
+ TTimeIntervalSeconds interval;
+ endTime.UniversalTime();
+ endTime.SecondsFrom(iStartTime, interval);
+
+ TBuf<100> time;
+ _LIT(KComposeTime, "Total time for composing: %d microseconds\n");
+ time.Format(KComposeTime, iComposeTime);
+ iErrorFile.Write(DES_AS_8_BIT(time));
+
+ _LIT(KTimeTaken, "Total time for tests: %d seconds");
+ time.Format(KTimeTaken, interval.Int());
+ iErrorFile.Write(DES_AS_8_BIT(time));
+
+
+ delete iFileFinder;
+ delete iDataSupplier;
+ CActiveScheduler::Stop();
+ }
+ break;
+ }
+ }
+
+//===================================================================================
+
+void CSmilTranslatorTestUtils::AppendErrorStr(TInt aError, TDes& aOutputMsg)
+ {
+ switch(aError)
+ {
+ case KErrXMLBadAttributeValue:
+ aOutputMsg.Append(_L("Bad Attribute Value")); break;
+
+ case KErrXMLBadAttributeName:
+ aOutputMsg.Append(_L("Bad Attribute Name")); break;
+
+ case KErrXMLInvalidChild:
+ aOutputMsg.Append(_L("Invalid Child")); break;
+
+ case KErrXMLBadNesting:
+ aOutputMsg.Append(_L("Bad Nesting")); break;
+
+ case KErrXMLIncomplete:
+ aOutputMsg.Append(_L("Incomplete")); break;
+
+ case KErrXMLBadElementName:
+ aOutputMsg.Append(_L("Bad Element Name")); break;
+
+ case KErrXMLDuplicateDocTypeTags:
+ aOutputMsg.Append(_L("Duplicate DocType Tags")); break;
+
+ case KErrXMLDuplicateVersionTags:
+ aOutputMsg.Append(_L("Duplicate Version Tags")); break;
+
+ case KErrXMLDuplicateRootElements:
+ aOutputMsg.Append(_L("Duplicate Root Elements")); break;
+
+ case KErrXMLMissingDocTypeTag:
+ aOutputMsg.Append(_L("Missing DocType Tag")); break;
+
+ case KErrXMLMissingVersionTag:
+ aOutputMsg.Append(_L("Missing Version Tag")); break;
+
+ case KErrXMLDuplicateAttributeName:
+ aOutputMsg.Append(_L("Duplicate Attribute Name")); break;
+
+ case KErrXMLMultipleRootElements:
+ aOutputMsg.Append(_L("Mulitiple Root Elements")); break;
+
+ case KErrXMLCorruptFile:
+ aOutputMsg.Append(_L("Corrupt File")); break;
+
+ case KErrXMLIllegalCharacter:
+ aOutputMsg.Append(_L("Illegal Character")); break;
+
+ case KErrXMLBadEntity:
+ aOutputMsg.Append(_L("Malformed Entity")); break;
+
+ case KErrXMLInvalidElement:
+ aOutputMsg.Append(_L("Invalid Element")); break;
+
+ case KErrXMLInvalidAttribute:
+ aOutputMsg.Append(_L("Invalid Attribute")); break;
+
+ case KErrPathNotFound:
+ aOutputMsg.Append(_L("File Path Not Found")); break;
+
+ case KErrNoMemory:
+ aOutputMsg.Append(_L("Memory Allocation Failure")); break;
+
+ case KErrNotSupported:
+ aOutputMsg.Append(_L("Not Supported")); break;
+
+ default:
+ aOutputMsg.Append(_L("Unknown Error")); break;
+ }
+ }
+
+//===================================================================================
+void CSmilTranslatorTestUtils::AppendSeverityStr(TInt aSeverity, TDes& aOutputMsg)
+ {
+ aOutputMsg.Append(_L(", Severity "));
+ switch(aSeverity)
+ {
+ case EXMLFatal:
+ aOutputMsg.Append(_L("Fatal"));
+ break;
+ case EXMLIndeterminate:
+ aOutputMsg.Append(_L("Indeterminate"));
+ break;
+ case EXMLWorkable:
+ aOutputMsg.Append(_L("Workable"));
+ break;
+ case EXMLNone:
+ aOutputMsg.Append(_L("None"));
+ break;
+ default:
+ aOutputMsg.Append(_L("Unknown"));
+ break;
+ }
+ }
+//===================================================================================
+
+void CSmilTranslatorTestUtils::ParseFileCompleteL()
+// call back function called from Parser::RunL()
+ {
+ // iXMLDoc ends up owned by this class, must delete off the old one on each pass.
+ delete iXMLDoc;
+ iXMLDoc = NULL;
+
+ // get parsed file, don't worry about errors, composer should be robust enough to handle bad files
+ iXMLDoc = iParser->DetachXMLDoc();
+
+ iComposerState = EComposing;
+ TRequestStatus *s = &iStatus;
+
+ iStartComposeTime.UniversalTime();
+
+ // create output dir if doesn't exist - this api ignores the file name (ignores everything after final '/')
+ fileSystem.MkDirAll(iOutputFileName);
+
+ // schedule composer active object for call to it's RunL function
+
+ if( iUseFileHandle )
+ {
+ RFile file;
+ TInt fileError = file.Replace(iSession, iOutputFileName, EFileWrite | EFileStream);
+
+ if( fileError==KErrNone )
+ {
+ // No function declaration of ComposeFile() that take RFile Object parameter
+// iErr = iComposer->ComposeFile(file, iXMLDoc, filetype);
+ iErr = iComposer->ComposeFile(iSession, iOutputFileName, iXMLDoc, testConfig->FileType());
+ }
+ else
+ {
+ // if a file error has occured, we need to set the internal error state
+ // and can only do this by trying to compose again with the filepath so
+ // it fails internally
+ iErr = iComposer->ComposeFile(iSession, iOutputFileName, iXMLDoc, testConfig->FileType());
+ }
+ }
+ else
+ {
+ iErr = iComposer->ComposeFile(iSession, iOutputFileName, iXMLDoc, testConfig->FileType());
+ }
+
+ // we are waiting on this event...
+ User::RequestComplete(s, KErrNone);
+ }
+
+//===================================================================================
+
+void CSmilTranslatorTestUtils::ComposeFileCompleteL()
+// call back function called from Composer::RunL()
+ {
+ TTime timeNow;
+ timeNow.UniversalTime();
+ TTimeIntervalMicroSeconds timeForCompose = timeNow.MicroSecondsFrom(iStartComposeTime);
+ iComposeTime += timeForCompose.Int64();
+
+ if (iComposerState == ESizing)
+ {
+ // Check the size of the file that has been written against the size calulated by the
+ // call to CMDXMLComposer::CalculateFileSize
+
+ RFile outputXMLFile;
+ outputXMLFile.Open(iSession, iOutputFileName, EFileRead);
+
+ TInt actualSize;
+ User::LeaveIfError(outputXMLFile.Size(actualSize));
+
+ if (iSize != actualSize)
+ {
+ // The calculated file size doesn't match the real file size, this test has failed
+ TBuf<255> outputMsg;
+
+ outputMsg.Append(KOutputNewLine);
+ outputMsg.Append(_L("Test Failed - The calculated file size doesn't match the actual size."));
+ outputMsg.Append(KOutputNewLine);
+
+ test.Printf(outputMsg); // print to console
+ iErrorFile.Write(DES_AS_8_BIT(outputMsg)); // print to error file
+ }
+
+ outputXMLFile.Close();
+
+ // If we are sizing then stop the active scheduler. Once the scheduler is stopped
+ // and this function exits, program control resumes where the scheduler was started
+ // in RunTestL.
+// CActiveScheduler::Stop();
+ }
+
+ else if (iComposerState == EComposing)
+ {
+ // The XML file has been composed. Now we need to run the sizing function to check
+ // that we can calculate the size correctly.
+
+ // Set the state to sizing and run the sizing operation...
+ iComposerState = ESizing;
+
+ // Calculate the file size and wait for the callback to this function again.
+ iComposer->CalculateFileSize(iSize, iXMLDoc, testConfig->FileType());
+ }
+ }
+
+//===================================================================================
+
+void CSmilTranslatorTestUtils::SetOutputFileName()
+ {
+ TInt offset;
+
+ iOutputFileName = iInputFileName;
+ if((offset = iOutputFileName.Find(KTestFindStr)) != KErrNotFound)
+ {
+ iOutputFileName.Replace(offset, TPtrC(KTestFindStr).Length(), KTestReplaceStr);
+ }
+ }
+
+//===================================================================================
+
+//
+// TestHarness implementation
+//
+
+
+
+LOCAL_C TInt startTestL()
+ {
+ TInt err = KErrNone;
+
+ // we may need to make some output dirs if they don't already exist
+ fileSystem.Connect();
+
+ scheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL(scheduler);
+ CActiveScheduler::Install( scheduler );
+
+ CSmilTranslatorTestUtils* ttu=CSmilTranslatorTestUtils::NewLC();
+
+ // suspend execution until active object scheduler is finished
+ CActiveScheduler::Start();
+
+ if (ttu->FilesProcessed()==0)
+ err=KErrNotFound;
+
+ fileSystem.Close();
+ CleanupStack::PopAndDestroy(2, scheduler); //scheduler, as well as the object
+ //placed on the stack by CSmilTranslatorTestUtils::NewLC();
+ return err;
+ }
+
+LOCAL_C TInt doMainL()
+ {
+ testConfig = CTestConfig::NewLC();
+
+ // set command line options
+ TInt err=testConfig->ProcessCommandLineL();
+ if(err!=KErrNone)
+ return err;
+
+ // users specified -h: display help to console and abort
+ if (testConfig->NeedsHelp())
+ {
+ testConfig->DisplayHelp();
+ test.Getch();
+ return KErrNone;
+ }
+
+ // user specified -i: let them override settings inside the console
+ if (testConfig->IsInteractive())
+ testConfig->InteractiveMode();
+
+#ifdef DEBUG_SMILTRANSLATORTEST_
+ testConfig->Dump();
+#endif
+
+ TInt returnCode = KErrNone;
+
+ // performance Performance Test
+ if (testConfig->TestType() == CTestConfig::EPerformance)
+ {
+ TInt loopFor = 0;
+ do
+ {
+ loopFor++;
+ returnCode=startTestL(); // Qualified: false leavescan error
+ }
+ while(loopFor!=testConfig->PerformanceTestIterations() && returnCode == KErrNone);
+ }
+ else if (testConfig->TestType()==CTestConfig::EMemory)
+ {
+ TInt after = 0;
+ do
+ {
+ after++;
+ User::__DbgSetAllocFail(RHeap::EUser, RHeap::EDeterministic, after);
+ returnCode=startTestL();
+ }
+ while(returnCode != KErrNone);
+ }
+ // Assume user wants a basic test
+ else
+ {
+ returnCode=startTestL();
+ }
+
+ CleanupStack::Pop(testConfig);
+ return returnCode;
+ }
+void CopyFileL()
+ {
+ RFs fs;
+ fs.Connect();
+ CleanupClosePushL(fs);
+
+ CFileMan* fileMan = CFileMan::NewL(fs);
+ CleanupStack::PushL(fileMan);
+
+ // Do the file copy
+ //User::LeaveIfError(fileMan->Copy(_L("z:\\gmxmltest.txt"),_L("c:\\gmxmltest.txt"),CFileMan::EOverWrite));
+ //User::LeaveIfError(fileMan->Copy(_L("z:\\legacyminidomparsertest"),_L("c:\\legacyminidomparsertest"),CFileMan::EOverWrite|CFileMan::ERecurse));
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+ theCleanup=CTrapCleanup::New();
+ test.Start(_L("Smil Translator"));
+ TRAPD(err,CopyFileL());
+ test(err == KErrNone);
+ TInt returnCode=KErrNone;
+ TRAP(returnCode,returnCode=doMainL());
+ test(returnCode==KErrNone);
+ delete testConfig;
+ delete theCleanup;
+ test.End();
+ test.Close();
+ __UHEAP_MARKEND;
+ User::Heap().Check();
+ return(KErrNone);
+ }
+
+// End Of File