⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elementsengine.cpp

📁 最新官方例子,图形,描述副,基本控件,通讯协议,等等,
💻 CPP
字号:
/**
*
* @brief Asynchronous test engine to verify the functionality of the Elements project
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/

// INCLUDE FILES

// Class include
#include "elementsengine.h"

// System includes
#include <e32cons.h>
#include <s32file.h>

// User includes
#include "elementrarray.h"
#include "elementcarray.h"
#include "csvfileloader.h"
#include "chemicalelement.h"


// ===================== CONSTANTS ==========================

_LIT(KMetalsFileName, "C:\\metals.csv");
_LIT(KNonMetalsFileName, "C:\\nonmetals.csv");
_LIT(KSemiMetalsFileName, "C:\\semimetals.csv");
_LIT(KTxtLoaded, "Loaded ");
_LIT(KTxtLoadedReturn, " loaded\n");
_LIT(KTxtSemiMetals, "Semimetals");
_LIT(KTxtNonMetals, "Nonmetals");
_LIT(KTxtMetals, "Metals");
_LIT(KTxtTestFileName, "C:\\elements");
_LIT(KTxtStoreTestFileName, "C:\\elementsstore");
const TInt KPanicLoadFailed = 1;
const TInt KPanicWrongElementCount = 2;
const TInt KPanicSampleElementSymbolInWrongPlace = 3;
const TInt KPanicSampleElementAtomicNumberInWrongPlace = 4;
_LIT(KTxtSampleElementSymbol, "Nd");
const TInt KMaxFeedbackLen = 100;
const TInt KNumberOfCsvFilesToLoad = 3;
const TInt KUidMetalsStreamId = 0x101F613F;
const TInt KUidNonmetalsStreamId = 0x101F6140;
const TInt KUidSemimetalsStreamId = 0x101F6141;
const TInt KExpectedElementCount = 118;


// ================= MEMBER FUNCTIONS =======================

CElementsEngine::CElementsEngine(CConsoleBase& aConsole) :
iConsole(aConsole)
	{
	}

CElementsEngine::~CElementsEngine()
	{
	delete iMetalsCsvFileLoader;
	delete iNonMetalsCsvFileLoader;
	delete iSemiMetalsCsvFileLoader;
	delete iElementList;
	delete iStore;
	delete iRootDictionary;
	iFs.Close();
	}

CElementsEngine* CElementsEngine::NewLC(CConsoleBase& aConsole)
	{
	CElementsEngine* self = new (ELeave) CElementsEngine(aConsole);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CElementsEngine* CElementsEngine::NewL(CConsoleBase& aConsole)
	{
	CElementsEngine* self = CElementsEngine::NewLC(aConsole);
	CleanupStack::Pop(self);
	return self;
	}

void CElementsEngine::ConstructL()
	{
	User::LeaveIfError(iFs.Connect());
	iElementList = new (ELeave) CElementRArray();
	//iElementList = CElementCArray::NewL();
	}

void CElementsEngine::LoadFromCsvFilesL()
	{
	delete iMetalsCsvFileLoader;
	iMetalsCsvFileLoader = 0;
	iMetalsCsvFileLoader = CCsvFileLoader::NewL(iFs, *iElementList, *this, KMetalsFileName);
	iMetalsCsvFileLoader->Start();

	delete iNonMetalsCsvFileLoader;
	iNonMetalsCsvFileLoader = 0;
	iNonMetalsCsvFileLoader = CCsvFileLoader::NewL(iFs, *iElementList, *this, KNonMetalsFileName);
	iNonMetalsCsvFileLoader->Start();

	delete iSemiMetalsCsvFileLoader;
	iSemiMetalsCsvFileLoader = 0;
	iSemiMetalsCsvFileLoader = CCsvFileLoader::NewL(iFs, *iElementList, *this, KSemiMetalsFileName);
	iSemiMetalsCsvFileLoader->Start();
	}

void CElementsEngine::NotifyElementLoaded(TInt aNewElementIndex)
	{
	//Start with KTxtLoaded...
	TBuf<KMaxFeedbackLen> loadedFeedbackString(KTxtLoaded);
	//...append the name of the new element...
	loadedFeedbackString.Append((iElementList->At(aNewElementIndex)).Name());
	//...append a new line...
	loadedFeedbackString.Append(KTxtNewLine);
	//...and print to the console
	iConsole.Printf(loadedFeedbackString);
	}

void CElementsEngine::NotifyLoadCompleted(TInt aCompletionStatus, const CCsvFileLoader& aLoader)
	{
	__ASSERT_ALWAYS(aCompletionStatus == KErrNone, Panic(KPanicLoadFailed));
	TBuf<KMaxFeedbackLen> completedFeedbackString;

	if (&aLoader == iMetalsCsvFileLoader)
		{
		completedFeedbackString = KTxtMetals;
		}

	else if (&aLoader == iNonMetalsCsvFileLoader)
		{
		completedFeedbackString = KTxtNonMetals;
		}

	else
		{
		completedFeedbackString = KTxtSemiMetals;
		}

	completedFeedbackString.Append(KTxtLoadedReturn);

	iConsole.Printf(completedFeedbackString);

	iFilesCompleted++;

	if (iFilesCompleted == KNumberOfCsvFilesToLoad)
		{
		CActiveScheduler::Stop();	//Loading is completed--stop the scheduler
		TestElementList();			//Carry out some simple tests on the data
		}
	}

void CElementsEngine::TestElementList()
	{
	__ASSERT_ALWAYS(iElementList->NumberOfElements() == KExpectedElementCount, Panic(KPanicWrongElementCount));

	TRAPD(err, iElementList->SortBySymbolL());
	__ASSERT_ALWAYS(!err, Panic(err));
	TInt sampleElementSymbolLocationWhenSortedBySymbol = 0;
	TRAP(err, sampleElementSymbolLocationWhenSortedBySymbol = 
		iElementList->FindElementBySymbolL(KTxtSampleElementSymbol));
	__ASSERT_ALWAYS(!err, Panic(err));
	__ASSERT_ALWAYS(sampleElementSymbolLocationWhenSortedBySymbol == 61,
		Panic(KPanicSampleElementSymbolInWrongPlace));

	TRAP(err, iElementList->SortByAtomicNumberL());
	__ASSERT_ALWAYS(!err, Panic(err));
	TInt sampleElementSymbolLocationWhenSortedByAtomicNumber = 0;
	TRAP(err, sampleElementSymbolLocationWhenSortedByAtomicNumber = 
		iElementList->FindElementBySymbolL(KTxtSampleElementSymbol));
	__ASSERT_ALWAYS(!err, Panic(err));
	__ASSERT_ALWAYS(sampleElementSymbolLocationWhenSortedByAtomicNumber == 59,
		Panic(KPanicSampleElementAtomicNumberInWrongPlace));
	
	TRAP(err, TestElementListStreamingL());
	__ASSERT_ALWAYS(!err, Panic(err));


	//etc...
	}

void CElementsEngine::TestElementListStreamingL()
	{
	RFileWriteStream writeStream;
	User::LeaveIfError(writeStream.Create(iFs, KTxtTestFileName, EFileWrite));
	writeStream.PushL();
	iElementList->ExternalizeL(writeStream);
	writeStream.CommitL();
	writeStream.Pop();
	writeStream.Release();

	iElementList->DeleteAllElements();
	__ASSERT_ALWAYS(iElementList->NumberOfElements() == 0, Panic(KPanicWrongElementCount));

	RFileReadStream readStream;
	User::LeaveIfError(readStream.Open(iFs, KTxtTestFileName, EFileRead));
	readStream.PushL();
	iElementList->InternalizeL(readStream);
	readStream.Pop();
	readStream.Close();

	__ASSERT_ALWAYS(iElementList->NumberOfElements() == KExpectedElementCount, Panic(KPanicWrongElementCount));

	User::LeaveIfError(iFs.Delete(KTxtTestFileName));

	//Now test Stores
	CreateStoreL();
	CreateRootDictionaryL();
	WriteElementsToStoreL();
	WriteRootDictionaryL();

	//Delete all of the elements
	iElementList->DeleteAllElements();
	__ASSERT_ALWAYS(iElementList->NumberOfElements() == 0, Panic(KPanicWrongElementCount));

	//delete the store to free resources before we can delete the file
	delete iStore;
	iStore = 0;

	//Now read them back from the store
	ReadElementsFromStoreL();
	__ASSERT_ALWAYS(iElementList->NumberOfElements() == KExpectedElementCount, Panic(KPanicWrongElementCount));


	User::LeaveIfError(iFs.Delete(KTxtStoreTestFileName));
	}

void CElementsEngine::CreateStoreL()
	{
	CFileStore* store = CDirectFileStore::CreateLC(iFs, KTxtStoreTestFileName, EFileWrite);
	store->SetTypeL(TUidType(store->Layout()));
	CleanupStack::Pop();	//store
	iStore = store;
	}

void CElementsEngine::CreateRootDictionaryL()
	{
	iRootDictionary = CStreamDictionary::NewL();
	}


void CElementsEngine::Panic(TInt aReason)
	{
	_LIT(KTxtElementsPanicCategory, "Elements");
	User::Panic(KTxtElementsPanicCategory, aReason);
	}

void CElementsEngine::WriteElementsToStoreL() const
	{
	//First, write out the different element types to separate streams
	TStreamId metalsStreamId = WriteSpecificElementTypeToStoreL(CChemicalElement::EMetallic);
	TStreamId nonmetalsStreamId = WriteSpecificElementTypeToStoreL(CChemicalElement::ENonmetallic);
	TStreamId semimetalsStreamId = WriteSpecificElementTypeToStoreL(CChemicalElement::ESemimetallic);

	//Now assign their IDs to the dictionary store
	iRootDictionary->AssignL(TUid::Uid(KUidMetalsStreamId), metalsStreamId);
	iRootDictionary->AssignL(TUid::Uid(KUidNonmetalsStreamId), nonmetalsStreamId);
	iRootDictionary->AssignL(TUid::Uid(KUidSemimetalsStreamId), semimetalsStreamId);
	}

void CElementsEngine::ReadElementsFromStoreL()
	{
	//Open the store
	//(Pretend we don't have this already!)
	CFileStore* store = CDirectFileStore::OpenLC(iFs, KTxtStoreTestFileName, EFileRead);

	//Create and internalise the dictionary from the root stream:
	//(Pretend we don't have this already!)
	CStreamDictionary* dictionary = CStreamDictionary::NewLC();
	RStoreReadStream dictionaryStream;
	dictionaryStream.OpenLC(*store, store->Root());	//dictionary stream is the root stream
	dictionaryStream >> *dictionary;	//Stream in the dictionary
	CleanupStack::PopAndDestroy();		//dictionaryStream

	//Now use the dictionary to look up the stream ids
	TStreamId metalsStreamId = dictionary->At(TUid::Uid(KUidMetalsStreamId));
	TStreamId nonmetalsStreamId = dictionary->At(TUid::Uid(KUidNonmetalsStreamId));
	TStreamId semimetalsStreamId = dictionary->At(TUid::Uid(KUidSemimetalsStreamId));
	CleanupStack::PopAndDestroy(dictionary);

	//Read in each stream
	RStoreReadStream stream;
	stream.OpenLC(*store, metalsStreamId);
	stream >> *iElementList;		//Cleanup stack used because >> can leave!
	CleanupStack::PopAndDestroy();	//stream

	stream.OpenLC(*store, nonmetalsStreamId);
	stream >> *iElementList;		//Cleanup stack used because >> can leave!
	CleanupStack::PopAndDestroy();	//stream

	stream.OpenLC(*store, semimetalsStreamId);
	stream >> *iElementList;		//Cleanup stack used because >> can leave!
	CleanupStack::PopAndDestroy();	//stream

	CleanupStack::PopAndDestroy(store);
	}

void CElementsEngine::WriteRootDictionaryL() const
	{
	RStoreWriteStream root;
	TStreamId id = root.CreateLC(*iStore);
	root << *iRootDictionary;
	root.CommitL();
	CleanupStack::PopAndDestroy();	//root
	iStore->SetRootL(id);
	iStore->CommitL();
	}

TStreamId CElementsEngine::WriteSpecificElementTypeToStoreL(CChemicalElement::TElementType aElementType) const
	{
	//First make an element list containing only the specified element type
	//(Could just use an RArray "raw," but then I'd have to write my own exernalizer!)
	CElementList* list = new (ELeave) CElementRArray;
	CleanupStack::PushL(list);

	for (TInt i = 0; i < iElementList->NumberOfElements() ;i++)
		{
		const CChemicalElement& element = iElementList->At(i);
		if (element.Type() != aElementType)
			{
			//Not the right type
			continue;
			}

		//Now make a copy of this element
		CChemicalElement* copy = CChemicalElement::NewLC(element.Name(), element.Symbol(),
			element.AtomicNumber(), element.RelativeAtomicMass(), aElementType, element.Radioactive());
		list->AppendL(copy);
		CleanupStack::Pop(copy);	//Ownership transferred to list which is already on stack
		}

	//Now we have a list with its own copies, we can externalise it
	RStoreWriteStream stream;
	TStreamId id = stream.CreateLC(*iStore);
	stream << *list;
	stream.CommitL();

	//deleting list is safe, since it has its own copies of the elements!
	CleanupStack::PopAndDestroy(2, list);	//stream, list
	return id;
	}


// End of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -