lowlevellibsandfws/apputils/bsul/src/IniParserImpl.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // 8 and 16 bit ini file parser
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalAll
       
    21 */
       
    22 
       
    23 #include "IniParserImpl.h"
       
    24 #include "inifile.h"
       
    25 #include "s32file.h"
       
    26 
       
    27 namespace BSUL
       
    28 {
       
    29 /**
       
    30 Creates a 8 bit section content iterator
       
    31 this iterator is used to navigate through the key value pairs
       
    32 within the section.Useful when the number of keys within the 
       
    33 section is unknown.
       
    34 @param aSectionName the name of the section to iterate
       
    35 @param aIniDocument the document object containing the section
       
    36 @return A pointer to a newly created CIniSecIter8 object
       
    37 @leave	KErrNoMemory if not enough memory
       
    38 		KErrArgument if aIniDocument is NULL
       
    39 */
       
    40 EXPORT_C CIniSecIter8* CIniSecIter8::NewL(const TDesC8& aSectionName,const CIniDocument8* aIniDocument)
       
    41 {
       
    42 	CIniSecIter8* self=new (ELeave)CIniSecIter8();
       
    43 	CleanupStack::PushL(self);
       
    44 	self->iImpl=CIniSecIter8Impl::NewL(aSectionName,aIniDocument);
       
    45 	CleanupStack::Pop();
       
    46 	return self;	
       
    47 }
       
    48 
       
    49 /**
       
    50 Return the next key value pair within the section
       
    51 @param aKey a pointer to contain the key name
       
    52 @param aValue a pointer to contain the key value
       
    53 @return ETrue if there are keyvalue pairs to return
       
    54 	    EFalse if it is already end of section
       
    55 @post the iterator points to the next available keyvalue pair
       
    56 	  the aKeyName points to  the key name
       
    57 	  the aKeyValue points to the key value
       
    58 */	
       
    59 EXPORT_C TBool CIniSecIter8::Next(TPtrC8& aKey,TPtrC8& aValue)
       
    60 {
       
    61 	return iImpl->Next(aKey,aValue);
       
    62 }
       
    63 
       
    64 /**
       
    65 Look ahead in the section to check whether there is 
       
    66 still any keyvalue pair in the section to be read
       
    67 @return ETrue if it is already end of section
       
    68 	    EFalse indicating the next keyvalue pair exists
       
    69 */
       
    70 EXPORT_C TBool CIniSecIter8::End()
       
    71 {
       
    72 	return iImpl->End();
       
    73 }
       
    74 
       
    75 /**
       
    76 Reset the iterator to point to the first keypair value within
       
    77 the section.
       
    78 @post the iterator now points to first keypair in the section
       
    79 */
       
    80 EXPORT_C void CIniSecIter8::Reset()
       
    81 {
       
    82 	iImpl->Reset();
       
    83 }
       
    84 
       
    85 /**
       
    86 Destructor
       
    87 */
       
    88 EXPORT_C CIniSecIter8::~CIniSecIter8()
       
    89 {
       
    90 	delete iImpl;
       
    91 }
       
    92 
       
    93 //Default constructor
       
    94 CIniSecIter8::CIniSecIter8()
       
    95 {
       
    96 }
       
    97 
       
    98 //
       
    99 
       
   100 /** 
       
   101 Opening 8 bit ini file for reading.If the supplied file name is a valid
       
   102 ini file, it will instantiate the object and read the content of 
       
   103 the ini file.If file not found it will simply instantiate the object.
       
   104 The file is opened for read only and close directly after the construction
       
   105 of this object is complete.
       
   106 User will need to explicitly call Externalise(aFileName) to write the content back to ini file.
       
   107 @param aFs the handle to the file session
       
   108 @param aFileName the ini file name to read from
       
   109 @return A pointer to a newly created CIniDocument8 object
       
   110 */
       
   111 EXPORT_C CIniDocument8* CIniDocument8::NewL(RFs& aFs,const TDesC& aFileName)
       
   112 	{
       
   113 	CIniDocument8* self=new (ELeave)CIniDocument8();
       
   114 	CleanupStack::PushL(self);
       
   115 	self->iImpl=CIniDocument8Impl::NewL(aFs,aFileName);
       
   116 	CleanupStack::Pop();
       
   117 	return self;	
       
   118 	}
       
   119 
       
   120 /**
       
   121 Externalise the buffered content to an output file name
       
   122 This will first write into a temporary file in the same directory and path
       
   123 as the supplied aFileName.It will then replace the existing file or 
       
   124 create a new file if does not exist yet.
       
   125 @param aFileName the output file name to write to
       
   126 @return KErrNone if no error
       
   127 		Other System Wide errors
       
   128 */
       
   129 EXPORT_C TInt CIniDocument8::Externalise(const TDesC& aFileName)
       
   130 {
       
   131 	TRAPD(r,iImpl->FlushL(aFileName));
       
   132 	return r;
       
   133 }
       
   134 /**
       
   135 Compare this document against another for differences.
       
   136 @param aDoc to compare against.
       
   137 @return True if same
       
   138 		Otherwise false
       
   139 */
       
   140 EXPORT_C TBool CIniDocument8::CompareDocs(CIniDocument8& aDoc) 
       
   141 	{
       
   142 	return (iImpl->CompareDocs( *(aDoc.iImpl) ));
       
   143 	}	
       
   144 
       
   145 /** 
       
   146 Get an array of the section name present in the ini document object
       
   147 Note that any items inside this array will be cleared and the array will
       
   148 be populated with the sections' names from this document object.
       
   149 @param aSectionList an array of descriptor to contain the section name
       
   150 @return KErrNone if successful, otherwise another of the system-wide error codes
       
   151 @post aSectionList contains all the section name in the document object
       
   152 */
       
   153 EXPORT_C TInt CIniDocument8::GetSectionList(RArray<TPtrC8>& aSectionList) const
       
   154 	{
       
   155 	return iImpl->GetSectionList(aSectionList);
       
   156 	}
       
   157 
       
   158 /**
       
   159 Get the value of a key within a section
       
   160 @param aSectionName the section where the key resides
       
   161 @param aKey the key name
       
   162 @param aValue pointer to the key value
       
   163 @return
       
   164 	KErrNotFound if either section or keyname not found
       
   165 	KErrNone if successful
       
   166 @post aKeyValue now points to the key value
       
   167 */
       
   168 EXPORT_C TInt CIniDocument8::GetKeyValue(const TDesC8& aSectionName,const TDesC8& aKey,TPtrC8& aValue) const
       
   169 	{
       
   170 	TRAPD(ret,iImpl->GetKeyValueL(aSectionName,aKey,aValue));
       
   171 	return ret;
       
   172 	}
       
   173 
       
   174 /**
       
   175 Add a section to the ini document object
       
   176 @param aSectionName the name of the section to be added
       
   177 @return
       
   178 	KErrNone if successful
       
   179 	KErrAlreadyExists if the section with that name already exists
       
   180 	Any other system wide error code
       
   181 @post a section with that name is created and added to the document object
       
   182 */
       
   183 EXPORT_C TInt CIniDocument8::AddSection(const TDesC8& aSectionName)
       
   184 	{
       
   185 	TRAPD(ret,iImpl->AddSectionL(aSectionName));
       
   186 	return ret;	
       
   187 	}
       
   188 
       
   189 /**
       
   190 Remove an existing section from the ini document object
       
   191 @param aSectionName the name of the section to be removed
       
   192 @return KErrNone if successful
       
   193 	    KErrNotFound if section does not exist
       
   194 	    Any other system wide error code
       
   195 @post if exist that section is removed from the document object	
       
   196 */	
       
   197 EXPORT_C TInt CIniDocument8::RemoveSection(const TDesC8& aSectionName)
       
   198 	{
       
   199 	TRAPD(ret,iImpl->RemoveSectionL(aSectionName));
       
   200 	return ret;
       
   201 	}
       
   202 
       
   203 /**
       
   204 Set the value of a key within a section.
       
   205 This API offers the following flexibility:
       
   206 -If section does not exist,create a section and key and value
       
   207 -If section exists but key does not exist, create the key and value
       
   208 -Else replace the existing key value with the new value
       
   209 @param aSectionName the name of the section
       
   210 @param aKey the name of the key
       
   211 @param aValue the new value for this key
       
   212 @return
       
   213 	KErrNone if successful,any other system wide error code
       
   214 */
       
   215 EXPORT_C TInt CIniDocument8::SetKey(const TDesC8& aSectionName,const TDesC8& aKey,const TDesC8& aValue)
       
   216 	{
       
   217 	TRAPD(ret,iImpl->SetKeyL(aSectionName,aKey,aValue));	
       
   218 	return ret;
       
   219 	}
       
   220 
       
   221 /**
       
   222 Remove an existing key within a section
       
   223 if supplied section or key name does not exist, it does nothing
       
   224 @param aSectionName the name of the section where the key resides
       
   225 @param aKey the name of the key to be removed
       
   226 @post if exist that key is removed from the section
       
   227 */
       
   228 EXPORT_C TInt CIniDocument8::RemoveKey(const TDesC8& aSectionName,const TDesC8& aKey)
       
   229 	{
       
   230 	TRAPD(ret,iImpl->RemoveKeyL(aSectionName,aKey));
       
   231 	return ret;	
       
   232 	}
       
   233 
       
   234 /**
       
   235 Destructor
       
   236 */	
       
   237 EXPORT_C CIniDocument8::~CIniDocument8()
       
   238 	{
       
   239 	delete iImpl;
       
   240 	}
       
   241 
       
   242 CIniDocument8::CIniDocument8()
       
   243 {
       
   244 }
       
   245 
       
   246 //
       
   247 /**
       
   248 Creates a 8 bit light weight parser
       
   249 @param aFs the handle to the file session
       
   250 @param aFileName the ini file name to open
       
   251 @return A pointer to a newly created CIniFile8 object
       
   252 @leave	KErrNoMemory if not enough memory
       
   253 		KErrNotFound if the supplied file does not exist
       
   254 */
       
   255 EXPORT_C CIniFile8* CIniFile8::NewL(RFs& aFs,const TDesC& aFileName)
       
   256 	{
       
   257 	CIniFile8* self=new (ELeave)CIniFile8;
       
   258 	CleanupStack::PushL(self);
       
   259 	self->iImpl=CIniFile8Impl::NewL(aFs,aFileName);
       
   260 	CleanupStack::Pop();
       
   261 	return self;
       
   262 	}
       
   263 
       
   264 /**
       
   265 Public destructor
       
   266 */	
       
   267 EXPORT_C CIniFile8::~CIniFile8()
       
   268 	{
       
   269 	delete iImpl;	
       
   270 	}
       
   271 
       
   272 /**
       
   273 Get the value of a key within a section
       
   274 @param aSectionName the section where the key resides
       
   275 @param aKeyName the key name
       
   276 @param aValue pointer to the key value
       
   277 @return
       
   278 	KErrNotFound if either section or keyname not found
       
   279 	KErrNone if successful
       
   280 */	
       
   281 EXPORT_C TInt CIniFile8::FindVar(const TDesC8& aSectionName,const TDesC8& aKeyName,TPtrC8& aValue)	const
       
   282 	{
       
   283 	return iImpl->FindVar(aSectionName,aKeyName,aValue);
       
   284 	}
       
   285 	
       
   286 CIniFile8::CIniFile8(){}
       
   287 
       
   288 //
       
   289 /**
       
   290 Creates a 16 bit section content iterator
       
   291 this iterator is used to navigate through the key value pairs
       
   292 within the section.Useful when the number of keys within the 
       
   293 section is unknown.
       
   294 @param aSectionName the name of the section to iterate
       
   295 @param aIniDocument the document object containing the section
       
   296 @return A pointer to a newly created CIniSecIter16 object
       
   297 @leave	KErrNoMemory if not enough memory
       
   298 		KErrArgument if aIniDocument is NULL
       
   299 */
       
   300 EXPORT_C CIniSecIter16* CIniSecIter16::NewL(const TDesC16& aSectionName,const CIniDocument16* aIniDocument)
       
   301 {
       
   302 	CIniSecIter16* self=new (ELeave)CIniSecIter16();
       
   303 	CleanupStack::PushL(self);
       
   304 	self->iImpl=CIniSecIter16Impl::NewL(aSectionName,aIniDocument);
       
   305 	CleanupStack::Pop();
       
   306 	return self;	
       
   307 }
       
   308 
       
   309 /**
       
   310 Return the next key value pair within the section
       
   311 @param aKey a pointer to contain the key name
       
   312 @param aValue a pointer to contain the key value
       
   313 @return ETrue if there are keyvalue pairs to return
       
   314 	    EFalse if it is already end of section
       
   315 @post the iterator points to the next available keyvalue pair
       
   316 	  the aKeyName points to  the key name
       
   317 	  the aKeyValue points to the key value
       
   318 */	
       
   319 EXPORT_C TBool CIniSecIter16::Next(TPtrC16& aKey,TPtrC16& aValue)
       
   320 {
       
   321 	return iImpl->Next(aKey,aValue);
       
   322 }
       
   323 
       
   324 /**
       
   325 Look ahead in the section to check whether there is 
       
   326 still any keyvalue pair in the section to be read
       
   327 @return ETrue if it is already end of section
       
   328 	    EFalse indicating the next keyvalue pair exists
       
   329 */
       
   330 EXPORT_C TBool CIniSecIter16::End()
       
   331 {
       
   332 	return iImpl->End();
       
   333 }
       
   334 
       
   335 /**
       
   336 Reset the iterator to point to the first keypair value within
       
   337 the section.
       
   338 @post the iterator now points to first keypair in the section
       
   339 */
       
   340 EXPORT_C void CIniSecIter16::Reset()
       
   341 {
       
   342 	iImpl->Reset();
       
   343 }
       
   344 
       
   345 /**
       
   346 Destructor
       
   347 */
       
   348 EXPORT_C CIniSecIter16::~CIniSecIter16()
       
   349 {
       
   350 	delete iImpl;
       
   351 }
       
   352 
       
   353 //Default constructor
       
   354 CIniSecIter16::CIniSecIter16()
       
   355 {
       
   356 }
       
   357 
       
   358 //
       
   359 
       
   360 /** 
       
   361 Opening 16 bit ini file for reading.If the supplied file name is a valid
       
   362 ini file, it will instantiate the object and read the content of 
       
   363 the ini file.If file not found it will simply instantiate the object.
       
   364 The file is opened for read only and close directly after the construction
       
   365 of this object is complete.
       
   366 User will need to explicitly call Externalise(aFileName) to write the content back to ini file.
       
   367 @param aFs the handle to the file session
       
   368 @param aFileName the ini file name to read from
       
   369 @return A pointer to a newly created CIniDocument16 object
       
   370 */
       
   371 EXPORT_C CIniDocument16* CIniDocument16::NewL(RFs& aFs,const TDesC& aFileName)
       
   372 	{
       
   373 	CIniDocument16* self=new (ELeave)CIniDocument16();
       
   374 	CleanupStack::PushL(self);
       
   375 	self->iImpl=CIniDocument16Impl::NewL(aFs,aFileName);
       
   376 	CleanupStack::Pop();
       
   377 	return self;	
       
   378 	}
       
   379 
       
   380 /**
       
   381 Flush the buffered content to an output file name
       
   382 This will first write into a temporary file in the same directory and path
       
   383 as the supplied aFileName.It will then replace the existing file or 
       
   384 create a new file if does not exist yet.
       
   385 @param aFileName the output file name to write to
       
   386 @return KErrNone if no error
       
   387 		Other System Wide errors
       
   388 */
       
   389 EXPORT_C TInt CIniDocument16::Externalise(const TDesC& aFileName)
       
   390 {
       
   391 	TRAPD(r,iImpl->FlushL(aFileName));
       
   392 	return r;
       
   393 }
       
   394 	
       
   395 /** 
       
   396 Get an array of the section name present in the ini document object
       
   397 Note that any items inside this array will be cleared and the array will
       
   398 be populated with the sections' names from this document object.
       
   399 @param aSectionList an array of descriptor to contain the section name
       
   400 @return KErrNone if successful, otherwise another of the system-wide error codes
       
   401 @post aSectionList contains all the section name in the document object
       
   402 */
       
   403 EXPORT_C TInt CIniDocument16::GetSectionList(RArray<TPtrC16>& aSectionList) const
       
   404 	{
       
   405 	return iImpl->GetSectionList(aSectionList);
       
   406 	}
       
   407 
       
   408 /**
       
   409 Get the value of a key within a section
       
   410 @param aSectionName the section where the key resides
       
   411 @param aKey the key name
       
   412 @param aValue pointer to the key value
       
   413 @return
       
   414 	KErrNotFound if either section or keyname not found
       
   415 	KErrNone if successful
       
   416 @post aKeyValue now points to the key value
       
   417 */
       
   418 EXPORT_C TInt CIniDocument16::GetKeyValue(const TDesC16& aSectionName,const TDesC16& aKey,TPtrC16& aValue) const
       
   419 	{
       
   420 	TRAPD(ret,iImpl->GetKeyValueL(aSectionName,aKey,aValue));
       
   421 	return ret;
       
   422 	}
       
   423 
       
   424 /**
       
   425 Add a section to the ini document object
       
   426 @param aSectionName the name of the section to be added
       
   427 @return
       
   428 	KErrNone if successful
       
   429 	KErrAlreadyExists if the section with that name already exists
       
   430 	Any other system wide error code
       
   431 @post a section with that name is created and added to the document object
       
   432 */
       
   433 EXPORT_C TInt CIniDocument16::AddSection(const TDesC16& aSectionName)
       
   434 	{
       
   435 	TRAPD(ret,iImpl->AddSectionL(aSectionName));
       
   436 	return ret;	
       
   437 	}
       
   438 
       
   439 /**
       
   440 Remove an existing section from the ini document object
       
   441 @param aSectionName the name of the section to be removed
       
   442 @return KErrNone if successful
       
   443 	    KErrNotFound if section does not exist
       
   444 	    Any other system wide error code
       
   445 @post if exist that section is removed from the document object	
       
   446 */	
       
   447 EXPORT_C TInt CIniDocument16::RemoveSection(const TDesC16& aSectionName)
       
   448 	{
       
   449 	TRAPD(ret,iImpl->RemoveSectionL(aSectionName));
       
   450 	return ret;
       
   451 	}
       
   452 
       
   453 /**
       
   454 Set the value of a key within a section.
       
   455 This API offers the following flexibility:
       
   456 -If section does not exist,create a section and key and value
       
   457 -If section exists but key does not exist, create the key and value
       
   458 -Else replace the existing key value with the new value
       
   459 @param aSectionName the name of the section
       
   460 @param aKey the name of the key
       
   461 @param aValue the new value for this key
       
   462 @return
       
   463 	KErrNone if successful,any other system wide error code
       
   464 */
       
   465 EXPORT_C TInt CIniDocument16::SetKey(const TDesC16& aSectionName,const TDesC16& aKey,const TDesC16& aValue)
       
   466 	{
       
   467 	TRAPD(ret,iImpl->SetKeyL(aSectionName,aKey,aValue));	
       
   468 	return ret;
       
   469 	}
       
   470 
       
   471 /**
       
   472 Remove an existing key within a section
       
   473 if supplied section or key name does not exist, it does nothing
       
   474 @param aSectionName the name of the section where the key resides
       
   475 @param aKey the name of the key to be removed
       
   476 @post if exist that key is removed from the section
       
   477 */
       
   478 EXPORT_C TInt CIniDocument16::RemoveKey(const TDesC16& aSectionName,const TDesC16& aKey)
       
   479 	{
       
   480 	TRAPD(ret,iImpl->RemoveKeyL(aSectionName,aKey));
       
   481 	return ret;	
       
   482 	}
       
   483 /**
       
   484 Compare two document objects. If names, keys or values differ, a false is returned,
       
   485 else a true is returned.
       
   486 @param aDoc name of the document to compare against this object.
       
   487 */
       
   488 EXPORT_C TBool CIniDocument16::CompareDocs(CIniDocument16& aDoc)	
       
   489 	{
       
   490 	return (iImpl->CompareDocs( *(aDoc.iImpl) ));
       
   491 	}	
       
   492 /**
       
   493 Destructor
       
   494 */	
       
   495 EXPORT_C CIniDocument16::~CIniDocument16()
       
   496 	{
       
   497 	delete iImpl;
       
   498 	}
       
   499 
       
   500 CIniDocument16::CIniDocument16(){}
       
   501 
       
   502 //
       
   503 /**
       
   504 Creates a 16 bit light weight parser
       
   505 @param aFs the handle to the file session
       
   506 @param aFileName the ini file name to open
       
   507 @return A pointer to a newly created CIniFile16 object
       
   508 @leave	KErrNoMemory if not enough memory
       
   509 		KErrNotFound if the supplied file does not exist
       
   510 */
       
   511 EXPORT_C CIniFile16* CIniFile16::NewL(RFs& aFs,const TDesC& aFileName)
       
   512 	{
       
   513 	return CIniFile16::NewL(aFs,aFileName,EFalse);
       
   514 	}
       
   515 
       
   516 /**
       
   517 Creates a 16 bit light weight parser
       
   518 @param aFs the handle to the file session
       
   519 @param aFileName the ini file name to open
       
   520 @param aConvert8To16 upconvert 8 bit files otherwise leave with KErrCorrupt
       
   521 @return A pointer to a newly created CIniFile16 object
       
   522 @leave	KErrNoMemory if not enough memory
       
   523 		KErrNotFound if the supplied file does not exist
       
   524 */
       
   525 EXPORT_C CIniFile16* CIniFile16::NewL(RFs& aFs,const TDesC& aFileName,TBool aConvert8To16)
       
   526 	{
       
   527 	CIniFile16* self=new (ELeave)CIniFile16;
       
   528 	CleanupStack::PushL(self);
       
   529 	self->iImpl=CIniFile16Impl::NewL(aFs,aFileName,aConvert8To16);
       
   530 	CleanupStack::Pop();
       
   531 	return self;
       
   532 	}
       
   533 
       
   534 /**
       
   535 Public Destructor
       
   536 */	
       
   537 EXPORT_C CIniFile16::~CIniFile16()
       
   538 	{
       
   539 	delete iImpl;	
       
   540 	}
       
   541 
       
   542 /**
       
   543 Get the value of a key within a section
       
   544 @param aSectionName the section where the key resides
       
   545 @param aKeyName the key name
       
   546 @param aValue pointer to the key value
       
   547 @return
       
   548 	KErrNotFound if either section or keyname not found
       
   549 	KErrNone if successful
       
   550 */		
       
   551 EXPORT_C TInt CIniFile16::FindVar(const TDesC16& aSectionName,const TDesC16& aKeyName,TPtrC16& aValue)const
       
   552 	{
       
   553 	return iImpl->FindVar(aSectionName,aKeyName,aValue);
       
   554 	}
       
   555 	
       
   556 CIniFile16::CIniFile16(){}
       
   557 
       
   558 //
       
   559 
       
   560 CIniDocument8Impl* CIniDocument8Impl::NewL(RFs& aFs,const TDesC& aFileName)
       
   561 {
       
   562 	CIniDocument8Impl* self= new (ELeave) CIniDocument8Impl();
       
   563 	CleanupStack::PushL(self);
       
   564 	self->ConstructL(aFs,aFileName);
       
   565 	CleanupStack::Pop();
       
   566 	return self;
       
   567 }
       
   568 
       
   569 // This method will panic if, when reading the input configuration file, a key
       
   570 // is attempted to be processed without a valid section name being already defined.
       
   571 void CIniDocument8Impl::ConstructL(RFs& aFs,const TDesC& aFileName)
       
   572 {
       
   573 	TInt    filesize=0;
       
   574 	TInt    startOfLine=0;
       
   575 	CIniSection8* section = NULL;
       
   576 	HBufC8* fileBuffer=NULL;
       
   577 	iTempImpl=new (ELeave)CIniDocumentTmpl8(aFs,ETrue);
       
   578 	
       
   579 	TRAPD(ret,GetBufferL(aFs,aFileName,fileBuffer));
       
   580 	//if the file is not found, assume we are creating a new file.
       
   581 	if (ret==KErrNotFound)
       
   582 		{
       
   583 		return;
       
   584 		}
       
   585 	User::LeaveIfError(ret);
       
   586 	if (!fileBuffer)
       
   587 		{	
       
   588 		return;	
       
   589 		}	
       
   590 	CleanupStack::PushL(fileBuffer);
       
   591 	filesize = fileBuffer->Length();
       
   592 	TPtrC8 bufferDescriptor = fileBuffer->Des();
       
   593 	while (startOfLine < filesize)
       
   594 		{
       
   595 		TPtrC8 myBuffer = ExtractLineFromBuffer<HBufC8, TPtrC8>(bufferDescriptor, startOfLine);
       
   596 		CIniLine8* line = CIniLine8::NewLC(myBuffer);
       
   597 		startOfLine += (line->LineBuffer()).Length();
       
   598 		
       
   599 		switch(line->LineType())
       
   600 			{
       
   601 			case ESection:
       
   602 			 	section = CIniSection8::NewLC(line);
       
   603 			 	iTempImpl->AddSectionL(section);
       
   604 			 	CleanupStack::Pop(section);
       
   605 			 	break;
       
   606 			 	
       
   607 			case EKeyValue:
       
   608 				{
       
   609 				CIniKey8* key = CIniKey8::NewLC(line);
       
   610 				if (section == NULL)
       
   611 					{
       
   612 					User::Leave(KErrCorrupt);	//Unnamed sections within the file are not allowed but not preventable, hence leave if found. 
       
   613 					}
       
   614 			 	section->InsertKeyL(key);
       
   615 			 	CleanupStack::Pop(key);
       
   616 			 	break;
       
   617 				}
       
   618 				
       
   619 			case EComment:
       
   620 				break;
       
   621 				
       
   622 			default:
       
   623 				User::Panic(_L("Invalid LineType"), KErrCorrupt);	// programming error.
       
   624 			}
       
   625 		iTempImpl->AppendIntoQueue(line);
       
   626 		CleanupStack::Pop(line);
       
   627 		}
       
   628 	CleanupStack::PopAndDestroy(fileBuffer);
       
   629 }
       
   630 
       
   631 void CIniDocument8Impl::FlushL(const TDesC& aFileName)
       
   632 {
       
   633 	iTempImpl->FlushL(aFileName);
       
   634 }
       
   635 
       
   636 TInt CIniDocument8Impl::GetSectionList(RArray<TPtrC8>& aSectionList) const
       
   637 {
       
   638 	return iTempImpl->GetSectionList(aSectionList);
       
   639 }
       
   640 
       
   641 void CIniDocument8Impl::GetKeyValueL(const TDesC8& aSectionName,const TDesC8& aKeyName,TPtrC8& aKeyValue) const
       
   642 {
       
   643 	iTempImpl->GetKeyValueL(aSectionName,aKeyName,aKeyValue);
       
   644 }
       
   645 
       
   646 void CIniDocument8Impl::AddSectionL(const TDesC8& aSectionName)
       
   647 {
       
   648 	iTempImpl->AddSectionL(aSectionName);
       
   649 }
       
   650 
       
   651 void CIniDocument8Impl::RemoveSectionL(const TDesC8& aSectionName)
       
   652 {
       
   653 	iTempImpl->RemoveSectionL(aSectionName);
       
   654 }
       
   655 
       
   656 void CIniDocument8Impl::SetKeyL(const TDesC8& aSectionName,const TDesC8& aKeyName,const TDesC8& aKeyValue)
       
   657 {
       
   658 	iTempImpl->SetKeyL(aSectionName,aKeyName,aKeyValue);
       
   659 }
       
   660 
       
   661 void CIniDocument8Impl::RemoveKeyL(const TDesC8& aSectionName,const TDesC8& aKeyName)
       
   662 {
       
   663 	iTempImpl->RemoveKeyL(aSectionName,aKeyName);
       
   664 }
       
   665 
       
   666 CIniDocument8Impl::~CIniDocument8Impl()
       
   667 {
       
   668 	delete iTempImpl;
       
   669 }
       
   670 
       
   671 CIniSection8* CIniDocument8Impl::SectionL(const TDesC8& aSectionName) const
       
   672 {
       
   673 	return iTempImpl->SectionL(aSectionName);
       
   674 }
       
   675 
       
   676 TBool CIniDocument8Impl::CompareDocs(CIniDocument8Impl& aDocImpl) 
       
   677 {
       
   678 	return(iTempImpl->CompareDocs(*aDocImpl.iTempImpl));
       
   679 }
       
   680 
       
   681 //
       
   682 CIniDocument16Impl* CIniDocument16Impl::NewL(RFs& aFs,const TDesC& aFileName)
       
   683 {
       
   684 	CIniDocument16Impl* self= new (ELeave) CIniDocument16Impl();
       
   685 	CleanupStack::PushL(self);
       
   686 	self->ConstructL(aFs,aFileName);
       
   687 	CleanupStack::Pop();
       
   688 	return self;
       
   689 }
       
   690 
       
   691 void CIniDocument16Impl::ConstructL(RFs& aFs,const TDesC& aFileName)
       
   692 {
       
   693 	TInt    filesize=0;
       
   694 	TInt    startOfLine=0;
       
   695 	CIniSection16* section = NULL;
       
   696 	HBufC8* fileBuffer=NULL;
       
   697 	iTempImpl=new (ELeave)CIniDocumentTmpl16(aFs,EFalse);
       
   698 	
       
   699 	TRAPD(ret,GetBufferL(aFs,aFileName,fileBuffer));
       
   700 	//if the file is not found, assume we are creating a new file.
       
   701 	if (ret==KErrNotFound)
       
   702 		{
       
   703 		return;
       
   704 		}
       
   705 	User::LeaveIfError(ret);
       
   706 	if (!fileBuffer)
       
   707 		{	
       
   708 		return;	
       
   709 		}	
       
   710 	CleanupStack::PushL(fileBuffer);
       
   711 	filesize = fileBuffer->Length()/2;
       
   712 	
       
   713 	// process the filemark at the start of the file.
       
   714 	const TUint16* rawptr16=reinterpret_cast<const TUint16*>(fileBuffer->Ptr());
       
   715 	TPtrC16 bufferPtr;
       
   716 	
       
   717 	//must always start with the byte ordering characters
       
   718 	bufferPtr.Set(rawptr16,1);
       
   719 	if (bufferPtr.Compare(_L("\xFEFF"))!=0)
       
   720 		User::Leave(KErrCorrupt);
       
   721 	//skip the byte ordering character(FEFF) assuming little endian
       
   722 	bufferPtr.Set(rawptr16+1,(filesize - 1));	
       
   723 	
       
   724 	while (startOfLine < (filesize-1))
       
   725 		{
       
   726 		TPtrC16 myBuffer = ExtractLineFromBuffer<HBufC16, TPtrC16>(bufferPtr, startOfLine);
       
   727 		CIniLine16* line = CIniLine16::NewLC(myBuffer);
       
   728 		startOfLine += (line->LineBuffer()).Length();
       
   729 		
       
   730 		TLineType lineType = line->LineType();
       
   731 		switch (lineType)
       
   732 			{
       
   733 			case ESection:
       
   734 				section = CIniSection16::NewLC(line);
       
   735 				iTempImpl->AddSectionL(section);
       
   736 			 	CleanupStack::Pop(section);
       
   737 			 	break;
       
   738 			 	
       
   739 			case EKeyValue:
       
   740 				{
       
   741 				CIniKey16* key = CIniKey16::NewLC(line);
       
   742 				
       
   743 				if (section == NULL)
       
   744 					{
       
   745 					User::Leave(KErrCorrupt);	//Unnamed sections are not allowed hence leave if found.
       
   746 					}
       
   747 				section->InsertKeyL(key);
       
   748 				CleanupStack::Pop(key);
       
   749 			 	break;
       
   750 				}
       
   751 				
       
   752 			case EComment:
       
   753 				break;
       
   754 				
       
   755 			default:
       
   756 				User::Panic(_L("Invalid LineType"), KErrCorrupt);
       
   757 			}
       
   758 		iTempImpl->AppendIntoQueue(line);
       
   759 		CleanupStack::Pop(line);
       
   760 	}	
       
   761 	CleanupStack::PopAndDestroy(fileBuffer);
       
   762 }
       
   763 
       
   764 void CIniDocument16Impl::FlushL(const TDesC& aFileName)
       
   765 {
       
   766 	iTempImpl->FlushL(aFileName);
       
   767 }
       
   768 
       
   769 TInt CIniDocument16Impl::GetSectionList(RArray<TPtrC16>& aSectionList) const
       
   770 {
       
   771 	return iTempImpl->GetSectionList(aSectionList);
       
   772 }
       
   773 
       
   774 void CIniDocument16Impl::GetKeyValueL(const TDesC16& aSectionName,const TDesC16& aKeyName,TPtrC16& aKeyValue) const
       
   775 {
       
   776 	iTempImpl->GetKeyValueL(aSectionName,aKeyName,aKeyValue);
       
   777 }
       
   778 
       
   779 void CIniDocument16Impl::AddSectionL(const TDesC16& aSectionName)
       
   780 {
       
   781 	iTempImpl->AddSectionL(aSectionName);
       
   782 }
       
   783 
       
   784 void CIniDocument16Impl::RemoveSectionL(const TDesC16& aSectionName)
       
   785 {
       
   786 	iTempImpl->RemoveSectionL(aSectionName);
       
   787 }
       
   788 
       
   789 void CIniDocument16Impl::SetKeyL(const TDesC16& aSectionName,const TDesC16& aKeyName,const TDesC16& aKeyValue)
       
   790 {
       
   791 	iTempImpl->SetKeyL(aSectionName,aKeyName,aKeyValue);
       
   792 }
       
   793 
       
   794 void CIniDocument16Impl::RemoveKeyL(const TDesC16& aSectionName,const TDesC16& aKeyName)
       
   795 {
       
   796 	iTempImpl->RemoveKeyL(aSectionName,aKeyName);
       
   797 }
       
   798 
       
   799 CIniDocument16Impl::~CIniDocument16Impl()
       
   800 	{
       
   801 	delete iTempImpl;
       
   802 	}
       
   803 
       
   804 CIniSection16* CIniDocument16Impl::SectionL(const TDesC16& aSectionName) const
       
   805 {
       
   806 	return iTempImpl->SectionL(aSectionName);
       
   807 }
       
   808 
       
   809 TBool CIniDocument16Impl::CompareDocs(CIniDocument16Impl& aDocImpl) 
       
   810 {
       
   811 	return(iTempImpl->CompareDocs(*(aDocImpl.iTempImpl)));
       
   812 }
       
   813 
       
   814 //	
       
   815 
       
   816 CIniSecIter8Impl* CIniSecIter8Impl::NewL(const TDesC8& aSectionName,const CIniDocument8* aIniDocument) 
       
   817 	{
       
   818 	CIniSecIter8Impl* self=new (ELeave)CIniSecIter8Impl();
       
   819 	CleanupStack::PushL(self);
       
   820 	self->ConstructL(aSectionName,aIniDocument);
       
   821 	CleanupStack::Pop();
       
   822 	return self;
       
   823 	}
       
   824 
       
   825 void CIniSecIter8Impl::ConstructL(const TDesC8& aSectionName,const CIniDocument8* aIniDocument)
       
   826 	{
       
   827 	iTempImpl=new (ELeave)CIniSecIterTmpl8();
       
   828 	if (!aIniDocument)
       
   829 		User::Leave(KErrArgument);
       
   830 	iTempImpl->iSection=aIniDocument->iImpl->SectionL(aSectionName);
       
   831 	}
       
   832 	
       
   833 TBool CIniSecIter8Impl::Next(TPtrC8& aKeyName,TPtrC8& aKeyValue)	
       
   834 	{
       
   835 	return iTempImpl->Next(aKeyName,aKeyValue);
       
   836 	}
       
   837 	
       
   838 void CIniSecIter8Impl::Reset()
       
   839 	{
       
   840 	iTempImpl->Reset();	
       
   841 	}
       
   842 
       
   843 //
       
   844 CIniSecIter16Impl* CIniSecIter16Impl::NewL(const TDesC16& aSectionName,const CIniDocument16* aIniDocument) 
       
   845 	{
       
   846 	CIniSecIter16Impl* self=new (ELeave)CIniSecIter16Impl();
       
   847 	CleanupStack::PushL(self);
       
   848 	self->ConstructL(aSectionName,aIniDocument);
       
   849 	CleanupStack::Pop();
       
   850 	return self;
       
   851 	}
       
   852 
       
   853 void CIniSecIter16Impl::ConstructL(const TDesC16& aSectionName,const CIniDocument16* aIniDocument)
       
   854 	{
       
   855 	iTempImpl=new (ELeave)CIniSecIterTmpl16();
       
   856 	if (!aIniDocument)
       
   857 		User::Leave(KErrArgument);	
       
   858 	iTempImpl->iSection=aIniDocument->iImpl->SectionL(aSectionName);
       
   859 	}
       
   860 	
       
   861 TBool CIniSecIter16Impl::Next(TPtrC16& aKeyName,TPtrC16& aKeyValue)	
       
   862 	{
       
   863 	return iTempImpl->Next(aKeyName,aKeyValue);
       
   864 	}
       
   865 	
       
   866 void CIniSecIter16Impl::Reset()
       
   867 	{
       
   868 	iTempImpl->Reset();
       
   869 	}
       
   870 
       
   871 //
       
   872 CIniFile8Impl* CIniFile8Impl::NewL(RFs& aFs,const TDesC& aFileName)
       
   873 	{
       
   874 	CIniFile8Impl* self=new (ELeave)CIniFile8Impl;
       
   875 	CleanupStack::PushL(self);
       
   876 	self->ConstructL(aFs,aFileName);
       
   877 	CleanupStack::Pop();
       
   878 	return self;
       
   879 	}
       
   880 
       
   881 void CIniFile8Impl::ConstructL(RFs& aFs,const TDesC& aFileName)
       
   882 	{
       
   883 	iTempImpl=new (ELeave)CIniFileTmpl8();
       
   884 	HBufC8* tempBuffer=NULL;
       
   885 	//read the file
       
   886 	GetBufferL(aFs,aFileName,tempBuffer);
       
   887 	if (tempBuffer)
       
   888 		{
       
   889 		CleanupStack::PushL(tempBuffer);
       
   890 		iTempImpl->ProcessBufferL(*tempBuffer);
       
   891 		CleanupStack::Pop();
       
   892 		delete tempBuffer;
       
   893 		}
       
   894 	}
       
   895 
       
   896 TInt CIniFile8Impl::FindVar(const TDesC8& aSection,const TDesC8& aKey,TPtrC8& aValue)
       
   897 	{
       
   898 	return iTempImpl->FindVar(aSection,aKey,aValue);	
       
   899 	}
       
   900 
       
   901 //
       
   902 CIniFile16Impl* CIniFile16Impl::NewL(RFs& aFs,const TDesC& aFileName,TBool aConvert8To16)
       
   903 	{
       
   904 	CIniFile16Impl* self=new (ELeave)CIniFile16Impl;
       
   905 	CleanupStack::PushL(self);
       
   906 	self->ConstructL(aFs,aFileName,aConvert8To16);
       
   907 	CleanupStack::Pop();
       
   908 	return self;
       
   909 	}
       
   910 
       
   911 void CIniFile16Impl::ConstructL(RFs& aFs,const TDesC& aFileName,TBool aConvert8To16)
       
   912 	{
       
   913 	iTempImpl=new (ELeave)CIniFileTmpl16();
       
   914 	HBufC8* tempBuffer=NULL;
       
   915 	//read the file
       
   916 	GetBufferL(aFs,aFileName,tempBuffer);
       
   917 	if (tempBuffer)
       
   918 		{
       
   919 		CleanupStack::PushL(tempBuffer);
       
   920 		TPtrC16 bufferPtr;
       
   921 		const TUint16* rawptr16=reinterpret_cast<const TUint16*>(tempBuffer->Ptr());
       
   922 		//must always start with the byte ordering characters
       
   923 		bufferPtr.Set(rawptr16,1);
       
   924 		if (bufferPtr.Compare(_L("\xFEFF"))==0)
       
   925 			{
       
   926 			//skip the byte ordering character(FEFF) assuming little endian
       
   927 			bufferPtr.Set(rawptr16+1,(tempBuffer->Length()/2)-1);
       
   928 			}
       
   929 		else
       
   930 			{
       
   931 			//byte ordering characters not found, so leave, unless we should upconvert
       
   932 			if (!aConvert8To16)
       
   933 				{			
       
   934 				User::Leave(KErrCorrupt);
       
   935 				}
       
   936 			//treat as an 8-bit file and upconvert to 16
       
   937 			HBufC16* tempBuffer16=HBufC16::NewL(tempBuffer->Length());
       
   938 			tempBuffer16->Des().Copy(*tempBuffer);
       
   939 			CleanupStack::PopAndDestroy(tempBuffer);
       
   940 			CleanupStack::PushL(tempBuffer16);	
       
   941 			bufferPtr.Set(*tempBuffer16);
       
   942 			}	
       
   943 		iTempImpl->ProcessBufferL(bufferPtr);
       
   944 		CleanupStack::PopAndDestroy();
       
   945 		}
       
   946 	}
       
   947 
       
   948 TInt CIniFile16Impl::FindVar(const TDesC16& aSection,const TDesC16& aKey,TPtrC16& aValue)
       
   949 	{
       
   950 	return iTempImpl->FindVar(aSection,aKey,aValue);	
       
   951 	}
       
   952 	
       
   953 }//namespace
       
   954 
       
   955