messagingfw/msgsrvnstore/server/src/msvinifile.cpp
changeset 0 8e480a14352b
child 22 d2c4c66342f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgsrvnstore/server/src/msvinifile.cpp	Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,358 @@
+// Copyright (c) 2007-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 "msvinifile.h"
+#include <f32file.h>
+#include <e32std.h>
+
+// Maximum token size
+const TInt KTokenSize=256;
+
+// Default location for our config files
+_LIT(KIniFileDir, "Z:\\private\\1000484b\\");
+
+
+
+CMsvIniData::CMsvIniData() 
+	: iPtr(NULL,0)
+	{
+	__DECLARE_NAME(_S("CMsvIniData"));
+	}
+
+
+CMsvIniData::~CMsvIniData()
+	{
+	delete (TText*)iPtr.Ptr();
+	delete iToken;
+	delete iName;
+	}
+
+
+
+/**
+ Creates and returns a pointer to CMsvIniData object, leave on failure
+ @return 	A pointer to the CiniData object
+*/
+CMsvIniData* CMsvIniData::NewL(const TDesC& aName)
+	{
+	CMsvIniData* p=new(ELeave) CMsvIniData;
+	CleanupStack::PushL(p);
+
+	p->ConstructL(aName);
+
+	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.
+@leave 			One of the system-wide error codes.
+*/
+void CMsvIniData::ConstructL(const TDesC& aName)
+	{
+ 	// 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();
+
+#if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)
+	iName = aName.AllocL();
+#else
+	TFindFile ff(fs.iObj);
+	User::LeaveIfError(ff.FindByDir(aName, KIniFileDir));
+	iName=ff.File().AllocL();
+#endif
+	
+	// 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.
+	//
+	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 CMsvIniData::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 CMsvIniData::FindVar(const TDesC& aSectName, const TDesC& aKeyName,TPtrC& aResult)
+	{
+	//Should use messaging panic codes???
+	__ASSERT_DEBUG(aSectName.Length() <= KTokenSize, User::Invariant());
+	__ASSERT_DEBUG(aKeyName.Length() <= KTokenSize, User::Invariant());
+
+	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] == '=') || (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 '=' sign
+	SearchBuf.Set(iPtr.Mid(posI));
+	TInt posSB = SearchBuf.Locate('=');
+	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 '='
+	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 CMsvIniData::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 CMsvIniData::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);
+	}