--- a/stif/Parser/src/StifFileParser.cpp Tue Jul 06 16:05:13 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,929 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: This module contains implementation of CStifParser
-* class member functions.
-*
-*/
-
-// INCLUDE FILES
-#include <e32std.h>
-#include "StifFileParser.h"
-#include "StifTestInterface.h"
-#include "ParserTracing.h"
-
-// EXTERNAL DATA STRUCTURES
-// None
-
-// EXTERNAL FUNCTION PROTOTYPES
-// None
-
-// CONSTANTS
-// None
-
-// MACROS
-// None
-
-// LOCAL CONSTANTS AND MACROS
-// None
-
-// MODULE DATA STRUCTURES
-// None
-
-// LOCAL FUNCTION PROTOTYPES
-// None
-
-// FORWARD DECLARATIONS
-// None
-
-// ==================== LOCAL FUNCTIONS =======================================
-// None
-
-// ================= MEMBER FUNCTIONS =========================================
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: CStifFileParser
-
- Description: Default constructor
-
- C++ default constructor can NOT contain any code, that
- might leave.
-
- Parameters: TCommentType aCommentType: in: Comment type's indication
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Approved
-
--------------------------------------------------------------------------------
-*/
-CStifFileParser::CStifFileParser(CStifParser::TCommentType aCommentType)
- {
- iCommentType = aCommentType;
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ConstructL
-
- Description: Symbian OS second phase constructor
-
- Symbian OS default constructor can leave.
-
- Sets variables.
-
- Parameters: RFs& aFs: in: Handle to valid file server
- RFile& aFile: in: Handle to the source file
- TBool aIsUnicode in: Is file in unicode format
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::ConstructL(RFs& aFs,
- RFile& aFile,
- TBool aIsUnicode)
- {
- //Initialization
- iFileServer = aFs;
- iBaseFile = aFile;
- iCurrentFile = &aFile;
- iIsUnicode = aIsUnicode;
- iBytesPerChar = iIsUnicode ? 2 : 1;
-
- //Create file stack (INCLUDE feature)
- iFileStack = new (ELeave) CStackDeprecated<RFile, EFalse>;
-
- //Add base file to file names array
- TFileName fn;
- iCurrentFile->FullName(fn);
- HBufC* newFile = fn.AllocLC();
- User::LeaveIfError(iFileNames.Append(newFile));
- CleanupStack::Pop(newFile);
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: NewL
-
- Description: Two-phased constructor.
-
- Starting creating parser with path and file information.
-
- Parameters: RFs& aFs: in: Handle to file server
- RFile& aFile: in: Source path definition
- TBool aIsUnicode in: Is file in unicode format
- TCommentType aCommentType: in: Comment type's indication
-
- Return Values: CStifFileParser* : pointer to CStifFileParser object
-
- Errors/Exceptions: Leaves if ConstructL leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-CStifFileParser* CStifFileParser::NewL(RFs& aFs,
- RFile& aFile,
- TBool aIsUnicode,
- CStifParser::TCommentType aCommentType)
- {
- // Create CStifParser object
- CStifFileParser* parser = new (ELeave) CStifFileParser(aCommentType);
-
- CleanupStack::PushL(parser);
- parser->ConstructL(aFs, aFile, aIsUnicode);
- CleanupStack::Pop(parser);
-
- return parser;
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ~CStifFileParser
-
- Description: Destructor
-
- Parameters: None
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-CStifFileParser::~CStifFileParser()
- {
- //Close file stack
- ClearFileStack();
- delete iFileStack;
-
- //Close section lines array
- ClearSectionLinesArray();
- iSectionLines.Close();
-
- //Close fila names array
- while(iFileNames.Count() > 0)
- {
- delete iFileNames[0];
- iFileNames.Remove(0);
- }
- iFileNames.Close();
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ReadLineL
-
- Description: Reads line from source file
-
- Parameters: TPtr& aLineBuffer: in: Descriptor in which line loads
- TPtr& aEndOfLineBuffer: in: Descriptor in which end of line sequence is loaded (0x0A or 0x0D 0x0A)
-
- Return Values: TBool: determines whether line was readed or not
-
- Errors/Exceptions: Leaves if seek command leaves
- Leaves if buffer is too small
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-TBool CStifFileParser::ReadLineL(TPtr& aLineBuffer,
- TPtr& aEndOfLineBuffer)
- {
- //Variables
- TBuf8<128> buf8;
- TBuf16<128> buf16;
- TPtrC16 buf;
- TInt pos;
- TInt offset;
- TChar char0x0A = 0x000A;
- TChar char0x0D = 0x000D;
-
- TBuf<1> b0x0A;
- b0x0A.Append(char0x0A);
-
- //Reset buffers
- aLineBuffer.Zero();
- aEndOfLineBuffer.Zero();
-
- //Read from source
- User::LeaveIfError(iCurrentFile->Read(buf8));
- buf16.Copy(buf8);
- if(iIsUnicode)
- buf.Set((TUint16 *)(buf8.Ptr()), buf8.Length() / 2);
- else
- buf.Set(buf16.Ptr(), buf16.Length());
-
- while(buf.Length())
- {
- //Search for end of line char
- pos = buf.Find(b0x0A);
-
- //If found, append readed data to output descriptor and move back file offset to correct position
- if(pos >= 0)
- {
- offset = -((buf.Length() - pos - 1) * iBytesPerChar);
- User::LeaveIfError(iCurrentFile->Seek(ESeekCurrent, offset));
- buf.Set(buf.Ptr(), pos + 1);
- aLineBuffer.Append(buf);
- break;
- }
- //Otherwise, append whole buffer to output descriptor
- else
- {
- aLineBuffer.Append(buf);
- }
- //Read next part of data
- User::LeaveIfError(iCurrentFile->Read(buf8));
- buf16.Copy(buf8);
- if(iIsUnicode)
- {
- buf.Set((TUint16 *)(buf8.Ptr()), buf8.Length() / 2);
- }
- else
- {
- buf.Set(buf16.Ptr(), buf16.Length());
- }
- }
-
- //Set correct end of line buffer
- if(buf.Length() > 1)
- {
- if(buf[buf.Length() - 2] == char0x0D)
- {
- aEndOfLineBuffer.Append(char0x0D);
- }
- }
- if(buf.Length() > 0)
- {
- if(buf[buf.Length() - 1] == char0x0A)
- {
- aEndOfLineBuffer.Append(char0x0A);
- }
- else
- {
- aEndOfLineBuffer.Zero();
- }
- }
- if(aEndOfLineBuffer.Length())
- {
- aLineBuffer.SetLength(aLineBuffer.Length() - aEndOfLineBuffer.Length());
- }
-
- //If no data was found, try to get previous file from stack
- if(aLineBuffer.Length() + aEndOfLineBuffer.Length() == 0)
- {
- //Pop file from stack. If stack is empty, then we achieved end of base file
- if(!iFileStack->IsEmpty())
- {
- PopFromFileStack();
- aEndOfLineBuffer.Copy(iEolBuf);
- return aEndOfLineBuffer.Length();
- }
- }
- //Check if this is include line
- else
- {
- if(aLineBuffer.Find(KIncludeKeyword) == 0)
- {
- TFileName fn;
- TLex lex(aLineBuffer);
-
- fn.Copy(lex.NextToken()); //get INCLUDE keyword
- fn.Copy(lex.NextToken()); //get cfg file name
- if(fn.Length() > 0)
- {
- TStifUtil::CorrectFilePathL( fn );
- PushFileToStackL(fn);
- iEolBuf.Copy(aEndOfLineBuffer);
- }
- else
- {
- __TRACE(KError, (_L("No filename was given after INCLUDE. Ignoring")));
- }
-
- //Read next line
- return ReadLineL(aLineBuffer, aEndOfLineBuffer);
- }
- }
-
- return aLineBuffer.Length() + aEndOfLineBuffer.Length();
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ReplaceCommentsLineL
-
- Description: Replaces comments with spaces from line and copy it to destination buffer
-
- Parameters: TPtr& aSrcBufPtr: in: Source line with comments
- TPtr& aDstBufPtr: out: Destination line without comments
- TWhatToFind& aFind: in out: Determines what method currently is looking for
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::ReplaceCommentsLineL(TPtr& aSrcBufPtr,
- TPtr& aDstBufPtr,
- TWhatToFind& aFind)
- {
- //Variables
- TLex lex(aSrcBufPtr);
- TChar ch;
- TChar chSpace(' ');
- TChar chSlash('/');
- TChar chQuota('\"');
- TChar chMulti('*');
- TChar chHash('#');
-
- //Clean buffer
- aDstBufPtr.Zero();
-
- while(!lex.Eos())
- {
- ch = lex.Get();
-
- //If the end of line, exit
- if(!ch)
- {
- break;
- }
-
- //We're looking for start od quoted text or comment
- if(aFind == EStart)
- {
- //Special character readed
- if(ch == chQuota)
- {
- aFind = EQuota;
- aDstBufPtr.Append(chSpace);
- }
- //Possible start of comment
- else if(ch == chSlash)
- {
- //Comment to the end of line found
- if(lex.Peek() == chSlash)
- {
- break;
- }
- //Beginning of a comment found
- else if(lex.Peek() == chMulti)
- {
- aFind = EEndOfComment;
- ch = lex.Get();
- aDstBufPtr.Append(chSpace);
- aDstBufPtr.Append(chSpace);
- }
- //No start of comment - add read slash
- else
- {
- aDstBufPtr.Append(ch);
- }
- }
- //Start of hash comment (to the end of line)
- else if(ch == chHash)
- {
- break;
- }
- //Append readed character to the destination buffer
- else
- {
- aDstBufPtr.Append(ch);
- }
- }
- //We're looking for the end of quoted text
- else if(aFind == EQuota)
- {
- if(ch == chQuota)
- {
- aFind = EStart;
- aDstBufPtr.Append(chSpace);
- }
- else
- {
- aDstBufPtr.Append(chSpace);
- }
- }
- //We're looking for the end of comment
- else if(aFind == EEndOfComment)
- {
- //It may be the end of a comment
- if(ch == chMulti)
- {
- ch = lex.Peek();
- //It is the end of a comment
- if(ch == chSlash)
- {
- aFind = EStart;
- ch = lex.Get();
- aDstBufPtr.Append(chSpace);
- aDstBufPtr.Append(chSpace);
- }
- //It is not the end of a comment, add this character to the destinaton buffer
- else
- {
- aDstBufPtr.Append(chSpace);
- }
- }
- //It is not the end of a comment, add this character to the destinaton buffer
- else
- {
- aDstBufPtr.Append(chSpace);
- }
- }
- }
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ReplaceHashCommentsLineL
-
- Description: Copy line to destination buffer and deletes #-style comments
-
- Parameters: TPtr& aSrcBufPtr: in: Source line with comments
- TPtr& aDstBufPtr: out: Destination line without comments
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::ReplaceHashCommentsLineL(TPtr& aSrcBufPtr,
- TPtr& aDstBufPtr)
- {
- //Variables
- TLex lex(aSrcBufPtr);
- TChar ch;
- TChar chHash('#');
-
- //Prepare destination buffer
- aDstBufPtr.Zero();
-
- //Copy source line to destination until # char is found
- while(!lex.Eos())
- {
- ch = lex.Get();
-
- //If the end of line, exit
- if(!ch)
- {
- break;
- }
-
- if(ch == chHash)
- {
- break;
- }
- else
- {
- aDstBufPtr.Append(ch);
- }
- }
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: NextSectionL
-
- Description: Finds n-th (aSeeked) section in file starting from m-th (aOffset) position
-
- Parameters: const TDesc& aStartTag: in: Starting tag of a section
- const TDesc& aEndTag: in: Ending tag of a section
- TInt& aOffset: in out: Current offset in file (*)
- TInt aSeeked: in: Which section is to be found
-
- Notification: aOffset has different meaning than before adding INCLUDE functionality.
- If it has 0 value, that means that we need to remove files stack and go
- back to base file to the beginning. Otherwise we don't change current
- file read-handler position.
-
- Return Values: HBufC *: address of a descriptor containing section. Section is returned without tags.
- Caller must take care about the freeing descriptor.
-
- Errors/Exceptions: Leaves if aSeeked is less than 1 or aOffset is negative
- Leaves if seek command leaves
- Leaves if cannot allocate buffers
- Leaves if cannot allocate section
- Leaves if length of readed line exceeds KMaxLineLength constant
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-HBufC* CStifFileParser::NextSectionL(const TDesC& aStartTag,
- const TDesC& aEndTag,
- TInt& aOffset,
- TInt aSeeked)
- {
- // Check arguments
- if(aSeeked < 1)
- {
- User::Leave(KErrArgument);
- }
- if(aOffset < 0)
- {
- User::Leave(KErrArgument);
- }
-
- TInt foundSection = 0;
- TInt ret;
-
- // Alloc buffers to read line
- const TInt KMaxLineLength = 4096; //If length of readed line exceeds this constant, method will leave
-
- HBufC* buf = HBufC::NewL(KMaxLineLength);
- CleanupStack::PushL(buf);
- TPtr bufPtr(buf->Des());
-
- HBufC* withoutCommentsBuf = HBufC::NewL(KMaxLineLength);
- CleanupStack::PushL(withoutCommentsBuf);
- TPtr withoutCommentsBufPtr(withoutCommentsBuf->Des());
-
- HBufC* endOfLine = HBufC::NewL(2); //After reading a line it contains 0D0A or 0A or null (how readed line is ended)
- CleanupStack::PushL(endOfLine);
- TPtr endOfLinePtr(endOfLine->Des());
-
- //Set valid position in file
- //but only if offset shows to 0. Otherwise keep previus position
- if(aOffset == 0)
- {
- User::LeaveIfError(iBaseFile.Seek(ESeekStart, aOffset));
- ClearFileStack();
- aOffset = 1;
- }
-
- //Prepare to read lines
- TBool validSectionBeginFound = EFalse;
- TBool validSectionEndFound = EFalse;
- TSectionFind whatToFindSection = ESectionStart;
- //If no start tag is given start to find end tag immediatly
- if(aStartTag.Length() == 0)
- {
- foundSection++;
- whatToFindSection = ESectionEnd;
- validSectionBeginFound = ETrue;
- }
- if(aEndTag.Length() == 0)
- {
- validSectionEndFound = ETrue;
- }
- TWhatToFind whatToFind = EStart;
-
- //Perform reading file
- while(ReadLineL(bufPtr, endOfLinePtr))
- {
- if(iCommentType == CStifParser::ECStyleComments)
- {
- ReplaceCommentsLineL(bufPtr, withoutCommentsBufPtr, whatToFind);
- }
- else
- {
- ReplaceHashCommentsLineL(bufPtr, withoutCommentsBufPtr);
- }
- if(whatToFindSection == ESectionStart)
- {
- //Find in line star tag (if start tag is not given, behave like we've found it)
- if(aStartTag.Length() == 0)
- {
- ret = 0;
- }
- else
- {
- ret = withoutCommentsBuf->Find(aStartTag);
- }
- //If found remember position, move offset of file to actual position
- if(ret >= 0)
- {
- whatToFindSection = ESectionEnd;
- TInt offset = -(bufPtr.Length() + endOfLinePtr.Length() - ret - aStartTag.Length()) * iBytesPerChar;
- User::LeaveIfError(iCurrentFile->Seek(ESeekCurrent, offset));
-
- whatToFind = EStart; //reset marker, because if we've found tag, we couldn't be in the middle of comment or quota
- foundSection++;
- //Add this line to section lines array
- if(foundSection == aSeeked)
- {
- validSectionBeginFound = ETrue;
- }
- continue;
- }
- }
- else if(whatToFindSection == ESectionEnd)
- {
- //Find in line end tag (if end tag is not given, behave like we've found it)
- if(aEndTag.Length() == 0)
- {
- ret = KErrNotFound;
- }
- else
- {
- ret = withoutCommentsBuf->Find(aEndTag);
- }
- //If found check if this is the one we're looking for
- if(ret >= 0)
- {
- whatToFindSection = ESectionStart;
- TInt offset = -(bufPtr.Length() + endOfLinePtr.Length() - ret - aEndTag.Length()) * iBytesPerChar;
- User::LeaveIfError(iCurrentFile->Seek(ESeekCurrent, offset));
-
- whatToFind = EStart; //reset marker, because if we've found tag, we couldn't be in the middle of comment or quota
- if(foundSection == aSeeked)
- {
- //Add this line to section lines array
- HBufC* line = HBufC::NewLC(bufPtr.Length());
- TPtr linePtr(line->Des());
- linePtr.Copy(bufPtr.MidTPtr(0, ret));
- User::LeaveIfError(iSectionLines.Append(line));
- CleanupStack::Pop(line);
- validSectionEndFound = ETrue;
- break;
- }
- else
- {
- continue;
- }
- }
- else
- {
- //If we're in section we are looking for, add line to array
- if(foundSection == aSeeked)
- {
- HBufC* line = HBufC::NewLC(bufPtr.Length() + endOfLinePtr.Length());
- TPtr linePtr(line->Des());
- linePtr.Copy(bufPtr);
- linePtr.Append(endOfLinePtr);
- User::LeaveIfError(iSectionLines.Append(line));
- CleanupStack::Pop(line);
- }
- }
- }
- }
-
- //Clean data
- CleanupStack::PopAndDestroy(endOfLine);
- CleanupStack::PopAndDestroy(withoutCommentsBuf);
- CleanupStack::PopAndDestroy(buf);
-
- //Load into section if found
- HBufC* section = NULL;
-
- if(validSectionBeginFound && validSectionEndFound)
- {
- //Count amount of memory needed for section
- TInt i;
- TInt size = 0;
- for(i = 0; i < iSectionLines.Count(); i++)
- size += iSectionLines[i]->Length();
-
- //Copy section from array to buffer
- section = HBufC::NewL(size);
- CleanupStack::PushL(section);
- TPtr sectionPtr(section->Des());
-
- for(i = 0; i < iSectionLines.Count(); i++)
- sectionPtr.Append(*iSectionLines[i]);
-
- ClearSectionLinesArray();
-
- //Clean local data
- CleanupStack::Pop(section);
-
- return section;
- }
-
- ClearSectionLinesArray();
-
- //If section was not found, then for compability with CSectionParser leave when not first section was seeking, return NULL when first section was seeking
- if(foundSection != aSeeked)
- {
- if( aSeeked - foundSection > 1)
- {
- User::Leave(KErrNotFound);
- }
- }
-
- return section;
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ClearFileStack
-
- Description: Closes all files on file stack and clears the stack
-
- Parameters: None
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::ClearFileStack(void)
- {
- while(!iFileStack->IsEmpty())
- {
- PopFromFileStack();
- }
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: PopFromFileStack
-
- Description: Pops RFile handle from file stack and sets correct current file handle
-
- Parameters: None
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::PopFromFileStack(void)
- {
- if(!iFileStack->IsEmpty())
- {
- //Pop from stack
- iCurrentFile = iFileStack->Pop();
-
- TFileName fn;
- iCurrentFile->FullName(fn);
-
- //And remove from file names array
- for(TInt i = iFileNames.Count() - 1; i >= 0; i--)
- {
- if(fn.CompareF(iFileNames[i]->Des()) == KErrNone)
- {
- delete iFileNames[i];
- iFileNames.Remove(i);
- break;
- }
- }
- __TRACE(KInfo, (_L("Closing file [%S]"), &fn));
-
- //Close file
- iCurrentFile->Close();
- delete iCurrentFile;
-
- //Set correct current file
- if(iFileStack->IsEmpty())
- {
- iCurrentFile = &iBaseFile; //base file, because stack is empty
- }
- else
- {
- iCurrentFile = iFileStack->Last();
- }
- }
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: PushFileToStack
-
- Description: Opens file and pushes it to stack
-
- Parameters: TDesc& aFileName in: name of file to open and add to stack
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::PushFileToStackL(const TDesC& aFileName)
- {
-
- //First check if file is not already included
- for(TInt i = 0; i < iFileNames.Count(); i++)
- {
- if(aFileName.CompareF(iFileNames[i]->Des()) == KErrNone)
- {
- __TRACE(KError, (_L("File [%S] was already included. Ignoring"), &aFileName));
- return;
- }
- }
-
- //Open and add file to stack
- RFile *nf = new RFile();
-
- __TRACE(KInfo, (_L("Including file [%S]"), &aFileName));
- TInt r = nf->Open(iFileServer, aFileName, EFileRead | EFileShareAny);
- if(r == KErrNone)
- {
- //Add to stack
- iFileStack->PushL(nf);
-
- //And add to file names array
- HBufC* newFile = aFileName.AllocLC();
- User::LeaveIfError(iFileNames.Append(newFile));
- CleanupStack::Pop(newFile);
-
- //Set valid pointer of current file
- iCurrentFile = nf;
- }
- else
- {
- __TRACE(KError, (_L("Could not open file [%S]. Error %d. Ignoring"), &aFileName, r));
- }
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifFileParser
-
- Method: ClearSectionLinesArray
-
- Description: Deletes all descriptors assigned to array and empties array
-
- Parameters: None
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifFileParser::ClearSectionLinesArray(void)
- {
- while(iSectionLines.Count() > 0)
- {
- delete iSectionLines[0];
- iSectionLines.Remove(0);
- }
- }
-
-// End of File