commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/CIniFile.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/CIniFile.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,387 @@
+// Copyright (c) 1997-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:
+//
+
+/**
+ @file 
+ @internalComponent
+*/
+
+#include <f32file.h>
+#include "CIniFile.h"
+#include "dbdef.h"
+
+CIniData::CIniData() 
+/**
+Default constructor
+
+*/
+	: iPtr(NULL,0), section(NULL,0), block(NULL,0), BlockState(E_UNKNOWN),
+	  blockStart(0), blockEnd(0), scanStart(0)
+	{
+	__DECLARE_NAME(_S("CIniData"));
+	}
+
+CIniData::~CIniData()
+/**
+Destructor
+
+*/
+	{
+	delete (TText*)iPtr.Ptr();
+	delete iToken;
+	delete iName;
+	}
+
+CIniData* CIniData::NewL(const TDesC& aName)
+/**
+Allocates and constructs a new CIniData object
+
+@param aName Name of the ini file to be read
+@return A newly created CIniData object
+*/
+	{
+	CIniData* p = new(ELeave) CIniData;
+	CleanupStack::PushL(p);
+	p->ConstructL(aName);
+	CleanupStack::Pop(p);
+	return p;
+	}
+
+
+void CIniData::ConstructL(const TDesC& aName)
+/**
+Allocates a buffer and reads file's contents into iPtr
+
+@param aName Name of the ini file to be read
+*/
+	{
+ 	// Allocate space for token
+	iToken=HBufC::NewL(MAX_COL_NAME_LEN + 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.FindByPath(aName, NULL));
+	iName=ff.File().AllocL();
+
+	// Open file
+	TAutoClose<RFile> file;
+	TInt size;
+	User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileRead));
+	file.PushL();
+
+	// Get file size and read in
+	User::LeaveIfError(file.iObj.Size(size));
+	TText* data=(TText*)User::AllocL(size);
+	iPtr.Set(data, TUint(size)/sizeof(TText), TUint(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, TUint(size)/sizeof(TText)-1, TUint(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();
+	}
+
+
+TInt CIniData::OpenSetBlock(const TDesC &aSection)
+/**
+Locates and opens a section for 'updates'
+
+@param aSection Section to work with
+@return ETrue if successful or EFalse
+*/
+	{
+	BlockState = E_SET;
+	return OpenBlock(aSection);
+	}
+
+
+TInt CIniData::OpenTemplateBlock(const TDesC &aSection)
+/**
+Locates and opens a section for 'template'
+
+@param aSection Section to work with
+@return ETrue if successful or EFalse
+*/
+	{
+	BlockState = E_TEMPLATE;
+	return OpenBlock(aSection);
+	}
+
+
+TInt CIniData::OpenAddBlock(const TDesC &aSection)
+/**
+Locates and opens a section for 'adds'
+
+@param aSection Section to work with
+@return ETrue if successful or EFalse
+*/
+	{
+	BlockState = E_ADD;
+	return OpenBlock(aSection);
+	}
+
+
+TInt CIniData::OpenBlock(const TDesC &aSection)
+/**
+Reads in the entire table section of all ADD / SET blocks into 'section'
+
+@param aSection Section to work with
+@return ETrue if successful or EFalse
+*/
+	{
+    if (BlockState != E_UNKNOWN)
+		{
+	    blockStart = 0;
+	    blockEnd = 0;
+	    scanStart = 0;
+
+	    TPtr sectionToken = iToken->Des();
+		_LIT(sectionTokenString,"[%S]");
+		sectionToken.Format(sectionTokenString,&aSection);
+
+	    // locate the section
+		TInt sectionStart = iPtr.FindF(sectionToken);
+	    if (sectionStart == KErrNotFound)
+			{
+	        return EFalse;
+			}
+
+		// step to the end of the section name
+		TPtrC tempSection = iPtr.Mid(sectionStart);
+        sectionStart += tempSection.Find(TPtrC(_S("]")));
+
+		if (sectionStart == KErrNotFound)
+			{
+			return EFalse;
+			}
+		sectionStart++;
+
+		// we are now at the start of the section data
+        tempSection.Set(iPtr.Mid(sectionStart));
+
+		// loop until we reach the end of the section
+		TUint32 i=0;
+		TUint32 lMaxLen = tempSection.Length();
+
+        for (i=0;i<lMaxLen;i++)
+			{
+	        if (tempSection.Ptr()[i] == '[' &&
+		        tempSection.Ptr()[i - 1] != '\\')
+				{
+			    i--;
+			    break;
+				}
+			}
+		
+		// set the actual section to work with
+        tempSection.Set(iPtr.Mid(sectionStart, i));
+		section.Set((unsigned short *)tempSection.Ptr(), tempSection.Length(), tempSection.Size());
+		}
+
+	return StepToNextBlock();	// find the first block
+	}
+
+
+TInt CIniData::StepToNextBlock()
+/**
+Locates the next available block of data within a section
+
+@return ETrue if successful or EFalse
+*/
+	{
+	if (BlockState != E_UNKNOWN)
+		{
+		// get unscanned portion of the section
+		TPtrC temp = section.Mid(scanStart);
+
+		// find the start of the next block
+		if (BlockState == E_SET)
+			{
+			blockStart = temp.FindF(TPtrC(BEGIN_SET));
+			blockEnd = temp.FindF(TPtrC(END_SET));
+			}
+		else if (BlockState == E_TEMPLATE)
+			{
+			blockStart = temp.FindF(TPtrC(BEGIN_TEMPLATE));
+			blockEnd = temp.FindF(TPtrC(END_TEMPLATE));
+			}
+		else if (BlockState == E_ADD)
+			{
+			blockStart = temp.FindF(TPtrC(BEGIN_ADD));
+			blockEnd = temp.FindF(TPtrC(END_ADD));
+			}
+
+		if (blockStart != KErrNotFound && blockEnd != KErrNotFound)
+			{
+			// set the start point for the next block search
+			scanStart += blockEnd;
+			scanStart++;
+
+			// set the actual block to work with
+			blockEnd -= blockStart;
+			TPtrC tempBlock = temp.Mid(blockStart,blockEnd);
+			block.Set((unsigned short *)tempBlock.Ptr(), tempBlock.Length(), tempBlock.Size());
+			return ETrue;
+			}
+		}
+
+	return EFalse;
+	}
+
+
+TInt CIniData::GetSetting(const TDesC &aValue, TPtrC &aSetting)
+/**
+Retrieves the value for a particular setting within a block
+
+@param aValue The setting to be retrieved 
+@param aSetting On return it contains the value for the setting
+@return KErrNone if successful or KErrArgument for fields simply left blank. If the global BlockState is unknown returns KErrNotReady.
+*/
+	{
+	TInt valid(KErrNotReady);	
+
+	if (BlockState != E_UNKNOWN)
+	    {
+		// first check for CONDITION field
+		// if we are NOT looking for this field, we need to trim off any condition
+		// field from the block because there may be a setting within it we 
+		// want to ignore during our search for this field
+        TPtrC pBlock(block);
+		TInt tempEnd = blockEnd;
+		TPtrC Condition = CONDITION;
+		if (aValue.Compare(Condition) != 0)
+		    {
+			TPtr varCondToken = iToken->Des();
+			_LIT(varCondTokenString, "%S=");
+			varCondToken.Format(varCondTokenString, &Condition);
+			TInt CondPos = pBlock.FindF(varCondToken);
+			if (CondPos != KErrNotFound)
+				{
+				tempEnd = CondPos;
+				}
+		    }
+
+		// now look for the actual value
+        TBool searchAgain = EFalse;
+        _LIT(varTokenString, "%S=");
+		TPtr varToken = iToken->Des();
+		varToken.Format(varTokenString, &aValue);
+
+        TInt pos = KErrNotFound;
+        do
+            {
+            searchAgain = EFalse;
+            pos = pBlock.FindF(varToken);
+		    if (pos != KErrNotFound && pos < tempEnd)
+		        {
+                // check that this is a complete match, not a substring
+                // match against another similar field, e.g. LoginScript
+                // must only match against "LoginScript" not "UseLoginScript"
+                if  (pos > 0)
+                    {
+                    // Previous character must be white space
+                    const TChar previousCharacter = pBlock[pos - 1];
+                    if  (previousCharacter.IsSpace())
+                        {
+			            // make sure we haven't overrun our block
+			            TInt length = varToken.Length();
+			            if (pos + length < tempEnd)
+			                {
+				            TLex lex(pBlock.Mid(pos + length));
+
+				            // if enclosed by quotes, extract the text within
+				            if (lex.Peek() == '"')
+				                {
+					            lex.SkipAndMark(1);			// start of data
+
+					            // stop at end of quote or line
+					            while(lex.Peek() != '"' && lex.Peek() != 10 && lex.Peek() != 13)
+									{
+						            lex.Inc();
+									}
+				                }
+							else if(lex.Peek() == 10 || lex.Peek() == 13)	// skip empty or blank field value
+								{
+								return KErrArgument;
+								}
+							else	// skip any unwanted spaces or tabs in a field value
+								{
+								TBool fieldValFound=EFalse;
+								while(lex.Peek() != 10 && lex.Peek() != 13) 
+									{
+									if(!fieldValFound)
+										{
+										while(lex.Peek() == 9 || lex.Peek() == 32) // skip any space or a tab
+											{
+											lex.SkipAndMark(1);
+											}
+										if(lex.Peek() == 10 || lex.Peek() == 13) // field value simply filled with space or tab
+											{
+											return KErrArgument;
+											}
+										}
+									fieldValFound=ETrue;	// start of real data
+									lex.Inc();
+									}
+								}
+
+				            aSetting.Set(lex.MarkedToken().Ptr(),lex.MarkedToken().Length());
+							valid = KErrNone;
+                            }
+                        }
+                    else
+                        {
+                        // E.g. LoginScript matched against UseLoginScript -> must look
+                        // for another match after the current one
+                        pBlock.Set(pBlock.Mid(pos+1));
+                        searchAgain = ETrue;
+                        }
+                    }
+			    }
+            }
+        while(searchAgain);
+
+	    }
+
+	return valid;
+    }