applayerprotocols/httptransportfw/Test/t_utils/ScriptFile.cpp
changeset 0 b16258d2340f
child 19 c0c2f28ace9c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/t_utils/ScriptFile.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,444 @@
+// Copyright (c) 2001-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:
+//
+
+#include "TestScripts.h"
+#include "httptestutils.h"
+
+EXPORT_C CScriptFile* CScriptFile::NewL(CHTTPTestUtils& aTestUtils, const TDesC& aComponent, const TDesC& aScript)
+	{
+	CScriptFile* self = NewLC(aTestUtils, aComponent, aScript);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CScriptFile* CScriptFile::NewLC(CHTTPTestUtils& aTestUtils, const TDesC& aComponent, const TDesC& aScript)
+	{
+	CScriptFile* self = NewLC(aTestUtils, aComponent);
+	self->ReadScriptL(aScript);
+	return self;
+	}
+
+EXPORT_C CScriptFile* CScriptFile::NewL(CHTTPTestUtils& aTestUtils, const TDesC& aComponent)
+	{
+	CScriptFile* self = NewLC(aTestUtils, aComponent);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CScriptFile* CScriptFile::NewLC(CHTTPTestUtils& aTestUtils, const TDesC& aComponent)
+	{
+	CScriptFile* self = new (ELeave) CScriptFile(aTestUtils);
+	CleanupStack::PushL(self);
+	self->ConstructL(aComponent);
+	return self;
+	}
+
+void CScriptFile::ConstructL(const TDesC& aComponent)
+	{
+	iSections = new (ELeave) CArrayPtrFlat<CScriptSection>(10);
+	iComponent = aComponent.AllocL();
+	}
+
+CScriptFile::CScriptFile(CHTTPTestUtils& aTestUtils)
+: iTestUtils(aTestUtils)
+	{
+	}
+
+EXPORT_C CScriptFile::~CScriptFile()
+	{
+	if (iSections)
+		{
+		iSections->ResetAndDestroy();
+		delete iSections;
+		}
+
+	delete iComponent;
+	}
+
+CScriptSection* CScriptFile::Section(const TDesC& aSectionName)
+	{
+	CScriptSection* section = iLastSection;
+
+	if (!iLastSection || iLastSection->SectionName().CompareF(aSectionName) != 0)
+		{
+		const TInt count = iSections->Count();
+		
+		for (TInt i = 0; i < count; i++) //order important
+			{
+			section = iSections->At(i);
+			iLastSection = section;
+
+			if (iLastSection->SectionName().CompareF(aSectionName) == 0)
+				{
+				break;
+				}
+			else
+				{
+				section = NULL;
+				}
+			}
+		}
+
+	return section;
+	}
+
+EXPORT_C const TDesC& CScriptFile::ItemValue(const TDesC& aSection, const TDesC& aItem, const TDesC& aDefault)
+	{
+	CScriptSection* section = Section(aSection);
+
+	if (section != NULL)
+		return section->ItemValue(aItem, aDefault);
+
+	return aDefault;
+	}
+
+EXPORT_C TInt CScriptFile::ItemValue(const TDesC& aSection, const TDesC& aItem, const TInt aDefault)
+	{
+	TInt output = aDefault;
+	CScriptSection* section = Section(aSection);
+
+	if (section != NULL)
+		{
+		output = section->ItemValue(aItem, aDefault);
+		}
+
+	return output;
+	}
+		
+EXPORT_C HBufC* CScriptFile::ItemValueLC(CHTTPTestUtils& aTestUtils, const TDesC& aComponent, const TDesC& aScript, const TDesC& aSection, const TDesC& aItem, const TDesC& aDefault)
+	{
+	CScriptFile* self = NewLC(aTestUtils, aComponent, aScript);
+	TPtrC output(self->ItemValue(aSection, aItem, aDefault));
+	HBufC* buf = output.AllocL();
+	CleanupStack::PopAndDestroy(self);
+	CleanupStack::PushL(buf);
+	return buf;
+	}
+
+EXPORT_C TInt CScriptFile::ItemValueL(CHTTPTestUtils& aTestUtils, const TDesC& aComponent, const TDesC& aScript, const TDesC& aSection, const TDesC& aItem, const TInt aDefault)
+	{
+	CScriptFile* self = NewLC(aTestUtils, aComponent, aScript);
+	TInt output = self->ItemValue(aSection, aItem, aDefault);
+	CleanupStack::PopAndDestroy(self);
+	return output;
+	}
+
+HBufC8* CScriptFile::ReadFileL(const TDesC& aFile) const
+	{
+	HBufC8* ret = iTestUtils.ReadFileLC(aFile);
+	CleanupStack::Pop(ret);
+	return ret;
+	}
+
+HBufC* CScriptFile::ReadFileLC(const TDesC& aScript) const
+	{
+	HBufC8* file = NULL;
+
+	TRAPD(err, file = ReadFileL(aScript));
+
+	if (err)
+		{
+		TParse fileOut;
+		err = iTestUtils.ResolveFile(*iComponent, aScript, fileOut);
+
+		if (err)
+			{
+			iTestUtils.Test().Printf(_L("Cannot read file %S. Error=%d"), &aScript, err);
+			User::Leave(err);
+			}
+
+		file = ReadFileL(fileOut.FullName());
+		}
+
+	CleanupStack::PushL(file);
+
+	HBufC* buf = HBufC::NewL(file->Length());
+	buf->Des().Copy(*file);
+	CleanupStack::PopAndDestroy(file);
+	CleanupStack::PushL(buf);
+	return buf;
+	}
+
+EXPORT_C void CScriptFile::ReadScriptL(const TDesC& aScript)
+	{
+	iSections->ResetAndDestroy();
+	ParseScriptSectionsL(aScript, KErrNotFound);
+	}
+
+void CScriptFile::ParseEmbeddedScriptsL(CScriptSection& aSection, TInt aInsertIndex)
+	{
+	// This must be a Script section
+	__ASSERT_DEBUG(aSection.SectionName().CompareF(KScriptsSection)==0, User::Invariant());
+	
+	// Loop through the script section and load and parse each script file in reverse
+	// order so that the sections are inserted in the correct order
+	TInt scriptCount = aSection.Items().Count();
+	for(TInt ii=scriptCount-1; ii>=0; --ii)
+		{
+		CScriptSectionItem& item = aSection.Item(ii);
+		
+		// Sometimes comments are included as part of the value. We need to include
+		// some simple parsing here to extract just the filename from the value
+		// by just including the text upto a '\n' or ' ' characters.
+		TPtrC fileName(item.Value());
+		TInt locateWhiteSpace = fileName.LocateF('\n');
+		if(locateWhiteSpace>0)
+			fileName.Set(fileName.Left(locateWhiteSpace));
+			
+		locateWhiteSpace = fileName.LocateF(' ');
+		if(locateWhiteSpace>0)
+		fileName.Set(fileName.Left(locateWhiteSpace));
+		
+		ParseScriptSectionsL(fileName, aInsertIndex);
+		}
+	}
+
+void CScriptFile::ParseScriptSectionsL(const TDesC& aScript, TInt aInsertIndex)
+	{
+	iLastSection = NULL;
+
+	CScriptSection* section = NULL;
+	CScriptSectionItem* currentItem = NULL;
+	TInt currentItemStart = 0;
+	CScriptSection* sectionAll = NULL;
+	RArray<TInt> sectionIndexArray;
+	CleanupClosePushL(sectionIndexArray);
+	TInt indexIncrement = 0;		
+	HBufC* scriptContents = ReadFileLC(aScript);
+
+	TLex input(*scriptContents);
+
+	while (!input.Eos())
+		{
+	    input.SkipSpaceAndMark();
+
+		input.SkipCharacters();
+		if ( input.TokenLength() == 0 )    // if valid potential token
+			{
+			break;
+			}
+
+		TPtrC token = input.MarkedToken();
+
+		if (token.CompareF(_L("endscript")) == 0)
+			{
+			break;
+			}
+		else if (token.FindF(KScriptSectionStart) == 0 && token.Length() > 2)
+			{
+			ParseAndSetItemValueL(*scriptContents, input, currentItemStart, currentItem);
+
+			TInt mid = 1;
+			TInt len = token.Length() - 2;
+
+			if (sectionAll)
+				section = CScriptSection::NewLC(token.Mid(mid, len), *sectionAll);
+			else
+				section = CScriptSection::NewLC(token.Mid(mid, len));
+
+			if (!sectionAll && section->SectionName().CompareF(_L("All")) == 0)
+				sectionAll = section;
+			
+			// We have a Scripts section, store its index as we need to track where
+			// it occured so that the scripts can be added in the same location
+			// after the current file has parsed
+			if (section->SectionName().CompareF(KScriptsSection) == 0)
+				{
+				if(aInsertIndex==KErrNotFound)
+					{
+					// Not an embedded script, simple store its index
+					TInt currectSectionsCount = iSections->Count();
+					sectionIndexArray.Append(currectSectionsCount);
+					}
+				else
+					{
+					// An embedded script, calculate the index it should be inserted at
+					TInt currectSectionsCount = indexIncrement+aInsertIndex;
+					sectionIndexArray.Append(currectSectionsCount);
+					}
+				}
+			
+			// Check if the section needs to be inserted at a particular location
+			if(aInsertIndex==KErrNotFound)
+				iSections->AppendL(section);
+			else
+				iSections->InsertL(aInsertIndex + indexIncrement++, section);
+				
+			CleanupStack::Pop(section);
+			}
+		else if (section)
+			{
+			TPtrC itemEnd(KScriptItemEnd);
+
+			if (itemEnd.Length() < token.Length() && token.Right(itemEnd.Length()).CompareF(itemEnd) == 0)
+				{
+				FoundNewItemL(*scriptContents, input, currentItemStart, *section, currentItem);
+				}
+			}
+		}
+
+	ParseAndSetItemValueL(*scriptContents, input, currentItemStart, currentItem);
+	CleanupStack::PopAndDestroy(scriptContents);
+	
+	// We have been tracking where the script sections have been inserted so we
+	// want to load the sections from the embedded script file and insert them
+	// at the same point. This must be done in reverse order so that the index
+	// values of script sections before the current one is maintained.
+	TInt scriptSectionsCount = sectionIndexArray.Count();
+	for( TInt ii=scriptSectionsCount-1; ii>=0; --ii)
+		{
+		TInt indexOfScriptSection = sectionIndexArray[ii];
+		ParseEmbeddedScriptsL(*(iSections->At(indexOfScriptSection)), indexOfScriptSection);
+		}
+	CleanupStack::PopAndDestroy(&sectionIndexArray);
+	}
+
+TPtrC CScriptFile::ParseValue(const TDesC& aText, const TLex& aInput, TInt aCurrentItemStart) const
+	{
+	TInt mid = aCurrentItemStart;
+	TInt len = aInput.MarkedOffset() - mid;
+	TPtrC ret(KNullDesC);
+
+	if (len > 0)
+		ret.Set(aText.Mid(mid, len));
+
+	return ret;
+	}
+
+void CScriptFile::ParseAndSetItemValueL(const TDesC& aText, const TLex& aInput, TInt aCurrentItemStart, CScriptSectionItem*& arCurrentItem)
+	{
+	if (arCurrentItem)
+		{
+		delete arCurrentItem->iValue;
+		arCurrentItem->iValue = NULL;
+		arCurrentItem->iValue = ParseValue(aText, aInput, aCurrentItemStart).AllocL();
+		arCurrentItem->iValue->Des().Trim();
+		ReplaceL(KScriptCRLF, KScriptLF, arCurrentItem->iValue);
+
+		if (arCurrentItem->Item().CompareF(KDefaults) == 0)
+			{
+			CopyInDefaultsL(arCurrentItem->iParent, arCurrentItem->Value());
+			}
+		}
+
+	arCurrentItem = NULL;
+	}
+
+void CScriptFile::FoundNewItemL(const TDesC& aText, TLex& arInput, TInt& arCurrentItemStart, CScriptSection& aSection, CScriptSectionItem*& arCurrentItem)
+	{
+	TPtrC token = arInput.MarkedToken();
+
+	ParseAndSetItemValueL(aText, arInput, arCurrentItemStart, arCurrentItem);
+
+	arInput.SkipSpaceAndMark();
+	arCurrentItemStart = arInput.Offset();
+
+	TPtrC itemEnd(KScriptItemEnd);
+	const TInt length = token.Length() - itemEnd.Length();
+	arCurrentItem = &aSection.ReplaceItemL(token.Left(length), KNullDesC);
+	}
+
+void CScriptFile::CopyInDefaultsL(CScriptSection& aSection, const TDesC& aDefaultFile)
+	{
+	CScriptFile* file = CScriptFile::NewLC(iTestUtils, *iComponent, aDefaultFile);
+
+	TInt count = file->Sections().Count();
+
+	if (count > 0)
+		{
+		CScriptSection& def = *file->Sections()[0];
+		aSection.SetDefaultsL(def);
+		}
+	CleanupStack::PopAndDestroy(file);
+	}
+
+EXPORT_C TInt CScriptFile::GetNextWord(TLex& aInput, TChar aDelimiter, TInt& aOutput)
+	{
+	aOutput = 0;
+	TPtrC string;
+	TInt err = GetNextWord(aInput, aDelimiter, string);
+
+	if (!err)
+		{
+		TLex number(string);
+		err = number.Val(aOutput);
+		}
+
+	return err;
+	}
+
+EXPORT_C TInt CScriptFile::GetNextWord(TLex& aInput, TChar aDelimiter, TPtrC& aOutput)
+	{
+	//Get to the start of the descriptor
+	while (!aInput.Peek().IsAlphaDigit() && aInput.Peek() != '+' && !aInput.Eos() && aInput.Peek() != aDelimiter)
+		aInput.Inc();
+
+	if (aInput.Eos())
+		return KErrNotFound;
+
+	aInput.Mark();
+
+	while (aInput.Peek() != aDelimiter && !aInput.Eos())
+		aInput.Inc();
+
+	aOutput.Set(aInput.MarkedToken());
+
+	if (!aInput.Eos())
+		aInput.SkipAndMark(1);
+
+	return KErrNone;
+	}
+
+EXPORT_C void CScriptFile::ReplaceL(const TDesC& aOld, const TDesC& aNew, HBufC*& rString)
+	{
+	HBufC* repl = ReplaceLC(aOld, aNew, *rString);
+	CleanupStack::Pop(repl);
+	delete rString;
+	rString = repl;
+	}
+
+EXPORT_C HBufC* CScriptFile::ReplaceLC(const TDesC& aOld, const TDesC& aNew, const TDesC& aOldString)
+	{
+	HBufC* rString = aOldString.AllocLC();
+	TInt oldLen = aOld.Length();
+	TInt newLen = aNew.Length();
+
+	if (!oldLen)
+		return rString;
+
+	for (TInt pos = 0; pos < rString->Length(); pos += newLen)
+		{
+		TPtrC ptrC = rString->Mid(pos);
+		TInt find = ptrC.Find(aOld);
+
+		if (find == KErrNotFound)
+			return rString;
+	
+		pos += find;
+
+		if (newLen > oldLen)
+			{
+			rString = rString->ReAllocL(rString->Length() + newLen - oldLen);
+			CleanupStack::Pop();
+			CleanupStack::PushL(rString);
+			}
+
+		TPtr ptr(rString->Des());
+		ptr.Replace(pos, oldLen, aNew);
+		}
+
+	return rString;
+	}
+