sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // 8 and 16 bit ini file parser
sl@0: // 
sl@0: //
sl@0: 
sl@0: /**
sl@0:  @file
sl@0:  @internalAll
sl@0: */
sl@0: 
sl@0: #include "IniParserImpl.h"
sl@0: #include "inifile.h"
sl@0: #include "s32file.h"
sl@0: 
sl@0: namespace BSUL
sl@0: {
sl@0: /**
sl@0: Creates a 8 bit section content iterator
sl@0: this iterator is used to navigate through the key value pairs
sl@0: within the section.Useful when the number of keys within the 
sl@0: section is unknown.
sl@0: @param aSectionName the name of the section to iterate
sl@0: @param aIniDocument the document object containing the section
sl@0: @return A pointer to a newly created CIniSecIter8 object
sl@0: @leave	KErrNoMemory if not enough memory
sl@0: 		KErrArgument if aIniDocument is NULL
sl@0: */
sl@0: EXPORT_C CIniSecIter8* CIniSecIter8::NewL(const TDesC8& aSectionName,const CIniDocument8* aIniDocument)
sl@0: {
sl@0: 	CIniSecIter8* self=new (ELeave)CIniSecIter8();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->iImpl=CIniSecIter8Impl::NewL(aSectionName,aIniDocument);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;	
sl@0: }
sl@0: 
sl@0: /**
sl@0: Return the next key value pair within the section
sl@0: @param aKey a pointer to contain the key name
sl@0: @param aValue a pointer to contain the key value
sl@0: @return ETrue if there are keyvalue pairs to return
sl@0: 	    EFalse if it is already end of section
sl@0: @post the iterator points to the next available keyvalue pair
sl@0: 	  the aKeyName points to  the key name
sl@0: 	  the aKeyValue points to the key value
sl@0: */	
sl@0: EXPORT_C TBool CIniSecIter8::Next(TPtrC8& aKey,TPtrC8& aValue)
sl@0: {
sl@0: 	return iImpl->Next(aKey,aValue);
sl@0: }
sl@0: 
sl@0: /**
sl@0: Look ahead in the section to check whether there is 
sl@0: still any keyvalue pair in the section to be read
sl@0: @return ETrue if it is already end of section
sl@0: 	    EFalse indicating the next keyvalue pair exists
sl@0: */
sl@0: EXPORT_C TBool CIniSecIter8::End()
sl@0: {
sl@0: 	return iImpl->End();
sl@0: }
sl@0: 
sl@0: /**
sl@0: Reset the iterator to point to the first keypair value within
sl@0: the section.
sl@0: @post the iterator now points to first keypair in the section
sl@0: */
sl@0: EXPORT_C void CIniSecIter8::Reset()
sl@0: {
sl@0: 	iImpl->Reset();
sl@0: }
sl@0: 
sl@0: /**
sl@0: Destructor
sl@0: */
sl@0: EXPORT_C CIniSecIter8::~CIniSecIter8()
sl@0: {
sl@0: 	delete iImpl;
sl@0: }
sl@0: 
sl@0: //Default constructor
sl@0: CIniSecIter8::CIniSecIter8()
sl@0: {
sl@0: }
sl@0: 
sl@0: //
sl@0: 
sl@0: /** 
sl@0: Opening 8 bit ini file for reading.If the supplied file name is a valid
sl@0: ini file, it will instantiate the object and read the content of 
sl@0: the ini file.If file not found it will simply instantiate the object.
sl@0: The file is opened for read only and close directly after the construction
sl@0: of this object is complete.
sl@0: User will need to explicitly call Externalise(aFileName) to write the content back to ini file.
sl@0: @param aFs the handle to the file session
sl@0: @param aFileName the ini file name to read from
sl@0: @return A pointer to a newly created CIniDocument8 object
sl@0: */
sl@0: EXPORT_C CIniDocument8* CIniDocument8::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: 	{
sl@0: 	CIniDocument8* self=new (ELeave)CIniDocument8();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->iImpl=CIniDocument8Impl::NewL(aFs,aFileName);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Externalise the buffered content to an output file name
sl@0: This will first write into a temporary file in the same directory and path
sl@0: as the supplied aFileName.It will then replace the existing file or 
sl@0: create a new file if does not exist yet.
sl@0: @param aFileName the output file name to write to
sl@0: @return KErrNone if no error
sl@0: 		Other System Wide errors
sl@0: */
sl@0: EXPORT_C TInt CIniDocument8::Externalise(const TDesC& aFileName)
sl@0: {
sl@0: 	TRAPD(r,iImpl->FlushL(aFileName));
sl@0: 	return r;
sl@0: }
sl@0: /**
sl@0: Compare this document against another for differences.
sl@0: @param aDoc to compare against.
sl@0: @return True if same
sl@0: 		Otherwise false
sl@0: */
sl@0: EXPORT_C TBool CIniDocument8::CompareDocs(CIniDocument8& aDoc) 
sl@0: 	{
sl@0: 	return (iImpl->CompareDocs( *(aDoc.iImpl) ));
sl@0: 	}	
sl@0: 
sl@0: /** 
sl@0: Get an array of the section name present in the ini document object
sl@0: Note that any items inside this array will be cleared and the array will
sl@0: be populated with the sections' names from this document object.
sl@0: @param aSectionList an array of descriptor to contain the section name
sl@0: @return KErrNone if successful, otherwise another of the system-wide error codes
sl@0: @post aSectionList contains all the section name in the document object
sl@0: */
sl@0: EXPORT_C TInt CIniDocument8::GetSectionList(RArray<TPtrC8>& aSectionList) const
sl@0: 	{
sl@0: 	return iImpl->GetSectionList(aSectionList);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Get the value of a key within a section
sl@0: @param aSectionName the section where the key resides
sl@0: @param aKey the key name
sl@0: @param aValue pointer to the key value
sl@0: @return
sl@0: 	KErrNotFound if either section or keyname not found
sl@0: 	KErrNone if successful
sl@0: @post aKeyValue now points to the key value
sl@0: */
sl@0: EXPORT_C TInt CIniDocument8::GetKeyValue(const TDesC8& aSectionName,const TDesC8& aKey,TPtrC8& aValue) const
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->GetKeyValueL(aSectionName,aKey,aValue));
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Add a section to the ini document object
sl@0: @param aSectionName the name of the section to be added
sl@0: @return
sl@0: 	KErrNone if successful
sl@0: 	KErrAlreadyExists if the section with that name already exists
sl@0: 	Any other system wide error code
sl@0: @post a section with that name is created and added to the document object
sl@0: */
sl@0: EXPORT_C TInt CIniDocument8::AddSection(const TDesC8& aSectionName)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->AddSectionL(aSectionName));
sl@0: 	return ret;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Remove an existing section from the ini document object
sl@0: @param aSectionName the name of the section to be removed
sl@0: @return KErrNone if successful
sl@0: 	    KErrNotFound if section does not exist
sl@0: 	    Any other system wide error code
sl@0: @post if exist that section is removed from the document object	
sl@0: */	
sl@0: EXPORT_C TInt CIniDocument8::RemoveSection(const TDesC8& aSectionName)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->RemoveSectionL(aSectionName));
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Set the value of a key within a section.
sl@0: This API offers the following flexibility:
sl@0: -If section does not exist,create a section and key and value
sl@0: -If section exists but key does not exist, create the key and value
sl@0: -Else replace the existing key value with the new value
sl@0: @param aSectionName the name of the section
sl@0: @param aKey the name of the key
sl@0: @param aValue the new value for this key
sl@0: @return
sl@0: 	KErrNone if successful,any other system wide error code
sl@0: */
sl@0: EXPORT_C TInt CIniDocument8::SetKey(const TDesC8& aSectionName,const TDesC8& aKey,const TDesC8& aValue)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->SetKeyL(aSectionName,aKey,aValue));	
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Remove an existing key within a section
sl@0: if supplied section or key name does not exist, it does nothing
sl@0: @param aSectionName the name of the section where the key resides
sl@0: @param aKey the name of the key to be removed
sl@0: @post if exist that key is removed from the section
sl@0: */
sl@0: EXPORT_C TInt CIniDocument8::RemoveKey(const TDesC8& aSectionName,const TDesC8& aKey)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->RemoveKeyL(aSectionName,aKey));
sl@0: 	return ret;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Destructor
sl@0: */	
sl@0: EXPORT_C CIniDocument8::~CIniDocument8()
sl@0: 	{
sl@0: 	delete iImpl;
sl@0: 	}
sl@0: 
sl@0: CIniDocument8::CIniDocument8()
sl@0: {
sl@0: }
sl@0: 
sl@0: //
sl@0: /**
sl@0: Creates a 8 bit light weight parser
sl@0: @param aFs the handle to the file session
sl@0: @param aFileName the ini file name to open
sl@0: @return A pointer to a newly created CIniFile8 object
sl@0: @leave	KErrNoMemory if not enough memory
sl@0: 		KErrNotFound if the supplied file does not exist
sl@0: */
sl@0: EXPORT_C CIniFile8* CIniFile8::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: 	{
sl@0: 	CIniFile8* self=new (ELeave)CIniFile8;
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->iImpl=CIniFile8Impl::NewL(aFs,aFileName);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Public destructor
sl@0: */	
sl@0: EXPORT_C CIniFile8::~CIniFile8()
sl@0: 	{
sl@0: 	delete iImpl;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Get the value of a key within a section
sl@0: @param aSectionName the section where the key resides
sl@0: @param aKeyName the key name
sl@0: @param aValue pointer to the key value
sl@0: @return
sl@0: 	KErrNotFound if either section or keyname not found
sl@0: 	KErrNone if successful
sl@0: */	
sl@0: EXPORT_C TInt CIniFile8::FindVar(const TDesC8& aSectionName,const TDesC8& aKeyName,TPtrC8& aValue)	const
sl@0: 	{
sl@0: 	return iImpl->FindVar(aSectionName,aKeyName,aValue);
sl@0: 	}
sl@0: 	
sl@0: CIniFile8::CIniFile8(){}
sl@0: 
sl@0: //
sl@0: /**
sl@0: Creates a 16 bit section content iterator
sl@0: this iterator is used to navigate through the key value pairs
sl@0: within the section.Useful when the number of keys within the 
sl@0: section is unknown.
sl@0: @param aSectionName the name of the section to iterate
sl@0: @param aIniDocument the document object containing the section
sl@0: @return A pointer to a newly created CIniSecIter16 object
sl@0: @leave	KErrNoMemory if not enough memory
sl@0: 		KErrArgument if aIniDocument is NULL
sl@0: */
sl@0: EXPORT_C CIniSecIter16* CIniSecIter16::NewL(const TDesC16& aSectionName,const CIniDocument16* aIniDocument)
sl@0: {
sl@0: 	CIniSecIter16* self=new (ELeave)CIniSecIter16();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->iImpl=CIniSecIter16Impl::NewL(aSectionName,aIniDocument);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;	
sl@0: }
sl@0: 
sl@0: /**
sl@0: Return the next key value pair within the section
sl@0: @param aKey a pointer to contain the key name
sl@0: @param aValue a pointer to contain the key value
sl@0: @return ETrue if there are keyvalue pairs to return
sl@0: 	    EFalse if it is already end of section
sl@0: @post the iterator points to the next available keyvalue pair
sl@0: 	  the aKeyName points to  the key name
sl@0: 	  the aKeyValue points to the key value
sl@0: */	
sl@0: EXPORT_C TBool CIniSecIter16::Next(TPtrC16& aKey,TPtrC16& aValue)
sl@0: {
sl@0: 	return iImpl->Next(aKey,aValue);
sl@0: }
sl@0: 
sl@0: /**
sl@0: Look ahead in the section to check whether there is 
sl@0: still any keyvalue pair in the section to be read
sl@0: @return ETrue if it is already end of section
sl@0: 	    EFalse indicating the next keyvalue pair exists
sl@0: */
sl@0: EXPORT_C TBool CIniSecIter16::End()
sl@0: {
sl@0: 	return iImpl->End();
sl@0: }
sl@0: 
sl@0: /**
sl@0: Reset the iterator to point to the first keypair value within
sl@0: the section.
sl@0: @post the iterator now points to first keypair in the section
sl@0: */
sl@0: EXPORT_C void CIniSecIter16::Reset()
sl@0: {
sl@0: 	iImpl->Reset();
sl@0: }
sl@0: 
sl@0: /**
sl@0: Destructor
sl@0: */
sl@0: EXPORT_C CIniSecIter16::~CIniSecIter16()
sl@0: {
sl@0: 	delete iImpl;
sl@0: }
sl@0: 
sl@0: //Default constructor
sl@0: CIniSecIter16::CIniSecIter16()
sl@0: {
sl@0: }
sl@0: 
sl@0: //
sl@0: 
sl@0: /** 
sl@0: Opening 16 bit ini file for reading.If the supplied file name is a valid
sl@0: ini file, it will instantiate the object and read the content of 
sl@0: the ini file.If file not found it will simply instantiate the object.
sl@0: The file is opened for read only and close directly after the construction
sl@0: of this object is complete.
sl@0: User will need to explicitly call Externalise(aFileName) to write the content back to ini file.
sl@0: @param aFs the handle to the file session
sl@0: @param aFileName the ini file name to read from
sl@0: @return A pointer to a newly created CIniDocument16 object
sl@0: */
sl@0: EXPORT_C CIniDocument16* CIniDocument16::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: 	{
sl@0: 	CIniDocument16* self=new (ELeave)CIniDocument16();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->iImpl=CIniDocument16Impl::NewL(aFs,aFileName);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Flush the buffered content to an output file name
sl@0: This will first write into a temporary file in the same directory and path
sl@0: as the supplied aFileName.It will then replace the existing file or 
sl@0: create a new file if does not exist yet.
sl@0: @param aFileName the output file name to write to
sl@0: @return KErrNone if no error
sl@0: 		Other System Wide errors
sl@0: */
sl@0: EXPORT_C TInt CIniDocument16::Externalise(const TDesC& aFileName)
sl@0: {
sl@0: 	TRAPD(r,iImpl->FlushL(aFileName));
sl@0: 	return r;
sl@0: }
sl@0: 	
sl@0: /** 
sl@0: Get an array of the section name present in the ini document object
sl@0: Note that any items inside this array will be cleared and the array will
sl@0: be populated with the sections' names from this document object.
sl@0: @param aSectionList an array of descriptor to contain the section name
sl@0: @return KErrNone if successful, otherwise another of the system-wide error codes
sl@0: @post aSectionList contains all the section name in the document object
sl@0: */
sl@0: EXPORT_C TInt CIniDocument16::GetSectionList(RArray<TPtrC16>& aSectionList) const
sl@0: 	{
sl@0: 	return iImpl->GetSectionList(aSectionList);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Get the value of a key within a section
sl@0: @param aSectionName the section where the key resides
sl@0: @param aKey the key name
sl@0: @param aValue pointer to the key value
sl@0: @return
sl@0: 	KErrNotFound if either section or keyname not found
sl@0: 	KErrNone if successful
sl@0: @post aKeyValue now points to the key value
sl@0: */
sl@0: EXPORT_C TInt CIniDocument16::GetKeyValue(const TDesC16& aSectionName,const TDesC16& aKey,TPtrC16& aValue) const
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->GetKeyValueL(aSectionName,aKey,aValue));
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Add a section to the ini document object
sl@0: @param aSectionName the name of the section to be added
sl@0: @return
sl@0: 	KErrNone if successful
sl@0: 	KErrAlreadyExists if the section with that name already exists
sl@0: 	Any other system wide error code
sl@0: @post a section with that name is created and added to the document object
sl@0: */
sl@0: EXPORT_C TInt CIniDocument16::AddSection(const TDesC16& aSectionName)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->AddSectionL(aSectionName));
sl@0: 	return ret;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Remove an existing section from the ini document object
sl@0: @param aSectionName the name of the section to be removed
sl@0: @return KErrNone if successful
sl@0: 	    KErrNotFound if section does not exist
sl@0: 	    Any other system wide error code
sl@0: @post if exist that section is removed from the document object	
sl@0: */	
sl@0: EXPORT_C TInt CIniDocument16::RemoveSection(const TDesC16& aSectionName)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->RemoveSectionL(aSectionName));
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Set the value of a key within a section.
sl@0: This API offers the following flexibility:
sl@0: -If section does not exist,create a section and key and value
sl@0: -If section exists but key does not exist, create the key and value
sl@0: -Else replace the existing key value with the new value
sl@0: @param aSectionName the name of the section
sl@0: @param aKey the name of the key
sl@0: @param aValue the new value for this key
sl@0: @return
sl@0: 	KErrNone if successful,any other system wide error code
sl@0: */
sl@0: EXPORT_C TInt CIniDocument16::SetKey(const TDesC16& aSectionName,const TDesC16& aKey,const TDesC16& aValue)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->SetKeyL(aSectionName,aKey,aValue));	
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Remove an existing key within a section
sl@0: if supplied section or key name does not exist, it does nothing
sl@0: @param aSectionName the name of the section where the key resides
sl@0: @param aKey the name of the key to be removed
sl@0: @post if exist that key is removed from the section
sl@0: */
sl@0: EXPORT_C TInt CIniDocument16::RemoveKey(const TDesC16& aSectionName,const TDesC16& aKey)
sl@0: 	{
sl@0: 	TRAPD(ret,iImpl->RemoveKeyL(aSectionName,aKey));
sl@0: 	return ret;	
sl@0: 	}
sl@0: /**
sl@0: Compare two document objects. If names, keys or values differ, a false is returned,
sl@0: else a true is returned.
sl@0: @param aDoc name of the document to compare against this object.
sl@0: */
sl@0: EXPORT_C TBool CIniDocument16::CompareDocs(CIniDocument16& aDoc)	
sl@0: 	{
sl@0: 	return (iImpl->CompareDocs( *(aDoc.iImpl) ));
sl@0: 	}	
sl@0: /**
sl@0: Destructor
sl@0: */	
sl@0: EXPORT_C CIniDocument16::~CIniDocument16()
sl@0: 	{
sl@0: 	delete iImpl;
sl@0: 	}
sl@0: 
sl@0: CIniDocument16::CIniDocument16(){}
sl@0: 
sl@0: //
sl@0: /**
sl@0: Creates a 16 bit light weight parser
sl@0: @param aFs the handle to the file session
sl@0: @param aFileName the ini file name to open
sl@0: @return A pointer to a newly created CIniFile16 object
sl@0: @leave	KErrNoMemory if not enough memory
sl@0: 		KErrNotFound if the supplied file does not exist
sl@0: */
sl@0: EXPORT_C CIniFile16* CIniFile16::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: 	{
sl@0: 	return CIniFile16::NewL(aFs,aFileName,EFalse);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Creates a 16 bit light weight parser
sl@0: @param aFs the handle to the file session
sl@0: @param aFileName the ini file name to open
sl@0: @param aConvert8To16 upconvert 8 bit files otherwise leave with KErrCorrupt
sl@0: @return A pointer to a newly created CIniFile16 object
sl@0: @leave	KErrNoMemory if not enough memory
sl@0: 		KErrNotFound if the supplied file does not exist
sl@0: */
sl@0: EXPORT_C CIniFile16* CIniFile16::NewL(RFs& aFs,const TDesC& aFileName,TBool aConvert8To16)
sl@0: 	{
sl@0: 	CIniFile16* self=new (ELeave)CIniFile16;
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->iImpl=CIniFile16Impl::NewL(aFs,aFileName,aConvert8To16);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Public Destructor
sl@0: */	
sl@0: EXPORT_C CIniFile16::~CIniFile16()
sl@0: 	{
sl@0: 	delete iImpl;	
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Get the value of a key within a section
sl@0: @param aSectionName the section where the key resides
sl@0: @param aKeyName the key name
sl@0: @param aValue pointer to the key value
sl@0: @return
sl@0: 	KErrNotFound if either section or keyname not found
sl@0: 	KErrNone if successful
sl@0: */		
sl@0: EXPORT_C TInt CIniFile16::FindVar(const TDesC16& aSectionName,const TDesC16& aKeyName,TPtrC16& aValue)const
sl@0: 	{
sl@0: 	return iImpl->FindVar(aSectionName,aKeyName,aValue);
sl@0: 	}
sl@0: 	
sl@0: CIniFile16::CIniFile16(){}
sl@0: 
sl@0: //
sl@0: 
sl@0: CIniDocument8Impl* CIniDocument8Impl::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: {
sl@0: 	CIniDocument8Impl* self= new (ELeave) CIniDocument8Impl();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aFs,aFileName);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: }
sl@0: 
sl@0: // This method will panic if, when reading the input configuration file, a key
sl@0: // is attempted to be processed without a valid section name being already defined.
sl@0: void CIniDocument8Impl::ConstructL(RFs& aFs,const TDesC& aFileName)
sl@0: {
sl@0: 	TInt    filesize=0;
sl@0: 	TInt    startOfLine=0;
sl@0: 	CIniSection8* section = NULL;
sl@0: 	HBufC8* fileBuffer=NULL;
sl@0: 	iTempImpl=new (ELeave)CIniDocumentTmpl8(aFs,ETrue);
sl@0: 	
sl@0: 	TRAPD(ret,GetBufferL(aFs,aFileName,fileBuffer));
sl@0: 	//if the file is not found, assume we are creating a new file.
sl@0: 	if (ret==KErrNotFound)
sl@0: 		{
sl@0: 		return;
sl@0: 		}
sl@0: 	User::LeaveIfError(ret);
sl@0: 	if (!fileBuffer)
sl@0: 		{	
sl@0: 		return;	
sl@0: 		}	
sl@0: 	CleanupStack::PushL(fileBuffer);
sl@0: 	filesize = fileBuffer->Length();
sl@0: 	TPtrC8 bufferDescriptor = fileBuffer->Des();
sl@0: 	while (startOfLine < filesize)
sl@0: 		{
sl@0: 		TPtrC8 myBuffer = ExtractLineFromBuffer<HBufC8, TPtrC8>(bufferDescriptor, startOfLine);
sl@0: 		CIniLine8* line = CIniLine8::NewLC(myBuffer);
sl@0: 		startOfLine += (line->LineBuffer()).Length();
sl@0: 		
sl@0: 		switch(line->LineType())
sl@0: 			{
sl@0: 			case ESection:
sl@0: 			 	section = CIniSection8::NewLC(line);
sl@0: 			 	iTempImpl->AddSectionL(section);
sl@0: 			 	CleanupStack::Pop(section);
sl@0: 			 	break;
sl@0: 			 	
sl@0: 			case EKeyValue:
sl@0: 				{
sl@0: 				CIniKey8* key = CIniKey8::NewLC(line);
sl@0: 				if (section == NULL)
sl@0: 					{
sl@0: 					User::Leave(KErrCorrupt);	//Unnamed sections within the file are not allowed but not preventable, hence leave if found. 
sl@0: 					}
sl@0: 			 	section->InsertKeyL(key);
sl@0: 			 	CleanupStack::Pop(key);
sl@0: 			 	break;
sl@0: 				}
sl@0: 				
sl@0: 			case EComment:
sl@0: 				break;
sl@0: 				
sl@0: 			default:
sl@0: 				User::Panic(_L("Invalid LineType"), KErrCorrupt);	// programming error.
sl@0: 			}
sl@0: 		iTempImpl->AppendIntoQueue(line);
sl@0: 		CleanupStack::Pop(line);
sl@0: 		}
sl@0: 	CleanupStack::PopAndDestroy(fileBuffer);
sl@0: }
sl@0: 
sl@0: void CIniDocument8Impl::FlushL(const TDesC& aFileName)
sl@0: {
sl@0: 	iTempImpl->FlushL(aFileName);
sl@0: }
sl@0: 
sl@0: TInt CIniDocument8Impl::GetSectionList(RArray<TPtrC8>& aSectionList) const
sl@0: {
sl@0: 	return iTempImpl->GetSectionList(aSectionList);
sl@0: }
sl@0: 
sl@0: void CIniDocument8Impl::GetKeyValueL(const TDesC8& aSectionName,const TDesC8& aKeyName,TPtrC8& aKeyValue) const
sl@0: {
sl@0: 	iTempImpl->GetKeyValueL(aSectionName,aKeyName,aKeyValue);
sl@0: }
sl@0: 
sl@0: void CIniDocument8Impl::AddSectionL(const TDesC8& aSectionName)
sl@0: {
sl@0: 	iTempImpl->AddSectionL(aSectionName);
sl@0: }
sl@0: 
sl@0: void CIniDocument8Impl::RemoveSectionL(const TDesC8& aSectionName)
sl@0: {
sl@0: 	iTempImpl->RemoveSectionL(aSectionName);
sl@0: }
sl@0: 
sl@0: void CIniDocument8Impl::SetKeyL(const TDesC8& aSectionName,const TDesC8& aKeyName,const TDesC8& aKeyValue)
sl@0: {
sl@0: 	iTempImpl->SetKeyL(aSectionName,aKeyName,aKeyValue);
sl@0: }
sl@0: 
sl@0: void CIniDocument8Impl::RemoveKeyL(const TDesC8& aSectionName,const TDesC8& aKeyName)
sl@0: {
sl@0: 	iTempImpl->RemoveKeyL(aSectionName,aKeyName);
sl@0: }
sl@0: 
sl@0: CIniDocument8Impl::~CIniDocument8Impl()
sl@0: {
sl@0: 	delete iTempImpl;
sl@0: }
sl@0: 
sl@0: CIniSection8* CIniDocument8Impl::SectionL(const TDesC8& aSectionName) const
sl@0: {
sl@0: 	return iTempImpl->SectionL(aSectionName);
sl@0: }
sl@0: 
sl@0: TBool CIniDocument8Impl::CompareDocs(CIniDocument8Impl& aDocImpl) 
sl@0: {
sl@0: 	return(iTempImpl->CompareDocs(*aDocImpl.iTempImpl));
sl@0: }
sl@0: 
sl@0: //
sl@0: CIniDocument16Impl* CIniDocument16Impl::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: {
sl@0: 	CIniDocument16Impl* self= new (ELeave) CIniDocument16Impl();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aFs,aFileName);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::ConstructL(RFs& aFs,const TDesC& aFileName)
sl@0: {
sl@0: 	TInt    filesize=0;
sl@0: 	TInt    startOfLine=0;
sl@0: 	CIniSection16* section = NULL;
sl@0: 	HBufC8* fileBuffer=NULL;
sl@0: 	iTempImpl=new (ELeave)CIniDocumentTmpl16(aFs,EFalse);
sl@0: 	
sl@0: 	TRAPD(ret,GetBufferL(aFs,aFileName,fileBuffer));
sl@0: 	//if the file is not found, assume we are creating a new file.
sl@0: 	if (ret==KErrNotFound)
sl@0: 		{
sl@0: 		return;
sl@0: 		}
sl@0: 	User::LeaveIfError(ret);
sl@0: 	if (!fileBuffer)
sl@0: 		{	
sl@0: 		return;	
sl@0: 		}	
sl@0: 	CleanupStack::PushL(fileBuffer);
sl@0: 	filesize = fileBuffer->Length()/2;
sl@0: 	
sl@0: 	// process the filemark at the start of the file.
sl@0: 	const TUint16* rawptr16=reinterpret_cast<const TUint16*>(fileBuffer->Ptr());
sl@0: 	TPtrC16 bufferPtr;
sl@0: 	
sl@0: 	//must always start with the byte ordering characters
sl@0: 	bufferPtr.Set(rawptr16,1);
sl@0: 	if (bufferPtr.Compare(_L("\xFEFF"))!=0)
sl@0: 		User::Leave(KErrCorrupt);
sl@0: 	//skip the byte ordering character(FEFF) assuming little endian
sl@0: 	bufferPtr.Set(rawptr16+1,(filesize - 1));	
sl@0: 	
sl@0: 	while (startOfLine < (filesize-1))
sl@0: 		{
sl@0: 		TPtrC16 myBuffer = ExtractLineFromBuffer<HBufC16, TPtrC16>(bufferPtr, startOfLine);
sl@0: 		CIniLine16* line = CIniLine16::NewLC(myBuffer);
sl@0: 		startOfLine += (line->LineBuffer()).Length();
sl@0: 		
sl@0: 		TLineType lineType = line->LineType();
sl@0: 		switch (lineType)
sl@0: 			{
sl@0: 			case ESection:
sl@0: 				section = CIniSection16::NewLC(line);
sl@0: 				iTempImpl->AddSectionL(section);
sl@0: 			 	CleanupStack::Pop(section);
sl@0: 			 	break;
sl@0: 			 	
sl@0: 			case EKeyValue:
sl@0: 				{
sl@0: 				CIniKey16* key = CIniKey16::NewLC(line);
sl@0: 				
sl@0: 				if (section == NULL)
sl@0: 					{
sl@0: 					User::Leave(KErrCorrupt);	//Unnamed sections are not allowed hence leave if found.
sl@0: 					}
sl@0: 				section->InsertKeyL(key);
sl@0: 				CleanupStack::Pop(key);
sl@0: 			 	break;
sl@0: 				}
sl@0: 				
sl@0: 			case EComment:
sl@0: 				break;
sl@0: 				
sl@0: 			default:
sl@0: 				User::Panic(_L("Invalid LineType"), KErrCorrupt);
sl@0: 			}
sl@0: 		iTempImpl->AppendIntoQueue(line);
sl@0: 		CleanupStack::Pop(line);
sl@0: 	}	
sl@0: 	CleanupStack::PopAndDestroy(fileBuffer);
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::FlushL(const TDesC& aFileName)
sl@0: {
sl@0: 	iTempImpl->FlushL(aFileName);
sl@0: }
sl@0: 
sl@0: TInt CIniDocument16Impl::GetSectionList(RArray<TPtrC16>& aSectionList) const
sl@0: {
sl@0: 	return iTempImpl->GetSectionList(aSectionList);
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::GetKeyValueL(const TDesC16& aSectionName,const TDesC16& aKeyName,TPtrC16& aKeyValue) const
sl@0: {
sl@0: 	iTempImpl->GetKeyValueL(aSectionName,aKeyName,aKeyValue);
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::AddSectionL(const TDesC16& aSectionName)
sl@0: {
sl@0: 	iTempImpl->AddSectionL(aSectionName);
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::RemoveSectionL(const TDesC16& aSectionName)
sl@0: {
sl@0: 	iTempImpl->RemoveSectionL(aSectionName);
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::SetKeyL(const TDesC16& aSectionName,const TDesC16& aKeyName,const TDesC16& aKeyValue)
sl@0: {
sl@0: 	iTempImpl->SetKeyL(aSectionName,aKeyName,aKeyValue);
sl@0: }
sl@0: 
sl@0: void CIniDocument16Impl::RemoveKeyL(const TDesC16& aSectionName,const TDesC16& aKeyName)
sl@0: {
sl@0: 	iTempImpl->RemoveKeyL(aSectionName,aKeyName);
sl@0: }
sl@0: 
sl@0: CIniDocument16Impl::~CIniDocument16Impl()
sl@0: 	{
sl@0: 	delete iTempImpl;
sl@0: 	}
sl@0: 
sl@0: CIniSection16* CIniDocument16Impl::SectionL(const TDesC16& aSectionName) const
sl@0: {
sl@0: 	return iTempImpl->SectionL(aSectionName);
sl@0: }
sl@0: 
sl@0: TBool CIniDocument16Impl::CompareDocs(CIniDocument16Impl& aDocImpl) 
sl@0: {
sl@0: 	return(iTempImpl->CompareDocs(*(aDocImpl.iTempImpl)));
sl@0: }
sl@0: 
sl@0: //	
sl@0: 
sl@0: CIniSecIter8Impl* CIniSecIter8Impl::NewL(const TDesC8& aSectionName,const CIniDocument8* aIniDocument) 
sl@0: 	{
sl@0: 	CIniSecIter8Impl* self=new (ELeave)CIniSecIter8Impl();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aSectionName,aIniDocument);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: void CIniSecIter8Impl::ConstructL(const TDesC8& aSectionName,const CIniDocument8* aIniDocument)
sl@0: 	{
sl@0: 	iTempImpl=new (ELeave)CIniSecIterTmpl8();
sl@0: 	if (!aIniDocument)
sl@0: 		User::Leave(KErrArgument);
sl@0: 	iTempImpl->iSection=aIniDocument->iImpl->SectionL(aSectionName);
sl@0: 	}
sl@0: 	
sl@0: TBool CIniSecIter8Impl::Next(TPtrC8& aKeyName,TPtrC8& aKeyValue)	
sl@0: 	{
sl@0: 	return iTempImpl->Next(aKeyName,aKeyValue);
sl@0: 	}
sl@0: 	
sl@0: void CIniSecIter8Impl::Reset()
sl@0: 	{
sl@0: 	iTempImpl->Reset();	
sl@0: 	}
sl@0: 
sl@0: //
sl@0: CIniSecIter16Impl* CIniSecIter16Impl::NewL(const TDesC16& aSectionName,const CIniDocument16* aIniDocument) 
sl@0: 	{
sl@0: 	CIniSecIter16Impl* self=new (ELeave)CIniSecIter16Impl();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aSectionName,aIniDocument);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: void CIniSecIter16Impl::ConstructL(const TDesC16& aSectionName,const CIniDocument16* aIniDocument)
sl@0: 	{
sl@0: 	iTempImpl=new (ELeave)CIniSecIterTmpl16();
sl@0: 	if (!aIniDocument)
sl@0: 		User::Leave(KErrArgument);	
sl@0: 	iTempImpl->iSection=aIniDocument->iImpl->SectionL(aSectionName);
sl@0: 	}
sl@0: 	
sl@0: TBool CIniSecIter16Impl::Next(TPtrC16& aKeyName,TPtrC16& aKeyValue)	
sl@0: 	{
sl@0: 	return iTempImpl->Next(aKeyName,aKeyValue);
sl@0: 	}
sl@0: 	
sl@0: void CIniSecIter16Impl::Reset()
sl@0: 	{
sl@0: 	iTempImpl->Reset();
sl@0: 	}
sl@0: 
sl@0: //
sl@0: CIniFile8Impl* CIniFile8Impl::NewL(RFs& aFs,const TDesC& aFileName)
sl@0: 	{
sl@0: 	CIniFile8Impl* self=new (ELeave)CIniFile8Impl;
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aFs,aFileName);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: void CIniFile8Impl::ConstructL(RFs& aFs,const TDesC& aFileName)
sl@0: 	{
sl@0: 	iTempImpl=new (ELeave)CIniFileTmpl8();
sl@0: 	HBufC8* tempBuffer=NULL;
sl@0: 	//read the file
sl@0: 	GetBufferL(aFs,aFileName,tempBuffer);
sl@0: 	if (tempBuffer)
sl@0: 		{
sl@0: 		CleanupStack::PushL(tempBuffer);
sl@0: 		iTempImpl->ProcessBufferL(*tempBuffer);
sl@0: 		CleanupStack::Pop();
sl@0: 		delete tempBuffer;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: TInt CIniFile8Impl::FindVar(const TDesC8& aSection,const TDesC8& aKey,TPtrC8& aValue)
sl@0: 	{
sl@0: 	return iTempImpl->FindVar(aSection,aKey,aValue);	
sl@0: 	}
sl@0: 
sl@0: //
sl@0: CIniFile16Impl* CIniFile16Impl::NewL(RFs& aFs,const TDesC& aFileName,TBool aConvert8To16)
sl@0: 	{
sl@0: 	CIniFile16Impl* self=new (ELeave)CIniFile16Impl;
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL(aFs,aFileName,aConvert8To16);
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: void CIniFile16Impl::ConstructL(RFs& aFs,const TDesC& aFileName,TBool aConvert8To16)
sl@0: 	{
sl@0: 	iTempImpl=new (ELeave)CIniFileTmpl16();
sl@0: 	HBufC8* tempBuffer=NULL;
sl@0: 	//read the file
sl@0: 	GetBufferL(aFs,aFileName,tempBuffer);
sl@0: 	if (tempBuffer)
sl@0: 		{
sl@0: 		CleanupStack::PushL(tempBuffer);
sl@0: 		TPtrC16 bufferPtr;
sl@0: 		const TUint16* rawptr16=reinterpret_cast<const TUint16*>(tempBuffer->Ptr());
sl@0: 		//must always start with the byte ordering characters
sl@0: 		bufferPtr.Set(rawptr16,1);
sl@0: 		if (bufferPtr.Compare(_L("\xFEFF"))==0)
sl@0: 			{
sl@0: 			//skip the byte ordering character(FEFF) assuming little endian
sl@0: 			bufferPtr.Set(rawptr16+1,(tempBuffer->Length()/2)-1);
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			//byte ordering characters not found, so leave, unless we should upconvert
sl@0: 			if (!aConvert8To16)
sl@0: 				{			
sl@0: 				User::Leave(KErrCorrupt);
sl@0: 				}
sl@0: 			//treat as an 8-bit file and upconvert to 16
sl@0: 			HBufC16* tempBuffer16=HBufC16::NewL(tempBuffer->Length());
sl@0: 			tempBuffer16->Des().Copy(*tempBuffer);
sl@0: 			CleanupStack::PopAndDestroy(tempBuffer);
sl@0: 			CleanupStack::PushL(tempBuffer16);	
sl@0: 			bufferPtr.Set(*tempBuffer16);
sl@0: 			}	
sl@0: 		iTempImpl->ProcessBufferL(bufferPtr);
sl@0: 		CleanupStack::PopAndDestroy();
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: TInt CIniFile16Impl::FindVar(const TDesC16& aSection,const TDesC16& aKey,TPtrC16& aValue)
sl@0: 	{
sl@0: 	return iTempImpl->FindVar(aSection,aKey,aValue);	
sl@0: 	}
sl@0: 	
sl@0: }//namespace
sl@0: 
sl@0: