datacommsserver/esockserver/ssock/INIFILE.CPP
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/INIFILE.CPP	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,505 @@
+// 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:
+//
+
+#include <es_ini.h>
+#include <f32file.h>
+#include <cfextras.h>
+
+
+/**
+@internalComponent
+*/
+class TFileListIter
+	{
+public:
+	TFileListIter()
+		{
+		iList = 0;
+		iIsCDir = EFalse;
+		iIdx = 0;
+		}
+	void Set(const CDir* aList)
+		{
+		iList = static_cast<const void*>(aList);
+	    iIdx = 0;
+		iIsCDir = ETrue;
+		}
+	void Set(const CommsFW::COwnEntryList* aList)
+		{
+		iList = static_cast<const void*>(aList);
+	    iIdx = 0;
+		iIsCDir = EFalse;
+		}
+	const TEntry* operator++(TInt)
+		{
+		const TEntry* entry = NULL;
+		if(iIsCDir)
+			{
+			const CDir* list = reinterpret_cast<const CDir*>(iList);
+			if(list != NULL && iIdx < list->Count())
+				{
+				entry = &(*list)[iIdx++];
+				}
+			}
+		else
+			{
+			const CommsFW::COwnEntryList* list = reinterpret_cast<const CommsFW::COwnEntryList*>(iList);
+			if(list != NULL && iIdx < list->Count())
+				{
+				entry = &(*list)[iIdx++];
+				}
+			}
+		return entry;
+		}
+private:
+	const void* iList;
+	TBool iIsCDir;
+	TInt iIdx;
+	};
+
+const TInt KTokenSize=32;
+
+// Warning !! redifinition required
+const TInt32 KUidCommsProcess = 0x101F7989;
+
+/*
+@internalComponent
+*/
+enum TIniPanic
+	{
+	ESectionNameTooBig,
+	EVarNameTooBig,
+	};
+
+/**
+@internalComponent
+*/
+void Panic(TIniPanic aPanic)
+	{
+	_LIT(cESockIniData,"CESockIniData");
+	User::Panic(cESockIniData,aPanic);
+	}
+
+
+EXPORT_C CESockIniData::CESockIniData() 
+: iPtr(NULL,0)
+	{
+	}
+
+EXPORT_C CESockIniData::CESockIniData(const CommsFW::COwnEntryList* aFileList) 
+: iPtr(NULL,0),
+  iFileList(aFileList)
+  	{
+	}
+
+EXPORT_C CESockIniData::~CESockIniData()
+	{
+	delete (TText*)iPtr.Ptr();
+	delete iToken;
+	delete iName;
+	}
+
+EXPORT_C CESockIniData* CESockIniData::NewL(const TDesC& aName)
+	{
+	CESockIniData* p=new(ELeave) CESockIniData;
+	CleanupStack::PushL(p);
+	p->ConstructL(aName);
+	CleanupStack::Pop();
+	return p;
+	}
+
+EXPORT_C CESockIniData* CESockIniData::NewL(const CommsFW::COwnEntryList* aFileList)
+	{
+	CESockIniData* p=new(ELeave) CESockIniData(aFileList);
+	CleanupStack::PushL(p);
+	p->ConstructL(KNullDesC);
+	CleanupStack::Pop();
+	return p;
+	}
+
+EXPORT_C void CESockIniData::ConstructL(const TDesC& aName)
+/**
+Allocate a buffer and Read file's contents into iPtr
+*/
+	{
+	
+    iToken=HBufC::NewL(KTokenSize+2);	// 2 extra chars for [tokenName]
+	
+	// protocol_buf is used to holf the protocol list
+	// and then the whole collated .ini file
+	CBufFlat* protocol_buf=CBufFlat::NewL(4);
+	CleanupStack::PushL(protocol_buf);
+	TInt protocol_pos = 0;
+	
+	//data_buf is used to temporarily hold the .esk files'bodies
+	CBufFlat* data_buf=CBufFlat::NewL(4);
+	CleanupStack::PushL(data_buf);
+	TInt data_pos = 0;
+	
+	TInt data_size =0;
+	
+	TAutoClose<RFs> fs;
+	User::LeaveIfError(fs.iObj.Connect());
+	fs.PushL();
+
+	TBuf<100> privatePath;
+	TBool isC32Exe = (RThread().SecureId() == KUidCommsProcess);
+ 	if(isC32Exe)	// If it is C32Exe, uppend private path with ESock
+        {
+		privatePath = KEsockIniFileDir;
+        }
+	else
+        {
+		fs.iObj.PrivatePath(privatePath);
+        }
+	
+	TFindFile ff(fs.iObj);
+	TFileListIter iter;
+	
+	if(aName == ESOCK_INI_DATA || aName.Length() == 0) 
+		{
+		CDir* ownedFileList = NULL;
+		if(iFileList)
+			{
+			iter.Set(iFileList);
+			}
+		else
+			{
+			// Have to build own file list
+			if(ff.FindWildByDir(KEsockWildCard, privatePath, ownedFileList) == KErrNone)
+				{
+				CleanupStack::PushL(ownedFileList);
+				iter.Set(ownedFileList);
+				}
+			}
+		_LIT(KSockManMainSectionName,"sockman");
+		_LIT(KProtocolListItemName,"protocols");
+		TPtrC protocols;
+		TInt err = KErrNone;
+		
+		_LIT(KTxtComma,",");
+		_LIT(KNewLine,"\r\n");
+		_LIT(KTxtIniFileStart,"[sockman] protocols= ");
+		
+		protocol_buf->InsertL(protocol_pos, (TAny*)(&KTxtIniFileStart)->Ptr(), (&KTxtIniFileStart)->Size());
+		protocol_pos+= (&KTxtIniFileStart)->Size();
+
+		TBool noBackupDirSearched(EFalse);
+		while (err==KErrNone)                
+			{
+			TBool firstEntry = ETrue;
+			while(const TEntry* entry = iter++)	//for (TInt i=0; i < iFileList->Count(); i++)    
+				{
+				TParse fullentry;
+				fullentry.Set(entry->iName,& ff.File(),NULL);      
+				TAutoClose<RFile> file;
+				User::LeaveIfError(file.iObj.Open(fs.iObj,fullentry.FullName(),EFileStreamText|EFileRead));
+				file.PushL();
+				User::LeaveIfError(file.iObj.Size(data_size));
+
+				// Following BR1123 we presume that all files are narrow-char only and widen them here
+				__ASSERT_COMPILE(sizeof(TText) == 2);
+				TUint8* rawBuff = (TUint8*) User::AllocLC(data_size * sizeof(TText));
+				TPtr8 rawTPtr(rawBuff, data_size * sizeof(TText));
+				User::LeaveIfError(file.iObj.Read(rawTPtr));
+
+				TText* dstPtr = (TText*) rawBuff;
+				for(TInt i = data_size - 1; i >= 0; --i)
+					{
+					dstPtr[i] = rawBuff[i];
+					}
+				iPtr.Set((TText*) rawBuff, data_size, data_size);
+				CleanupStack::Pop();  // Get data off; destructor takes care of freeing iPtr
+				
+				if(FindVar(KSockManMainSectionName,KProtocolListItemName,protocols))
+					{
+					//Store the protocol in the protocol dynamic buffer
+					if(firstEntry)
+						{
+						firstEntry = EFalse;
+						}
+					else
+						{
+						protocol_buf->ExpandL(protocol_pos, (&KTxtComma)->Size());
+						protocol_buf->Write(protocol_pos,(TAny*)(&KTxtComma)->Ptr(), (&KTxtComma)->Size());
+						protocol_pos+=(&KTxtComma)->Size();
+						}
+					protocol_buf->ExpandL(protocol_pos, protocols.Size());
+					protocol_buf->Write(protocol_pos, protocols.Ptr(), protocols.Size());
+					protocol_pos+=protocols.Size();
+					}
+				else
+					{
+					// Protocols line absent; whole of text is "trailer"
+					protocols.Set(iPtr.Ptr(), 0);
+					data_buf->ExpandL(data_pos, (&KNewLine)->Size());
+					data_buf->Write(data_pos, (TAny*)(&KNewLine)->Ptr(), (&KNewLine)->Size());
+					data_pos+=(&KNewLine)->Size();
+					}
+				
+				TInt dif = (protocols.Ptr()+protocols.Length()) - iPtr.Ptr();
+				
+				//Store the rest of the file in the data dynamic buffer
+				data_buf->ExpandL(data_pos, (data_size-dif)*sizeof(TText));
+				data_buf->Write(data_pos, (protocols.Ptr()+protocols.Length()), (data_size-dif)*sizeof(TText));
+				data_pos+= (data_size - dif)*sizeof(TText);
+				
+				//Delete temporary buffer
+				delete (TText*)iPtr.Ptr();
+				iPtr.Set(NULL,0,0);
+				file.Pop();
+				}
+			
+			if(ownedFileList)
+				{
+				CleanupStack::PopAndDestroy(ownedFileList);
+
+				//Continue the search in the next drive in the search sequence
+				err=ff.FindWild(ownedFileList); 
+				
+				if (err==KErrNone)
+					{
+					CleanupStack::PushL(ownedFileList);
+					iter.Set(ownedFileList);
+					protocol_buf->ExpandL(protocol_pos, (&KTxtComma)->Size());
+					protocol_buf->Write(protocol_pos,(TAny*)(&KTxtComma)->Ptr(), (&KTxtComma)->Size());
+					protocol_pos+=(&KTxtComma)->Size();
+					}
+				else if (err==KErrNoMemory)
+					{
+					User::Leave(err);
+					}
+				else if(err==KErrNotFound && !noBackupDirSearched)
+					{
+ 					//It's time to look into nobackup directory
+ 					noBackupDirSearched = ETrue;
+ 					if(isC32Exe)	// If it is C32Exe, uppend private path with ESock
+         				{
+ 						privatePath = KEsockNoBackupDir;
+ 						err = ff.FindWildByDir(KEsockWildCard, privatePath, ownedFileList);
+ 						if(err == KErrNone)
+ 							{
+ 							CleanupStack::PushL(ownedFileList);
+ 							iter.Set(ownedFileList);
+ 							}
+         				}
+ 					}
+				}
+			else
+			    {
+			    err=KErrNotFound; // Break out of while loop
+			    }
+			}
+		
+		//Copy all the collated esk bodies into the protocol_buf after the protocol list
+		protocol_buf->ExpandL(protocol_pos, data_buf->Size());
+		protocol_buf->Write(protocol_pos, data_buf->Ptr(0), data_buf->Size());
+		
+		//Copy the all collated initialisation information into its final destination
+		TText* newinifile = (TText*)User::AllocL(protocol_buf->Size());
+		protocol_buf->Read(0, newinifile, protocol_buf->Size());
+		
+		data_size = protocol_buf->Size() / (TInt) sizeof(TText);
+		iPtr.Set(newinifile, data_size, data_size);
+		
+		fs.Pop();
+		}
+	else
+	// Deals with standard .ini file
+		{
+		
+ 		TInt err = KErrNone;
+ 		err = ff.FindByDir(aName, privatePath);
+ 		if(err!=KErrNone && isC32Exe)
+ 			{
+ 			privatePath = KEsockNoBackupDir;
+ 			User::LeaveIfError(ff.FindByDir(aName, privatePath));	
+ 			}
+ 				
+		iName=ff.File().AllocL();
+		
+		TAutoClose<RFile> file;
+		TInt size;
+		User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileRead));
+		file.PushL();
+		
+		User::LeaveIfError(file.iObj.Size(size));
+		TText* data=(TText*)User::AllocL(size);
+		iPtr.Set(data, size/(TInt)sizeof(TText), size/(TInt)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/(TInt)sizeof(TText)-1, size/(TInt)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();
+		
+		}
+	CleanupStack::PopAndDestroy(2); // remove protocol_buf - data_buf
+	}
+
+EXPORT_C TBool CESockIniData::FindVar(const TDesC &aVarName, TPtrC &aResult) const
+	{
+	TInt pos=iPtr.Find(aVarName);
+	if (pos==KErrNotFound)
+		return(EFalse);
+	TLex lex(iPtr.Mid(pos));
+	lex.SkipCharacters();
+	lex.SkipSpaceAndMark();		// Should be at the start of the data
+	lex.SkipCharacters();
+	aResult.Set(lex.MarkedToken().Ptr(),lex.MarkedToken().Length());
+	return(ETrue);
+	}
+
+EXPORT_C TBool CESockIniData::FindVar(const TDesC &aVarName, TInt &aResult) const
+	{
+	TPtrC ptr(NULL,0);
+	if (FindVar(aVarName,ptr))
+		{
+		TLex lex(ptr);
+		if (lex.Val(aResult)==KErrNone)
+			return(ETrue);
+		}
+	return(EFalse);
+	}
+
+EXPORT_C TBool CESockIniData::FindVar(const TDesC &aSection,const TDesC &aVarName,TPtrC &aResult) const
+/**
+Find a variable's value given a section name and a var name
+*/
+	{
+	__ASSERT_DEBUG(aSection.Length()<=KTokenSize,Panic(ESectionNameTooBig));
+	__ASSERT_DEBUG(aVarName.Length()<=KTokenSize,Panic(EVarNameTooBig));
+
+	TPtr sectionToken=iToken->Des();
+	_LIT(sectionTokenString,"[%S]");
+	sectionToken.Format(sectionTokenString,&aSection);
+	TInt sectionStart=iPtr.Find(sectionToken);
+	if (sectionStart==KErrNotFound)
+		return EFalse;
+	TPtrC section=iPtr.Mid(sectionStart);
+	sectionStart+=section.Find(TPtrC(_S("]")));
+	if (sectionStart==KErrNotFound)
+		return EFalse;
+	sectionStart++;
+	section.Set(iPtr.Mid(sectionStart));
+	
+	TInt sectionEnd=section.Find(TPtrC(_S("[")));
+	if (sectionEnd==KErrNotFound)
+		sectionEnd=iPtr.Length()-sectionStart;
+	
+	section.Set(iPtr.Mid(sectionStart,sectionEnd));
+	TPtr varToken=iToken->Des();
+	_LIT(varTokenString,"%S=");
+	varToken.Format(varTokenString,&aVarName);
+	TInt pos=section.Find(varToken);
+	if (pos==KErrNotFound)
+		return EFalse;
+	TLex lex(section.Mid(pos));
+	lex.SkipCharacters();
+	lex.SkipSpaceAndMark();		// Should be at the start of the data
+	lex.SkipCharacters();
+	aResult.Set(lex.MarkedToken().Ptr(),lex.MarkedToken().Length());
+	return(ETrue);
+
+	}
+
+EXPORT_C TBool CESockIniData::FindVar(const TDesC &aSection,const TDesC &aVarName,TInt &aResult) const
+	{
+	TPtrC ptr(NULL,0);
+	if (FindVar(aSection,aVarName,ptr))
+		{
+		TLex lex(ptr);
+		if (lex.Val(aResult)==KErrNone)
+			return(ETrue);
+		}
+	return(EFalse);
+}
+
+EXPORT_C TInt CESockIniData::WriteVar(const TDesC& aSection,const TDesC& aVarName,TInt aValue)
+/**
+Changes the string associated with a token
+*/
+	{
+	TBuf<32> buf;
+	buf.Num(aValue);
+	return WriteVar(aSection, aVarName, buf);
+	}
+
+EXPORT_C TInt CESockIniData::WriteVar(const TDesC& aSection,const TDesC& aVarName,const TDesC& aValue)
+/**
+Changes the string associated with a token
+*/
+	{
+	// First find the variable - this gives us a descriptor into the
+	// ini data giving the bound of the item that has gto be replaced.
+	TPtrC ptr;
+	
+	if (!FindVar(aSection, aVarName, ptr))
+		return KErrNotFound;
+	
+	TInt pos = ptr.Ptr()-iPtr.Ptr();
+	TInt size = (iPtr.Length()+aValue.Length()-ptr.Length())*sizeof(TText);
+
+	if (size>iPtr.MaxLength())
+		{
+		TText* newdata = (TText*)User::ReAlloc((TUint8*)iPtr.Ptr(), size); 
+		if (newdata == 0)
+			return KErrNoMemory;
+
+		iPtr.Set(newdata, iPtr.Length(), size/(TInt)sizeof(TText));
+		}
+	
+	iPtr.Replace(pos, ptr.Length(), aValue);
+	return KErrNone;
+	}
+
+EXPORT_C void CESockIniData::CommitL()
+	{
+	TAutoClose<RFs> fs;
+	User::LeaveIfError(fs.iObj.Connect());
+	fs.PushL();
+
+	TAutoClose<RFile> file;
+	User::LeaveIfError(file.iObj.Replace(fs.iObj,*iName,EFileStreamText|EFileWrite));
+	file.PushL();
+
+	TPtrC8 ptrc8((TUint8*)iPtr.Ptr(), iPtr.Size());
+	User::LeaveIfError(file.iObj.Write(ptrc8));
+
+	file.Pop();
+	fs.Pop();
+	}
+