diff -r 000000000000 -r 5d03bc08d59c windowing/windowserver/nonnga/SERVER/INIFILE.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/windowing/windowserver/nonnga/SERVER/INIFILE.CPP Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,550 @@ +// Copyright (c) 1996-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 +#include "server.h" +#include "inifile.h" + +// uncomment so that if the wsini.ini file is not found on drive Wserv loaded from or drive Z: (if different) +// it will be searched for on drive C: (if different from Wserv's drive) +//#define LOAD_INI_FILE_FROM_DRIVE_Z_OR_C + + +GLREF_D CDebugLogBase *wsDebugLog; + +_LIT(KDefaultSectionName,"DEFAULT"); +_LIT(KCommentMarker,"//"); +_LIT(KScreenSectionName,"SCREEN"); +const TUint16 KNewSection('['); +const TUint16 KSpaceChar(' '); +const TUint16 KNewSection2(']'); +const TInt KDefaultSectionNumber(0); +const TInt KDefaultScreenId(-1); + + +CIniFile::CIniFile() + {} + +CIniFile::~CIniFile() + { + FreeData(); + } + +CIniSection * CIniFile::FindSection(TInt aScreen) + { + for (TInt sect = 0; sect < iSectionArray.Count(); ++sect) + { + if (iSectionArray[sect]->Screen() == aScreen) + { + return iSectionArray[sect]; + } + } + return NULL; + } + +CIniSection * CIniFile::FindSection(const TDesC& aName) + { + for (TInt sect = 0; sect < iSectionArray.Count(); ++sect) + { + if (iSectionArray[sect]->Screen() == KDefaultScreenId && !iSectionArray[sect]->Name().CompareF(aName)) + { + return iSectionArray[sect]; + } + } + return NULL; + } + +/* Processes a .ini file entry section name. + + @return the corresponding index. + @param aLine Input line of text from the .ini file, stripped of comments & excess whitespace. + @leave KErrNoMemory + */ +CIniSection * CIniFile::AddOrFindIniSectionL(TPtr& aSectionName) + { + aSectionName.Trim(); + + // DEFAULT section + if (aSectionName.CompareF(KDefaultSectionName) == 0) + { + return iSectionArray[KDefaultSectionNumber]; + } + + // SCREENx section + if (0 == aSectionName.FindF(KScreenSectionName)) + { + TLex lex(aSectionName.Mid(KScreenSectionName().Length())); + TInt screenNum; + lex.SkipSpace(); + if (lex.Val(screenNum) == KErrNone) + { + return AddOrFindScreenSectionL(screenNum); + } + } + + // other section + return AddOrFindNamedSectionL(aSectionName); + } + +CIniSection * CIniFile::CreateSectionL(TInt aScreen) + { + CIniSection* newSection = new (ELeave) CIniSection(aScreen); + CleanupStack::PushL( newSection ) ; + newSection->ConstructL() ; + User::LeaveIfError(iSectionArray.Append(newSection)); + CleanupStack::Pop( newSection ) ; + if (aScreen + 1 > iScreenCount) + iScreenCount = aScreen + 1; + return newSection; + } + +CIniSection * CIniFile::CreateSectionL(const TDesC& aName) + { + CIniSection* newSection = new (ELeave) CIniSection(KDefaultScreenId); + CleanupStack::PushL( newSection ) ; + newSection->ConstructL(aName) ; + User::LeaveIfError(iSectionArray.Append(newSection)); + CleanupStack::Pop( newSection ) ; + return newSection; + } + + +void CIniFile::doConstructL(RFile &aFile) + { + TFileText textFile; + textFile.Set(aFile); + const TInt KMaxIniLine=256; + TBuf readLine; + TBool first=ETrue; + + // always have a [DEFAULT] section + CIniSection * currentSection = CreateSectionL(KDefaultSectionName); + + FOREVER + { + TInt err=textFile.Read(readLine); + if (err==KErrEof) + break; + User::LeaveIfError(err); + + if (readLine.Length()>0) + { + if (first && (readLine[0]==0xFFFE || readLine[0]==0xFEFF)) + readLine.Delete(0,1); + + // Comment marker "//" indicates the rest of the line should be discarded + TInt commentStart = readLine.Find(KCommentMarker); + if (commentStart != KErrNotFound) + { + readLine.Delete(commentStart, readLine.Length()); + } + + // compact unnecessary whitespace + readLine.TrimAll(); + + // anything left in buffer? + if (readLine.Length() > 0) + { + // section name requires "[" and "]" + if (readLine[0] == KNewSection && readLine.LocateReverse(KNewSection2) == readLine.Length() - 1) + { + TPtr nameText = readLine.MidTPtr(1, readLine.Length() - 2); // strip [ and ] + currentSection = AddOrFindIniSectionL(nameText); + } + else + { + if (currentSection) + { + currentSection->AddVariableL(readLine); + } + } + } + first=EFalse; + } + } + + if (iScreenCount == 0) + { + iScreenCount = 1; + } + } + +CIniFile* CIniFile::NewL() + { + CIniFile* self = new (ELeave) CIniFile(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CIniFile::FreeData() + { + iSectionArray.ResetAndDestroy() ; + iScreenCount = 0; + } + +void errFreeData(TAny *aIniFile) + { + ((CIniFile *)aIniFile)->FreeData(); + } + +HBufC* IniFileSearchPathLC() + { + _LIT(KPath,"\\SYSTEM\\DATA\\"); + _LIT(KPathSep,";"); + const TInt KLengthPerPath = 2 + KPath().Length(); + // work out which drive Wserv loaded from + RProcess self; + TFileName myPath = self.FileName(); + TParsePtrC myDrive(myPath); + TDriveUnit myDriveUnit(myDrive.Drive()); + // need extra buffer space for search paths for drives Z: or C: ? +#if defined(LOAD_INI_FILE_FROM_DRIVE_Z_OR_C) + TInt numPaths = 2; + if (myDriveUnit != EDriveZ && myDriveUnit != EDriveC) + { + numPaths += 1; + } +#else + TInt numPaths = 1; + if (myDriveUnit != EDriveZ) + { + numPaths += 1; + } +#endif + HBufC* searchPath = HBufC::NewLC(numPaths * KLengthPerPath + (numPaths - 1) * KPathSep().Length()); + TPtr pPath(searchPath->Des()); + pPath.Append(myDrive.Drive()); + pPath.Append(KPath); + if (myDriveUnit != EDriveZ) + { + pPath.Append(KPathSep); + pPath.Append(TDriveUnit(EDriveZ).Name()); + pPath.Append(KPath); + } +#if defined(LOAD_INI_FILE_FROM_DRIVE_Z_OR_C) + if (myDriveUnit != EDriveC) + { + pPath.Append(KPathSep); + pPath.Append(TDriveUnit(EDriveC).Name()); + pPath.Append(KPath); + } +#endif + return searchPath; + } + +void CIniFile::ConstructL() + { + TAutoClose fs; + User::LeaveIfError(fs.iObj.Connect()); + fs.iObj.SetNotifyUser(EFalse); + fs.PushL(); + HBufC* searchPath = IniFileSearchPathLC(); + _LIT(KFileName,"WSINI.INI"); + TFindFile findinifile(fs.iObj); + TInt err=findinifile.FindByPath(KFileName,searchPath); + User::LeaveIfError(err); + CleanupStack::PopAndDestroy(searchPath); + TAutoClose file; + User::LeaveIfError(file.iObj.Open(fs.iObj,findinifile.File(),EFileStreamText|EFileRead)); + file.PushL(); + CleanupStack::PushL(TCleanupItem(errFreeData,this)); + doConstructL(file.iObj); + CleanupStack::Pop(); // TCleanupItem + file.Pop(); + fs.Pop(); + } + +/* If the Section for the screen exists find the data, otherwise create a new data structure. + + @param aScreen Screen number + @return index to section + @leave KErrNoMemory + */ +CIniSection * CIniFile::AddOrFindScreenSectionL(TInt aScreen) + { + CIniSection * section = FindSection(aScreen); + if (!section) + section = CreateSectionL(aScreen); + return section; + } + +/* If the Section exists find the data, otherwise create a new data structure. + + @param aName section name + @return index to section + @leave KErrNoMemory + */ +CIniSection * CIniFile::AddOrFindNamedSectionL(const TDesC& aName) + { + CIniSection * section = FindSection(aName); + if (!section) + section = CreateSectionL(aName); + return section; + } + +TBool CIniFile::FindVar(const TDesC &aVarName, TPtrC &aResult) + { + return iSectionArray[KDefaultSectionNumber]->FindVar(aVarName, aResult); + } + + +TBool CIniFile::FindVar(const TDesC &aVarName, TInt &aResult) + { + return iSectionArray[KDefaultSectionNumber]->FindVar(aVarName, aResult); + } + +TBool CIniFile::FindVar(const TDesC &aVarName) +// +// Used to simply detect the presence of the specified variable name +// + { + TPtrC ptr(NULL,0); + return FindVar(aVarName, ptr); + } + +// FindVar in [SCREENx] sections +TBool CIniFile::FindVar( TInt aScreen, const TDesC &aVarName) + { + TPtrC ptr(NULL,0); + return FindVar(aScreen, aVarName, ptr); + } + +TBool CIniFile::FindVar( TInt aScreen, const TDesC& aVarName, TPtrC &aResult ) + { + CIniSection * section = FindSection(aScreen); + TBool found = EFalse; + if (section) + found = section->FindVar(aVarName, aResult); + if (!found) + found = FindVar(aVarName, aResult); + return found; + } + +TBool CIniFile::FindVar(TInt aScreen, const TDesC &aVarName, TInt &aResult) + { + CIniSection * section = FindSection(aScreen); + TBool found = EFalse; + if (section) + found = section->FindVar(aVarName, aResult); + if (!found) + found = FindVar(aVarName, aResult); + return found; + } + +// FindVar in named sections +TBool CIniFile::FindVar(const TDesC& aSectionName, const TDesC &aVarName) + { + TPtrC ptr(NULL,0); + return FindVar(aSectionName, aVarName, ptr); + } + +TBool CIniFile::FindVar(const TDesC& aSectionName, const TDesC& aVarName, TPtrC &aResult ) + { + CIniSection * section = FindSection(aSectionName); + TBool found = EFalse; + if (section) + found = section->FindVar(aVarName, aResult); + if (!found) + found = FindVar(aVarName, aResult); + return found; + } + +TBool CIniFile::FindVar(const TDesC& aSectionName, const TDesC &aVarName, TInt &aResult) + { + CIniSection * section = FindSection(aSectionName); + TBool found = EFalse; + if (section) + found = section->FindVar(aVarName, aResult); + if (!found) + found = FindVar(aVarName, aResult); + return found; + } + +TInt CIniFile::NumberOfScreens() const + { + return iScreenCount; + } + + +// CIniSection. +// ini file structure is now in sections like this +// +// [DEFAULT] +// varname value +// varname2 value2 +// [SCREEN0] +// screenvar value +// etc +// +// CIniSection represents a section - i.e. section name and content pairs. +// Content pairs are as ini file was previously (so use same code) +// [default] section name is optional to support backwards compatibility +// if no sutable value is found in a [screenN] section the [default] section will be searched. + + +CIniSection::CIniSection(TInt aScreen) : iScreen(aScreen) + {} + +void CIniSection::ConstructL() + { + iPtrArray = new (ELeave) CArrayPtrFlat(8) ; + } + +void CIniSection::ConstructL(const TDesC& aName) + { + iName.CreateL(aName); + ConstructL(); + } + +CIniSection::~CIniSection() + { + iName.Close(); + iPtrArray->ResetAndDestroy() ; + delete iPtrArray ; + } + +inline TInt CIniSection::Screen() const + { return iScreen; } + +inline const TDesC& CIniSection::Name() const + { return iName; } + +TBool CIniSection::FindVar( const TDesC& aVarName, TPtrC &aResult ) + { + if (iPtrArray) + { + TInt index(KErrNotFound); + + if (FindVarName(aVarName, index)) + { + TLex lex((*iPtrArray)[index]->Mid(aVarName.Length())); + lex.SkipSpace(); + aResult.Set(lex.Remainder()); + + if (wsDebugLog) + { + wsDebugLog->IniFileSettingRead(iScreen, aVarName, ETrue, aResult); + } + return(ETrue); + } + } + + if (wsDebugLog) + { + wsDebugLog->IniFileSettingRead(iScreen, aVarName, EFalse, KNullDesC); + } + return(EFalse); + } + +/* + create a TPtrC with just the first word (variable name) in the given string + */ +TPtrC CIniSection::VarName(const TDesC& aVarString) + { + TInt varLength = aVarString.Locate(KSpaceChar); + if (varLength == KErrNotFound) + { + varLength = aVarString.Length(); + } + return aVarString.Left(varLength); + } + + +TBool CIniSection::FindVar(const TDesC &aVarName, TInt &aResult) + { + TPtrC ptr(NULL,0); + // do text Find + if (FindVar(aVarName, ptr)) + { + TLex lex(ptr); + _LIT(HexFormatCheck,"0x"); + TPtrC hexPtr(HexFormatCheck); + if(ptr.Left(2) != hexPtr) + { + if (lex.Val(aResult) == KErrNone) + { + return ETrue; + } + } + else + { + lex.SkipAndMark(2); //To skip 0x in hex code + if (lex.Val((TUint32&)aResult, EHex) == KErrNone) + { + return ETrue; + } + } + } + + return EFalse; + } + + +/* + Find variable name in sorted array, using binary search + @param aVarName variable name to search for, must have any space and variable value stripped. + @param aIndex output index of matching or preceeding item + @return + */ +TBool CIniSection::FindVarName(const TDesC& aVarName, TInt& aIndex) + { + // Binary Search + // left is lowest index to include, right is highest index + 1; + TInt left = 0; + TInt right = iPtrArray->Count(); + + while (right > left) + { + TInt middle = (left + right)>>1; + // compare to start of variable string + TPtrC cmpString = VarName(*(*iPtrArray)[middle]); + TInt cmp = aVarName.CompareF(cmpString); + + if (cmp == 0) + { + aIndex = middle; + return ETrue; + } + else if (cmp > 0) + { + left = middle + 1; + } + else + { + right = middle; + } + } + + aIndex = right; + return EFalse; + } + +void CIniSection::AddVariableL(const TDesC& aNewVariable) + { + // use variable name only for search + TPtrC varName = VarName(aNewVariable); + TInt index(0); + + // ignore duplicate definitions + if (0 == FindVarName(varName, index)) + { // insert in sorted array + HBufC* hbuf = aNewVariable.AllocLC() ; + iPtrArray->InsertL(index, hbuf); + CleanupStack::Pop(hbuf); + } + } +