stif/Parser/src/StifFileParser.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 0 a03f92240627
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description: This module contains implementation of CStifParser 
       
    15 * class member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include "StifFileParser.h"
       
    22 #include "StifTestInterface.h"
       
    23 #include "ParserTracing.h"
       
    24 
       
    25 // EXTERNAL DATA STRUCTURES
       
    26 // None
       
    27 
       
    28 // EXTERNAL FUNCTION PROTOTYPES
       
    29 // None
       
    30 
       
    31 // CONSTANTS
       
    32 // None
       
    33 
       
    34 // MACROS
       
    35 // None
       
    36 
       
    37 // LOCAL CONSTANTS AND MACROS
       
    38 // None
       
    39 
       
    40 // MODULE DATA STRUCTURES
       
    41 // None
       
    42 
       
    43 // LOCAL FUNCTION PROTOTYPES
       
    44 // None
       
    45 
       
    46 // FORWARD DECLARATIONS
       
    47 // None
       
    48 
       
    49 // ==================== LOCAL FUNCTIONS =======================================
       
    50 // None
       
    51 
       
    52 // ================= MEMBER FUNCTIONS =========================================
       
    53 
       
    54 /*
       
    55 -------------------------------------------------------------------------------
       
    56 
       
    57     Class: CStifFileParser
       
    58 
       
    59     Method: CStifFileParser
       
    60 
       
    61     Description: Default constructor
       
    62 
       
    63     C++ default constructor can NOT contain any code, that
       
    64     might leave.
       
    65 
       
    66     Parameters: TCommentType aCommentType: in: Comment type's indication
       
    67 
       
    68     Return Values: None
       
    69 
       
    70     Errors/Exceptions: None
       
    71 
       
    72     Status: Approved
       
    73 
       
    74 -------------------------------------------------------------------------------
       
    75 */
       
    76 CStifFileParser::CStifFileParser(CStifParser::TCommentType aCommentType)
       
    77 	{
       
    78     iCommentType = aCommentType;
       
    79 	}
       
    80 
       
    81 /*
       
    82 -------------------------------------------------------------------------------
       
    83 
       
    84     Class: CStifFileParser
       
    85 
       
    86     Method: ConstructL
       
    87 
       
    88     Description: Symbian OS second phase constructor
       
    89 
       
    90     Symbian OS default constructor can leave.
       
    91 
       
    92     Sets variables.
       
    93 
       
    94     Parameters: RFs& aFs:        in: Handle to valid file server
       
    95                 RFile& aFile:    in: Handle to the source file
       
    96                 TBool aIsUnicode in: Is file in unicode format
       
    97 
       
    98     Return Values: None
       
    99 
       
   100     Errors/Exceptions:  None
       
   101 
       
   102     Status: Proposal
       
   103 
       
   104 -------------------------------------------------------------------------------
       
   105 */
       
   106 void CStifFileParser::ConstructL(RFs& aFs,
       
   107                                  RFile& aFile,
       
   108                                  TBool aIsUnicode)
       
   109 	{
       
   110 	//Initialization
       
   111 	iFileServer = aFs;
       
   112 	iBaseFile = aFile;
       
   113 	iCurrentFile = &aFile;
       
   114 	iIsUnicode = aIsUnicode;
       
   115 	iBytesPerChar = iIsUnicode ? 2 : 1;
       
   116 
       
   117 	//Create file stack (INCLUDE feature)
       
   118 	iFileStack = new (ELeave) CStackDeprecated<RFile, EFalse>;
       
   119 
       
   120 	//Add base file to file names array
       
   121 	TFileName fn;
       
   122 	iCurrentFile->FullName(fn);
       
   123 	HBufC* newFile = fn.AllocLC();
       
   124 	User::LeaveIfError(iFileNames.Append(newFile));
       
   125 	CleanupStack::Pop(newFile);
       
   126 	}
       
   127 
       
   128 /*
       
   129 -------------------------------------------------------------------------------
       
   130 
       
   131     Class: CStifFileParser
       
   132 
       
   133     Method: NewL
       
   134 
       
   135     Description: Two-phased constructor.
       
   136 
       
   137     Starting creating parser with path and file information.
       
   138 
       
   139     Parameters: RFs& aFs:                  in: Handle to file server
       
   140                 RFile& aFile:              in: Source path definition
       
   141                 TBool aIsUnicode           in: Is file in unicode format
       
   142                 TCommentType aCommentType: in: Comment type's indication
       
   143 
       
   144     Return Values: CStifFileParser* : pointer to CStifFileParser object
       
   145 
       
   146     Errors/Exceptions: Leaves if ConstructL leaves
       
   147 
       
   148     Status: Proposal
       
   149 
       
   150 -------------------------------------------------------------------------------
       
   151 */
       
   152 CStifFileParser* CStifFileParser::NewL(RFs& aFs,
       
   153                                        RFile& aFile,
       
   154                                        TBool aIsUnicode,
       
   155                                        CStifParser::TCommentType aCommentType)
       
   156 	{
       
   157     // Create CStifParser object
       
   158     CStifFileParser* parser = new (ELeave) CStifFileParser(aCommentType);
       
   159 
       
   160     CleanupStack::PushL(parser);
       
   161     parser->ConstructL(aFs, aFile, aIsUnicode);
       
   162     CleanupStack::Pop(parser);
       
   163 
       
   164     return parser;
       
   165 	}
       
   166 
       
   167 /*
       
   168 -------------------------------------------------------------------------------
       
   169 
       
   170     Class: CStifFileParser
       
   171 
       
   172     Method: ~CStifFileParser
       
   173 
       
   174     Description: Destructor
       
   175 
       
   176     Parameters: None
       
   177 
       
   178     Return Values: None
       
   179 
       
   180     Errors/Exceptions: None
       
   181 
       
   182     Status: Proposal
       
   183 
       
   184 -------------------------------------------------------------------------------
       
   185 */
       
   186 CStifFileParser::~CStifFileParser()
       
   187 	{
       
   188 	//Close file stack
       
   189 	ClearFileStack();
       
   190 	delete iFileStack;
       
   191 
       
   192 	//Close section lines array
       
   193 	ClearSectionLinesArray();
       
   194 	iSectionLines.Close();
       
   195 	
       
   196 	//Close fila names array
       
   197 	while(iFileNames.Count() > 0)
       
   198 		{
       
   199 		delete iFileNames[0];
       
   200 		iFileNames.Remove(0);
       
   201 		}
       
   202 	iFileNames.Close();
       
   203 	}
       
   204 
       
   205 /*
       
   206 -------------------------------------------------------------------------------
       
   207 
       
   208     Class: CStifFileParser
       
   209 
       
   210     Method: ReadLineL
       
   211 
       
   212     Description: Reads line from source file
       
   213 
       
   214     Parameters: TPtr& aLineBuffer:      in: Descriptor in which line loads
       
   215                 TPtr& aEndOfLineBuffer: in: Descriptor in which end of line sequence is loaded (0x0A or 0x0D 0x0A)
       
   216 
       
   217     Return Values: TBool: determines whether line was readed or not
       
   218 
       
   219     Errors/Exceptions:  Leaves if seek command leaves
       
   220     					Leaves if buffer is too small
       
   221 
       
   222     Status: Proposal
       
   223 
       
   224 -------------------------------------------------------------------------------
       
   225 */
       
   226 TBool CStifFileParser::ReadLineL(TPtr& aLineBuffer,
       
   227                                  TPtr& aEndOfLineBuffer)
       
   228 	{
       
   229 	//Variables
       
   230 	TBuf8<128> buf8;
       
   231 	TBuf16<128> buf16;
       
   232 	TPtrC16 buf;
       
   233 	TInt pos;
       
   234 	TInt offset;
       
   235 	TChar char0x0A = 0x000A;
       
   236 	TChar char0x0D = 0x000D;
       
   237 
       
   238 	TBuf<1> b0x0A;
       
   239 	b0x0A.Append(char0x0A);
       
   240 
       
   241 	//Reset buffers
       
   242 	aLineBuffer.Zero();
       
   243 	aEndOfLineBuffer.Zero();
       
   244 
       
   245 	//Read from source
       
   246 	User::LeaveIfError(iCurrentFile->Read(buf8));
       
   247 	buf16.Copy(buf8);
       
   248 	if(iIsUnicode)
       
   249 		buf.Set((TUint16 *)(buf8.Ptr()), buf8.Length() / 2);
       
   250 	else
       
   251 		buf.Set(buf16.Ptr(), buf16.Length());
       
   252 
       
   253 	while(buf.Length())
       
   254 		{
       
   255 		//Search for end of line char
       
   256 		pos = buf.Find(b0x0A);
       
   257 
       
   258 		//If found, append readed data to output descriptor and move back file offset to correct position
       
   259 		if(pos >= 0)
       
   260 			{
       
   261 			offset = -((buf.Length() - pos - 1) * iBytesPerChar);
       
   262 			User::LeaveIfError(iCurrentFile->Seek(ESeekCurrent, offset));
       
   263 			buf.Set(buf.Ptr(), pos + 1);
       
   264 			aLineBuffer.Append(buf);
       
   265 			break;
       
   266 			}
       
   267 		//Otherwise, append whole buffer to output descriptor
       
   268 		else
       
   269 			{
       
   270 			aLineBuffer.Append(buf);
       
   271 			}
       
   272 		//Read next part of data
       
   273 		User::LeaveIfError(iCurrentFile->Read(buf8));
       
   274 		buf16.Copy(buf8);
       
   275 		if(iIsUnicode)
       
   276 			{
       
   277 			buf.Set((TUint16 *)(buf8.Ptr()), buf8.Length() / 2);
       
   278 			}
       
   279 		else
       
   280 			{
       
   281 			buf.Set(buf16.Ptr(), buf16.Length());
       
   282 			}
       
   283 		}
       
   284 
       
   285 	//Set correct end of line buffer
       
   286 	if(buf.Length() > 1)
       
   287 		{
       
   288 		if(buf[buf.Length() - 2] == char0x0D)
       
   289 			{
       
   290 			aEndOfLineBuffer.Append(char0x0D);
       
   291 			}
       
   292 		}
       
   293 	if(buf.Length() > 0)
       
   294 		{
       
   295 		if(buf[buf.Length() - 1] == char0x0A)
       
   296 			{
       
   297 			aEndOfLineBuffer.Append(char0x0A);
       
   298 			}
       
   299 		else
       
   300 			{
       
   301 			aEndOfLineBuffer.Zero();
       
   302 			}
       
   303 		}
       
   304 	if(aEndOfLineBuffer.Length())
       
   305 		{
       
   306 		aLineBuffer.SetLength(aLineBuffer.Length() - aEndOfLineBuffer.Length());
       
   307 		}
       
   308 
       
   309 	//If no data was found, try to get previous file from stack
       
   310 	if(aLineBuffer.Length() + aEndOfLineBuffer.Length() == 0)
       
   311 		{
       
   312 		//Pop file from stack. If stack is empty, then we achieved end of base file
       
   313 		if(!iFileStack->IsEmpty())
       
   314 			{
       
   315 			PopFromFileStack();
       
   316 			aEndOfLineBuffer.Copy(iEolBuf);
       
   317 			return aEndOfLineBuffer.Length();
       
   318 			}
       
   319 		}
       
   320 	//Check if this is include line
       
   321 	else
       
   322 		{
       
   323 		if(aLineBuffer.Find(KIncludeKeyword) == 0)
       
   324 			{
       
   325 			TFileName fn;
       
   326 			TLex lex(aLineBuffer);
       
   327 
       
   328 			fn.Copy(lex.NextToken()); //get INCLUDE keyword
       
   329 			fn.Copy(lex.NextToken()); //get cfg file name
       
   330 			if(fn.Length() > 0)
       
   331 				{
       
   332 				TStifUtil::CorrectFilePathL( fn );
       
   333 				PushFileToStackL(fn);
       
   334 				iEolBuf.Copy(aEndOfLineBuffer);
       
   335 				}
       
   336 			else
       
   337 				{
       
   338 				__TRACE(KError, (_L("No filename was given after INCLUDE. Ignoring")));
       
   339 				}
       
   340 
       
   341 			//Read next line
       
   342 			return ReadLineL(aLineBuffer, aEndOfLineBuffer);
       
   343 			}
       
   344 		}
       
   345 	
       
   346 	return aLineBuffer.Length() + aEndOfLineBuffer.Length();
       
   347 	}
       
   348 
       
   349 /*
       
   350 -------------------------------------------------------------------------------
       
   351 
       
   352     Class: CStifFileParser
       
   353 
       
   354     Method: ReplaceCommentsLineL
       
   355 
       
   356     Description: Replaces comments with spaces from line and copy it to destination buffer
       
   357 
       
   358     Parameters: TPtr& aSrcBufPtr:        in:  Source line with comments
       
   359                 TPtr& aDstBufPtr:       out:  Destination line without comments
       
   360                 TWhatToFind& aFind:  in out:  Determines what method currently is looking for
       
   361 
       
   362     Return Values: None
       
   363 
       
   364     Errors/Exceptions:  None
       
   365 
       
   366     Status: Proposal
       
   367 
       
   368 -------------------------------------------------------------------------------
       
   369 */
       
   370 void CStifFileParser::ReplaceCommentsLineL(TPtr& aSrcBufPtr,
       
   371                                            TPtr& aDstBufPtr,
       
   372 										   TWhatToFind& aFind)
       
   373 	{
       
   374 	//Variables
       
   375 	TLex lex(aSrcBufPtr);
       
   376 	TChar ch;
       
   377 	TChar chSpace(' ');
       
   378 	TChar chSlash('/');
       
   379 	TChar chQuota('\"');
       
   380 	TChar chMulti('*');
       
   381 	TChar chHash('#');
       
   382 
       
   383 	//Clean buffer
       
   384 	aDstBufPtr.Zero();
       
   385 
       
   386 	while(!lex.Eos())
       
   387 		{
       
   388 		ch = lex.Get();
       
   389 
       
   390 		//If the end of line, exit
       
   391 		if(!ch)
       
   392 			{
       
   393 			break;
       
   394 			}
       
   395 
       
   396 		//We're looking for start od quoted text or comment
       
   397 		if(aFind == EStart)
       
   398 			{
       
   399 			//Special character readed
       
   400 			if(ch == chQuota)
       
   401 				{
       
   402 				aFind = EQuota;
       
   403 				aDstBufPtr.Append(chSpace);
       
   404 				}
       
   405 			//Possible start of comment
       
   406 			else if(ch == chSlash)
       
   407 				{
       
   408 				//Comment to the end of line found
       
   409 				if(lex.Peek() == chSlash)
       
   410 					{
       
   411 					break;
       
   412 					}
       
   413 				//Beginning of a comment found
       
   414 				else if(lex.Peek() == chMulti)
       
   415 					{
       
   416 					aFind = EEndOfComment;
       
   417 					ch = lex.Get();
       
   418 					aDstBufPtr.Append(chSpace);
       
   419 					aDstBufPtr.Append(chSpace);
       
   420 					}
       
   421 				//No start of comment - add read slash
       
   422 				else
       
   423 					{
       
   424 					aDstBufPtr.Append(ch);
       
   425 					}
       
   426 				}
       
   427 			//Start of hash comment (to the end of line)
       
   428 			else if(ch == chHash)
       
   429 				{
       
   430 				break;
       
   431 				}
       
   432 			//Append readed character to the destination buffer
       
   433 			else
       
   434 				{
       
   435 				aDstBufPtr.Append(ch);
       
   436 				}
       
   437 			}
       
   438 		//We're looking for the end of quoted text
       
   439 		else if(aFind == EQuota)
       
   440 			{
       
   441 			if(ch == chQuota)
       
   442 				{
       
   443 				aFind = EStart;
       
   444 				aDstBufPtr.Append(chSpace);
       
   445 				}
       
   446 			else
       
   447 				{
       
   448 				aDstBufPtr.Append(chSpace);
       
   449 				}
       
   450 			}
       
   451 		//We're looking for the end of comment
       
   452 		else if(aFind == EEndOfComment)
       
   453 			{
       
   454 			//It may be the end of a comment
       
   455 			if(ch == chMulti)
       
   456 				{
       
   457 				ch = lex.Peek();
       
   458 				//It is the end of a comment
       
   459 				if(ch == chSlash)
       
   460 					{
       
   461 					aFind = EStart;
       
   462 					ch = lex.Get();
       
   463 					aDstBufPtr.Append(chSpace);
       
   464 					aDstBufPtr.Append(chSpace);
       
   465 					}
       
   466 				//It is not the end of a comment, add this character to the destinaton buffer
       
   467 				else
       
   468 					{
       
   469 					aDstBufPtr.Append(chSpace);
       
   470 					}
       
   471 				}
       
   472 			//It is not the end of a comment, add this character to the destinaton buffer
       
   473 			else
       
   474 				{
       
   475 				aDstBufPtr.Append(chSpace);
       
   476 				}
       
   477 			}
       
   478 		}
       
   479 	}
       
   480 
       
   481 /*
       
   482 -------------------------------------------------------------------------------
       
   483 
       
   484     Class: CStifFileParser
       
   485 
       
   486     Method: ReplaceHashCommentsLineL
       
   487 
       
   488     Description: Copy line to destination buffer and deletes #-style comments
       
   489 
       
   490     Parameters: TPtr& aSrcBufPtr:     in:  Source line with comments
       
   491                 TPtr& aDstBufPtr:    out: Destination line without comments
       
   492 
       
   493     Return Values: None
       
   494 
       
   495     Errors/Exceptions:  None
       
   496 
       
   497     Status: Proposal
       
   498 
       
   499 -------------------------------------------------------------------------------
       
   500 */
       
   501 void CStifFileParser::ReplaceHashCommentsLineL(TPtr& aSrcBufPtr,
       
   502                                                TPtr& aDstBufPtr)
       
   503 	{
       
   504 	//Variables
       
   505 	TLex lex(aSrcBufPtr);
       
   506 	TChar ch;
       
   507 	TChar chHash('#');
       
   508 
       
   509 	//Prepare destination buffer
       
   510 	aDstBufPtr.Zero();
       
   511 
       
   512 	//Copy source line to destination until # char is found
       
   513 	while(!lex.Eos())
       
   514 		{
       
   515 		ch = lex.Get();
       
   516 
       
   517 		//If the end of line, exit
       
   518 		if(!ch)
       
   519 			{
       
   520 			break;
       
   521 			}
       
   522 
       
   523 		if(ch == chHash)
       
   524 			{
       
   525 			break;
       
   526 			}
       
   527 		else
       
   528 			{
       
   529 			aDstBufPtr.Append(ch);
       
   530 			}
       
   531 		}
       
   532 	}
       
   533 
       
   534 /*
       
   535 -------------------------------------------------------------------------------
       
   536 
       
   537     Class: CStifFileParser
       
   538 
       
   539     Method: NextSectionL
       
   540 
       
   541     Description: Finds n-th (aSeeked) section in file starting from m-th (aOffset) position
       
   542 
       
   543     Parameters: const TDesc& aStartTag: in:     Starting tag of a section
       
   544                 const TDesc& aEndTag:   in:     Ending tag of a section
       
   545                 TInt& aOffset:          in out: Current offset in file (*)
       
   546                 TInt aSeeked:           in:     Which section is to be found
       
   547     
       
   548     Notification: aOffset has different meaning than before adding INCLUDE functionality.
       
   549                   If it has 0 value, that means that we need to remove files stack and go
       
   550                   back to base file to the beginning. Otherwise we don't change current
       
   551                   file read-handler position.
       
   552 
       
   553     Return Values: HBufC *: address of a descriptor containing section. Section is returned without tags.
       
   554                             Caller must take care about the freeing descriptor.
       
   555 
       
   556     Errors/Exceptions:  Leaves if aSeeked is less than 1 or aOffset is negative
       
   557     					Leaves if seek command leaves
       
   558     					Leaves if cannot allocate buffers
       
   559     					Leaves if cannot allocate section
       
   560     					Leaves if length of readed line exceeds KMaxLineLength constant
       
   561 
       
   562     Status: Proposal
       
   563 
       
   564 -------------------------------------------------------------------------------
       
   565 */
       
   566 HBufC* CStifFileParser::NextSectionL(const TDesC& aStartTag,
       
   567                                      const TDesC& aEndTag,
       
   568                                      TInt& aOffset,
       
   569                                      TInt aSeeked)
       
   570 	{
       
   571 	// Check arguments
       
   572 	if(aSeeked < 1)
       
   573 		{		
       
   574 		User::Leave(KErrArgument);
       
   575 		}
       
   576 	if(aOffset < 0)
       
   577 		{		
       
   578 		User::Leave(KErrArgument);
       
   579 		}
       
   580 
       
   581 	TInt foundSection = 0;
       
   582 	TInt ret;
       
   583 
       
   584 	// Alloc buffers to read line
       
   585 	const TInt KMaxLineLength = 4096; //If length of readed line exceeds this constant, method will leave
       
   586 
       
   587 	HBufC* buf = HBufC::NewL(KMaxLineLength);
       
   588 	CleanupStack::PushL(buf);
       
   589 	TPtr bufPtr(buf->Des());
       
   590 
       
   591 	HBufC* withoutCommentsBuf = HBufC::NewL(KMaxLineLength);
       
   592 	CleanupStack::PushL(withoutCommentsBuf);
       
   593 	TPtr withoutCommentsBufPtr(withoutCommentsBuf->Des());
       
   594 
       
   595 	HBufC* endOfLine = HBufC::NewL(2);  //After reading a line it contains 0D0A or 0A or null (how readed line is ended)
       
   596 	CleanupStack::PushL(endOfLine);
       
   597 	TPtr endOfLinePtr(endOfLine->Des());
       
   598 
       
   599 	//Set valid position in file
       
   600 	//but only if offset shows to 0. Otherwise keep previus position
       
   601 	if(aOffset == 0)
       
   602 		{
       
   603 		User::LeaveIfError(iBaseFile.Seek(ESeekStart, aOffset));
       
   604 		ClearFileStack();
       
   605 		aOffset = 1;
       
   606 		}
       
   607 
       
   608 	//Prepare to read lines
       
   609 	TBool validSectionBeginFound = EFalse;
       
   610 	TBool validSectionEndFound = EFalse;
       
   611 	TSectionFind whatToFindSection = ESectionStart;
       
   612 	//If no start tag is given start to find end tag immediatly
       
   613 	if(aStartTag.Length() == 0)
       
   614 		{
       
   615 		foundSection++;
       
   616 		whatToFindSection = ESectionEnd;
       
   617 		validSectionBeginFound = ETrue;
       
   618 		}
       
   619 	if(aEndTag.Length() == 0)
       
   620 		{
       
   621 		validSectionEndFound = ETrue;
       
   622 		}
       
   623 	TWhatToFind whatToFind = EStart;
       
   624 
       
   625 	//Perform reading file
       
   626 	while(ReadLineL(bufPtr, endOfLinePtr))
       
   627 		{
       
   628 		if(iCommentType == CStifParser::ECStyleComments)
       
   629 			{				
       
   630 			ReplaceCommentsLineL(bufPtr, withoutCommentsBufPtr, whatToFind);
       
   631 			}
       
   632 		else
       
   633 			{
       
   634 			ReplaceHashCommentsLineL(bufPtr, withoutCommentsBufPtr);
       
   635 			}
       
   636 			if(whatToFindSection == ESectionStart)
       
   637 			{
       
   638 			//Find in line star tag (if start tag is not given, behave like we've found it)
       
   639 			if(aStartTag.Length() == 0)
       
   640 				{
       
   641 				ret = 0;
       
   642 				}
       
   643 			else
       
   644 				{
       
   645 				ret = withoutCommentsBuf->Find(aStartTag);
       
   646 				}
       
   647 			//If found remember position, move offset of file to actual position
       
   648 			if(ret >= 0)
       
   649 				{
       
   650 				whatToFindSection = ESectionEnd;
       
   651 				TInt offset = -(bufPtr.Length() + endOfLinePtr.Length() - ret - aStartTag.Length()) * iBytesPerChar;
       
   652 				User::LeaveIfError(iCurrentFile->Seek(ESeekCurrent, offset));
       
   653 
       
   654 				whatToFind = EStart; //reset marker, because if we've found tag, we couldn't be in the middle of comment or quota
       
   655 				foundSection++;
       
   656 				//Add this line to section lines array
       
   657 				if(foundSection == aSeeked)
       
   658 					{
       
   659 					validSectionBeginFound = ETrue;
       
   660 					}
       
   661 				continue;
       
   662 				}
       
   663 			}
       
   664 		else if(whatToFindSection == ESectionEnd)
       
   665 			{
       
   666 			//Find in line end tag (if end tag is not given, behave like we've found it)
       
   667 			if(aEndTag.Length() == 0)
       
   668 				{
       
   669 				ret = KErrNotFound;
       
   670 				}
       
   671 			else
       
   672 				{
       
   673 				ret = withoutCommentsBuf->Find(aEndTag);
       
   674 				}
       
   675 				//If found check if this is the one we're looking for
       
   676 			if(ret >= 0)
       
   677 				{
       
   678 				whatToFindSection = ESectionStart;
       
   679 				TInt offset = -(bufPtr.Length() + endOfLinePtr.Length() - ret - aEndTag.Length()) * iBytesPerChar;
       
   680 				User::LeaveIfError(iCurrentFile->Seek(ESeekCurrent, offset));
       
   681 
       
   682 				whatToFind = EStart; //reset marker, because if we've found tag, we couldn't be in the middle of comment or quota
       
   683 				if(foundSection == aSeeked)
       
   684 					{
       
   685 					//Add this line to section lines array
       
   686 					HBufC* line = HBufC::NewLC(bufPtr.Length());
       
   687 					TPtr linePtr(line->Des());
       
   688 					linePtr.Copy(bufPtr.MidTPtr(0, ret));
       
   689 					User::LeaveIfError(iSectionLines.Append(line));
       
   690 					CleanupStack::Pop(line);
       
   691 					validSectionEndFound = ETrue;
       
   692 					break;
       
   693 					}
       
   694 				else
       
   695 					{
       
   696 					continue;
       
   697 					}
       
   698 				}
       
   699 			else
       
   700 				{
       
   701 				//If we're in section we are looking for, add line to array
       
   702 				if(foundSection == aSeeked)
       
   703 					{
       
   704 					HBufC* line = HBufC::NewLC(bufPtr.Length() + endOfLinePtr.Length());
       
   705 					TPtr linePtr(line->Des());
       
   706 					linePtr.Copy(bufPtr);
       
   707 					linePtr.Append(endOfLinePtr);
       
   708 					User::LeaveIfError(iSectionLines.Append(line));
       
   709 					CleanupStack::Pop(line);
       
   710 					}
       
   711 				}
       
   712 			}
       
   713 		}
       
   714 
       
   715 	//Clean data
       
   716 	CleanupStack::PopAndDestroy(endOfLine);
       
   717 	CleanupStack::PopAndDestroy(withoutCommentsBuf);
       
   718 	CleanupStack::PopAndDestroy(buf);
       
   719 	
       
   720 	//Load into section if found
       
   721 	HBufC* section = NULL;
       
   722 
       
   723 	if(validSectionBeginFound && validSectionEndFound)
       
   724 		{
       
   725 		//Count amount of memory needed for section
       
   726 		TInt i;
       
   727 		TInt size = 0;
       
   728 		for(i = 0; i < iSectionLines.Count(); i++)
       
   729 			size += iSectionLines[i]->Length();
       
   730 		
       
   731 		//Copy section from array to buffer
       
   732 		section = HBufC::NewL(size);
       
   733 		CleanupStack::PushL(section);
       
   734 		TPtr sectionPtr(section->Des());
       
   735 
       
   736 		for(i = 0; i < iSectionLines.Count(); i++)
       
   737 			sectionPtr.Append(*iSectionLines[i]);
       
   738 
       
   739 		ClearSectionLinesArray();
       
   740 		
       
   741 		//Clean local data
       
   742 		CleanupStack::Pop(section);
       
   743 		
       
   744 		return section;
       
   745 		}
       
   746 	
       
   747 	ClearSectionLinesArray();
       
   748 
       
   749 	//If section was not found, then for compability with CSectionParser leave when not first section was seeking, return NULL when first section was seeking
       
   750 	if(foundSection != aSeeked)
       
   751 		{
       
   752 		if( aSeeked - foundSection > 1)
       
   753 			{			
       
   754 			User::Leave(KErrNotFound);
       
   755 			}
       
   756 		}
       
   757 
       
   758     return section;
       
   759 	}
       
   760 
       
   761 /*
       
   762 -------------------------------------------------------------------------------
       
   763 
       
   764     Class: CStifFileParser
       
   765 
       
   766     Method: ClearFileStack
       
   767 
       
   768     Description: Closes all files on file stack and clears the stack
       
   769 
       
   770     Parameters: None
       
   771 
       
   772     Return Values: None
       
   773 
       
   774     Errors/Exceptions:  None
       
   775 
       
   776     Status: Proposal
       
   777 
       
   778 -------------------------------------------------------------------------------
       
   779 */
       
   780 void CStifFileParser::ClearFileStack(void)
       
   781 	{
       
   782 	while(!iFileStack->IsEmpty())
       
   783 		{
       
   784 		PopFromFileStack();
       
   785 		}
       
   786 	}
       
   787 
       
   788 /*
       
   789 -------------------------------------------------------------------------------
       
   790 
       
   791     Class: CStifFileParser
       
   792 
       
   793     Method: PopFromFileStack
       
   794 
       
   795     Description: Pops RFile handle from file stack and sets correct current file handle
       
   796 
       
   797     Parameters: None
       
   798 
       
   799     Return Values: None
       
   800 
       
   801     Errors/Exceptions:  None
       
   802 
       
   803     Status: Proposal
       
   804 
       
   805 -------------------------------------------------------------------------------
       
   806 */
       
   807 void CStifFileParser::PopFromFileStack(void)
       
   808 	{
       
   809 	if(!iFileStack->IsEmpty())
       
   810 		{
       
   811 		//Pop from stack
       
   812 		iCurrentFile = iFileStack->Pop();
       
   813 
       
   814 		TFileName fn;
       
   815 		iCurrentFile->FullName(fn);
       
   816 
       
   817 		//And remove from file names array
       
   818 		for(TInt i = iFileNames.Count() - 1; i >= 0; i--)
       
   819 			{
       
   820 			if(fn.CompareF(iFileNames[i]->Des()) == KErrNone)
       
   821 				{
       
   822 				delete iFileNames[i];
       
   823 				iFileNames.Remove(i);
       
   824 				break;
       
   825 				}
       
   826 			}
       
   827 		__TRACE(KInfo, (_L("Closing file [%S]"), &fn));
       
   828 
       
   829 		//Close file
       
   830 		iCurrentFile->Close();
       
   831 		delete iCurrentFile;
       
   832 
       
   833 		//Set correct current file
       
   834 		if(iFileStack->IsEmpty())
       
   835 			{
       
   836 			iCurrentFile = &iBaseFile; //base file, because stack is empty
       
   837 			}
       
   838 		else
       
   839 			{
       
   840 			iCurrentFile = iFileStack->Last();
       
   841 			}
       
   842 		}
       
   843 	}
       
   844 
       
   845 /*
       
   846 -------------------------------------------------------------------------------
       
   847 
       
   848     Class: CStifFileParser
       
   849 
       
   850     Method: PushFileToStack
       
   851 
       
   852     Description: Opens file and pushes it to stack
       
   853 
       
   854     Parameters: TDesc& aFileName   in: name of file to open and add to stack
       
   855 
       
   856     Return Values: None
       
   857 
       
   858     Errors/Exceptions:  None
       
   859 
       
   860     Status: Proposal
       
   861 
       
   862 -------------------------------------------------------------------------------
       
   863 */
       
   864 void CStifFileParser::PushFileToStackL(const TDesC& aFileName)
       
   865 	{
       
   866 
       
   867 	//First check if file is not already included
       
   868 	for(TInt i = 0; i < iFileNames.Count(); i++)
       
   869 		{
       
   870 		if(aFileName.CompareF(iFileNames[i]->Des()) == KErrNone)
       
   871 			{
       
   872 			__TRACE(KError, (_L("File [%S] was already included. Ignoring"), &aFileName));
       
   873 			return;
       
   874 			}
       
   875 		}
       
   876 
       
   877 	//Open and add file to stack
       
   878 	RFile *nf = new RFile();
       
   879 
       
   880 	__TRACE(KInfo, (_L("Including file [%S]"), &aFileName));
       
   881 	TInt r = nf->Open(iFileServer, aFileName, EFileRead | EFileShareAny);
       
   882 	if(r == KErrNone)
       
   883 		{
       
   884 		//Add to stack
       
   885 		iFileStack->PushL(nf);
       
   886 
       
   887 		//And add to file names array
       
   888 		HBufC* newFile = aFileName.AllocLC();
       
   889 		User::LeaveIfError(iFileNames.Append(newFile));
       
   890 		CleanupStack::Pop(newFile);
       
   891 
       
   892 		//Set valid pointer of current file
       
   893 		iCurrentFile = nf;
       
   894 		}
       
   895 	else
       
   896 		{
       
   897 		__TRACE(KError, (_L("Could not open file [%S]. Error %d. Ignoring"), &aFileName, r));
       
   898 		}
       
   899 	}
       
   900 
       
   901 /*
       
   902 -------------------------------------------------------------------------------
       
   903 
       
   904     Class: CStifFileParser
       
   905 
       
   906     Method: ClearSectionLinesArray
       
   907 
       
   908     Description: Deletes all descriptors assigned to array and empties array
       
   909 
       
   910     Parameters: None
       
   911 
       
   912     Return Values: None
       
   913 
       
   914     Errors/Exceptions:  None
       
   915 
       
   916     Status: Proposal
       
   917 
       
   918 -------------------------------------------------------------------------------
       
   919 */
       
   920 void CStifFileParser::ClearSectionLinesArray(void)
       
   921 	{
       
   922 	while(iSectionLines.Count() > 0)
       
   923 		{
       
   924 		delete iSectionLines[0];
       
   925 		iSectionLines.Remove(0);
       
   926 		}
       
   927 	}
       
   928 
       
   929 // End of File