windowing/windowserver/test/PARSEINIDATA.CPP
author Faisal Memon <faisal.memon@nokia.com>
Fri, 14 May 2010 15:41:33 +0100
branchNewGraphicsArchitecture
changeset 64 5c983aa672ea
parent 0 5d03bc08d59c
permissions -rw-r--r--
Merge 1. Pull in cpp files in the performance enhanced Khronos RI OVG files which are newly added. I've ignored platform-specific cpp files for linux, macosx, and null operating systems because this local solution has its own platform glue (i.e. facility to target Bitmaps but no full windowing support). I've ignored sfEGLInterface.cpp because this is used as a bridge to go from EGL to Nokia's Platsim which offers an EGL service. That's not relevant to this implementation because this is ARM side code, not Intel side. I just left a comment to sfEGLInterface.cpp in case we need to pick up this later on. The current code compiles on winscw. Prior to this fix, the code works on winscw, and can launch the SVG tiger (tiger.exe). That takes about 20 seconds to render. I hope to always be able to show this icon on each commit, and the plan is for the render time to reduce with this series of submissions. On this commit, the tiger renders ok in 20 seconds.

// Copyright (c) 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:
// Parse the ini file
// 
//

/**
@file
@test
@internalComponent
*/

#include "PARSEINIDATA.H"
#include <f32file.h>
#include <e32std.h>

// Default directory to look for INI file
_LIT(KIniFileDir,"Z:\\System\\Data\\");

// Constant Value changed for DEF047130 fix
const TInt KTokenSize = 256;

enum TIniPanic
	{
	ESectionNameTooBig,
	EKeyNameTooBig,
	};

//
void Panic(TIniPanic aPanic)
	{
	_LIT(CIniData,"CIniData");
	User::Panic(CIniData,aPanic);
	}

/**
Constructor
*/
CIniData::CIniData() : iPtr(NULL,0)
	{
	__DECLARE_NAME(_S("CIniData"));
	}

/**
Destructor.
Frees the resources located in second-phase constructor
*/
CIniData::~CIniData()
	{
	delete (TText*)iPtr.Ptr();
	delete iToken;
	delete iName;
	}

/**
 Creates, and returns a pointer to CIniData object, leave on failure
 @param aName the name of the file which contains the ini data
 @param aDelimeter	Delimiter used in wsini.ini file between variable and value
 @return A pointer to the CiniData object
*/
CIniData* CIniData::NewL(const TDesC& aName, char aDelimiter)
	{
	CIniData* p = new(ELeave) CIniData;
	CleanupStack::PushL(p);
	p->ConstructL(aName, aDelimiter);
	CleanupStack::Pop();
	return p;
	}

/**
 Second-phase constructor.
 The function attempts to allocate a buffer and Read file's contents into iPtr
 @param aName the name of the file which contains the ini data
 @param aDelimeter	Delimiter used in wsini.ini file between variable and value
 @leave One of the system-wide error codes
*/
void CIniData::ConstructL(const TDesC& aName, char aDelimiter)
	{
	//Set delimiter
	iDelimiter = aDelimiter;
	
 	// Allocate space for token
	iToken=HBufC::NewL(KTokenSize+2);	// 2 extra chars for [tokenName]

	// Connect to file server
	TAutoClose<RFs> fs;
	User::LeaveIfError(fs.iObj.Connect());
	fs.PushL();

	// Find file, given name
	TFindFile ff(fs.iObj);
	User::LeaveIfError(ff.FindByDir(aName, KIniFileDir));
	iName = ff.File().AllocL();

	// Open file
	TAutoClose<RFile> file;
	TInt size;
	User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileShareReadersOrWriters));
	file.PushL();

	// Get file size and read in
	User::LeaveIfError(file.iObj.Size(size));
	TText* data = (TText*)User::AllocL(size);
	iPtr.Set(data, size/sizeof(TText), size/sizeof(TText));
	TPtr8 dest((TUint8*)data, 0, size);
	User::LeaveIfError(file.iObj.Read(dest));
	TUint8* ptr = (TUint8*)data;

	//
	// This is orderred as FEFF assuming the processor is Little Endian
	// The data in the file is FFFE.		PRR 28/9/98
	//
	if(size>=(TInt)sizeof(TText) && iPtr[0]==0xFEFF)
	{
		// UNICODE Text file so lose the FFFE
		Mem::Copy(ptr, ptr+sizeof(TText), size-sizeof(TText));
		iPtr.Set(data, size/sizeof(TText)-1, size/sizeof(TText)-1);
	}
	else if(size)
	{
		// NON-UNICODE so convert to UNICODE
		TText* newdata = (TText*)User::AllocL(size*sizeof(TText));
		iPtr.Set(newdata, size, size);
		TInt i;
		for(i = 0 ; i<size ; ++i)
			iPtr[i] = ptr[i];
		delete data;
	}

	file.Pop();
	fs.Pop();
}

/**
Find a text value from given aKeyName regardless the section in the ini data file
@param aKeyName Key being searched for
@param aResult On return, contains the text result 
@return ETrue if found, otherwise EFalse
*/
TBool CIniData::FindVar(const TDesC& aKeyName, TPtrC& aResult)
	{
	// Call with no section, so starts at beginning
	if (FindVar((TDesC&)KNullDesC , aKeyName, aResult))
		return(ETrue);
	else
		return(EFalse);
	}

/**
Find a text value from given aKeyName and aSecName in the ini data file
@param aSectName Section containing key
@param aKeyName Key being searched for in aSectName
@param aResult On return, contains the text result 
@return ETrue if found, otherwise EFalse
*/
TBool CIniData::FindVar(const TDesC& aSectName,const TDesC& aKeyName,TPtrC& aResult)
	{

	__ASSERT_DEBUG(aSectName.Length()<=KTokenSize,Panic(ESectionNameTooBig));
	__ASSERT_DEBUG(aKeyName.Length()<=KTokenSize,Panic(EKeyNameTooBig));

	TInt posStartOfSection(0);
	TInt posEndOfSection(iPtr.Length()); // Default to the entire length of the ini data
	TPtrC SearchBuf;

	// If we have a section, set pos to section start
	TInt posI(0);	// Position in internal data Buffer
	if( aSectName.Length() > 0 )
		{
		TBool FoundSection(false);
		while ( ! FoundSection )
			{
			// Move search buffer to next area of interest
			SearchBuf.Set(iPtr.Mid(posI));

			// Make up token "[SECTIONNAME]", to search for
			TPtr sectionToken = iToken->Des();
			_LIT(sectionTokenFmtString,"[%S]");
			sectionToken.Format(sectionTokenFmtString,&aSectName);

			// Search for next occurrence of aSectName
			TInt posSB = SearchBuf.Find(sectionToken);

			if (posSB == KErrNotFound)
				return(EFalse);

			// Check this is at beginning of line (ie. non-commented)
			// ie. Check preceding char was LF
			if(posSB>0)
				{
				// Create a Buffer, starting one char before found subBuf
				TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1));
				// Check first char is end of prev
				if(CharBefore[0] == '\n')
					{
					FoundSection = ETrue;		// found
					posI = posI + posSB;
					}
				else
					{
					posI = posI + posSB + 1;	// try again
					}
				}
			else
				{
				FoundSection = ETrue;
				}

			}	// while ( ! FoundSection ) 

		// Set start of section, after section name, (incl '[' and ']')
		posStartOfSection = posI + aSectName.Length() + 2;

		// Set end of section, by finding begin of next section or end
		SearchBuf.Set(iPtr.Mid(posI));
		_LIT(nextSectionBuf,"\n[");
		TInt posSB = SearchBuf.Find(nextSectionBuf);
		if(posSB != KErrNotFound)
			{
			posEndOfSection = posI + posSB;
			}
		else
			{
			posEndOfSection = iPtr.Length();
			}

		}	// if( aSectName.Length() > 0 )

	// Look for key in ini file data Buffer
	posI = posStartOfSection;
	TBool FoundKey(false);
	while ( ! FoundKey )
		{
		// Search for next occurrence of aKeyName
		SearchBuf.Set(iPtr.Mid(posI,posEndOfSection-posI));
		TInt posSB = SearchBuf.Find(aKeyName);

		// If not found, return
		if (posSB == KErrNotFound)
			return(EFalse);

		// Check this is at beginning of line (ie. non-commented)
		// ie. Check preceding char was CR or LF
		if(posSB>0)
			{
			// Create a Buffer, starting one char before found subBuf
			TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1));
			// Check if the first char is end of prev and also check 
			// if the token found is not a substring of another string  
			TBool beginningOK = ((CharBefore[0] == '\n') || (CharBefore[0] == ' ') || (CharBefore[0] == '\t'));
			TBool endingOK = ((CharBefore[aKeyName.Length()+1] == iDelimiter) || (CharBefore[aKeyName.Length()+1] == ' ') || (CharBefore[aKeyName.Length()+1] == '\t'));
			if (beginningOK && endingOK)
				{
				FoundKey = ETrue;
				posI = posI + posSB;
				}
			else
				{
				posI = posI + posSB + 1;
				}
			}
		else
			{
			FoundKey = ETrue;
			}
		}	// while ( ! FoundKey )

	// Set pos, to just after iDelimiter sign
	SearchBuf.Set(iPtr.Mid(posI));
	TInt posSB = SearchBuf.Locate(iDelimiter);
	if(posSB==KErrNotFound)		// Illegal format, should flag this...
		return(EFalse);

	// Identify start and end of data (EOL or EOF)
	posI = posI + posSB + 1;	// 1 char after iDelimiter
	TInt posValStart = posI;
	TInt posValEnd;
	SearchBuf.Set(iPtr.Mid(posI));
	posSB = SearchBuf.Locate('\r');
	if(posSB != KErrNotFound)
		{
		posValEnd = posI + posSB;
		}
	else
		{
		posValEnd = iPtr.Length();
		}

	// Check we are still in the section requested
	if( aSectName.Length() > 0 )
		{
		if( posValEnd > posEndOfSection )
			{
			return(EFalse);
			}
		}
	// Parse Buffer from posn of key
	// Start one space after '='
	TLex lex(iPtr.Mid(posValStart, posValEnd-posValStart));
	lex.SkipSpaceAndMark();		// Should be at the start of the data
	aResult.Set(lex.MarkedToken().Ptr(),posValEnd-posValStart - lex.Offset() );
	return(ETrue);
	}

/**
Find an integer value from given aKeyName regardless the section in the ini data file
@param aKeyName Key being searched for
@param aResult On return, contains the TInt result 
@return ETrue if found, otherwise EFalse
*/
TBool CIniData::FindVar(const TDesC& aKeyName, TInt& aResult)
	{
	TPtrC ptr(NULL,0);
	if (FindVar(aKeyName,ptr))
		{
		TLex lex(ptr);
		if (lex.Val(aResult) == KErrNone)
			return(ETrue);
		}
	return(EFalse);
	}

/**
Find an integer value from given aKeyName and aSecName in the ini data file
@param aSectName Section containing key
@param aKeyName Key being searched for  in aSectName
@param aResult On return, contains TInt result 
@return ETrue if found, otherwise EFalse
*/
TBool CIniData::FindVar(const TDesC& aSection,const TDesC& aKeyName,TInt& aResult)
	{
	TPtrC ptr(NULL,0);
	if (FindVar(aSection,aKeyName,ptr))
		{
		TLex lex(ptr);
		if (lex.Val(aResult) == KErrNone)
			return(ETrue);
		}
	return(EFalse);
}