--- a/stif/Parser/src/StifParser.cpp Mon Jun 28 15:36:07 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,891 +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 "StifParser.h"
-#include "ParserTracing.h"
-#include "StifFileParser.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: CStifParser
-
- Method: CStifParser
-
- 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
-
--------------------------------------------------------------------------------
-*/
-CStifParser::CStifParser( TCommentType aCommentType ) :
- iBuffer( 0, 0 )
- {
- iCommentType = aCommentType;
-
- iParsingMode = EFileParsing;
-
- iIsUnicode = EFalse;
-
- iFileParser = NULL;
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: ConstructL
-
- Description: Symbian OS second phase constructor
-
- Symbian OS default constructor can leave.
-
- Connecting and opening configuration file if path and file information is
- given. If path and file information is not given and information is given
- in buffer then create parser according to the buffer.
-
- Parameters: const TDesC& aPath: in: Source path definition
- const TDesC& aConfig: in: Configuration filename
- const TDesC& aBuffer: in: Buffer of the parsed information
-
- Return Values: None
-
- Errors/Exceptions: Leaves if called Connect method fails
- Leaves if called SetSessionPath method fails
- Leaves if called Open method fails
- Leaves if HBufC::NewL operation leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifParser::ConstructL( const TDesC& aPath,
- const TDesC& aConfig,
- const TDesC& aBuffer)
- {
- if( aPath == KNullDesC && aConfig == KNullDesC && aBuffer != KNullDesC )
- {
- // Set mode
- iParsingMode = EBufferParsing;
-
- // Construct modifiable heap-based descriptor.
- iBufferTmp = HBufC::NewL( aBuffer.Length() );
- //iBuffer = iBufferTmp->Des();
- iBuffer.Set( iBufferTmp->Des() );
- // Copy content
- iBuffer.Copy( aBuffer );
- }
-
- else
- {
- User::LeaveIfError( iFileServer.Connect() );
-
- __TRACE( KInfo, ( _L( "STIFPARSER: Open configfile '%S%S'" ),
- &aPath, &aConfig ) );
-
- User::LeaveIfError( iFileServer.SetSessionPath( aPath ) );
- User::LeaveIfError( iFile.Open(
- iFileServer, aConfig, EFileRead | EFileShareAny ) );
-
- //Check whether the file is unicoded
- __TRACE(KInfo, (_L("STIFPARSER: Check if the file is unicode")));
- _LIT(KUnicode, "#UNICODE");
- const TInt KUnicodeLength(8 * 2 + 2); //times two, because we want to read unicode string using 8bit descriptor
- //two characters more because on some systems FEFF is always added on the beginning of unicode file
- TInt size(0);
-
- User::LeaveIfError(iFile.Size(size));
-
- if(size >= KUnicodeLength)
- {
- TBuf8<KUnicodeLength> buf;
-
- User::LeaveIfError(iFile.Read(0, buf));
- TPtrC16 bufuni((TUint16 *)(buf.Ptr()), buf.Length() / 2);
- if(bufuni.Find(KUnicode) != KErrNotFound)
- {
- iIsUnicode = ETrue;
- __TRACE(KInfo, (_L("STIFPARSER: File is unicode")));
- }
- }
-
- //Create file parser object
- iFileParser = CStifFileParser::NewL(iFileServer, iFile, iIsUnicode, iCommentType);
- }
-
- iOffset = 0;
-
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: NewL
-
- Description: Two-phased constructor.
-
- Starting creating parser with path and file information.
-
- Parameters: const TDesC& aPath: in: Source path definition
- const TDesC& aConfig: in: Configuration filename
- TCommentType aCommentType: in: Comment type's indication
-
- Return Values: CStifParser* : pointer to CStifParser object
-
- Errors/Exceptions: Leaves if ConstructL leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-EXPORT_C CStifParser* CStifParser::NewL( const TDesC& aPath,
- const TDesC& aConfig,
- TCommentType aCommentType )
- {
- __TRACE( KInfo, ( _L( "STIFPARSER: Debug information is used" ) ) );
-
- // Create CStifParser object
- CStifParser* parser = new (ELeave) CStifParser( aCommentType );
-
- CleanupStack::PushL( parser );
- parser->ConstructL( aPath, aConfig );
- CleanupStack::Pop( parser );
-
- return parser;
-
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: NewL
-
- Description: Two-phased constructor.
-
- Starting creating parser with buffer information.
-
- Parameters: const TDesC& aBuffer: in: Buffer of the parsed informations
- TCommentType aCommentType: in: Comment type's indication
-
- Return Values: CStifParser* : pointer to CStifParser object
-
- Errors/Exceptions: Leaves if ConstructL leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-EXPORT_C CStifParser* CStifParser::NewL( const TDesC& aBuffer,
- TCommentType aCommentType )
- {
- __TRACE( KInfo, ( _L( "STIFPARSER: Debug information is used" ) ) );
-
- // Create CStifParser object
- CStifParser* parser = new (ELeave) CStifParser( aCommentType );
-
- CleanupStack::PushL( parser );
- // No path and file name informations. Buffer is given
- parser->ConstructL( KNullDesC, KNullDesC, aBuffer );
- CleanupStack::Pop( parser );
-
- return parser;
-
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: ~CStifParser
-
- Description: Destructor
-
- Close file and the fileserver handles.
-
- Parameters: None
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-EXPORT_C CStifParser::~CStifParser()
- {
-
- if( iParsingMode == EBufferParsing )
- {
- delete iBufferTmp;
- }
- else
- {
- delete iFileParser;
- iFile.Close();
- iFileServer.Close();
- }
-
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: SectionL
-
- Description: Parses sections from configuration files.
-
- Open and read configuration source and parses a required section.
- If start tag is empty the parsing starts beginning of the configuration
- file. If end tag is empty the parsing goes end of configuration file.
- This method starts always from beginning of configuration file and parses
- first section if aSeeked parameters is not given.
- If configuration file includes several sections with both start and end
- tags so aSeeked parameter seeks the required section. The aSeeked
- parameters indicates section that will be parsed.
-
- Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
- const TDesC& aEndTag: in: Indicates an end tag for parsing
- TInt aSeeked: in: a seeked section which will be parsed
-
- Return Values: See NextSectionL() method
-
- Errors/Exceptions: See NextSectionL() method
-
- Status: Approved
-
--------------------------------------------------------------------------------
-*/
-EXPORT_C CStifSectionParser* CStifParser::SectionL( const TDesC& aStartTag,
- const TDesC& aEndTag,
- TInt aSeeked )
- {
- iOffset = 0;
- return NextSectionL( aStartTag, aEndTag, aSeeked );
-
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: NextSectionL
-
- Description: Parses sections from configuration files.
-
- Open and read configuration source and parses a required section.
- If start tag is empty the parsing starts beginning of the configuration
- file. If end tag is empty the parsing goes end of configuration file.
- This method will parse next section after the earlier section if aSeeked
- parameter is not given.
- If configuration file includes several sections with both start and end
- tags so aSeeked parameter seeks the required section. The aSeeked
- parameters indicates section that will be parsed.
-
- Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
- const TDesC& aEndTag: in: Indicates an end tag for parsing
- TInt aSeeked: in: a seeked section which will be parsed
-
- Return Values: CStifSectionParser* : pointer to CStifSectionParser object
- NULL will return if NextSectionFileL (or NextSectionMemoryL) returns NULL
-
- Errors/Exceptions: Leaves if NextSectionFileL leaves
- Leaves if NextSectionMemoryL leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-EXPORT_C CStifSectionParser* CStifParser::NextSectionL( const TDesC& aStartTag,
- const TDesC& aEndTag,
- TInt aSeeked )
- {
- //If parsing mode is set to file, we parse directly in the file
- if(iParsingMode == EFileParsing)
- {
- return NextSectionFileL(aStartTag, aEndTag, aSeeked);
- }
-
- //If parsing mode is set to buffer, process in old way
- return NextSectionMemoryL(aStartTag, aEndTag, aSeeked);
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: NextSectionMemoryL
-
- Description: Parses sections from configuration files.
-
- Open and read configuration source and parses a required section.
- If start tag is empty the parsing starts beginning of the configuration
- file. If end tag is empty the parsing goes end of configuration file.
- This method will parse next section after the earlier section if aSeeked
- parameter is not given.
- If configuration file includes several sections with both start and end
- tags so aSeeked parameter seeks the required section. The aSeeked
- parameters indicates section that will be parsed.
-
- Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
- const TDesC& aEndTag: in: Indicates an end tag for parsing
- TInt aSeeked: in: a seeked section which will be parsed
-
- Return Values: CStifSectionParser* : pointer to CStifSectionParser object
- NULL will return if file size or aSeeked is not positive
- NULL will return if start tag is not found
- NULL will return if end tag is not found
- NULL will return if parsed section length is not positive
-
- Errors/Exceptions: Leaves if called Size method fails
- Leaves if HBufC::NewLC method leaves
- Leaves if called Read method fails
- Leaves if CStifSectionParser::NewL methods leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-CStifSectionParser* CStifParser::NextSectionMemoryL( const TDesC& aStartTag,
- const TDesC& aEndTag,
- TInt aSeeked )
- {
- TInt size( 0 );
- // Parser is created straight with data
- if( iParsingMode == EBufferParsing )
- {
- size = iBuffer.Length();
- }
- // Parser is created with path and file informations
- else
- {
- User::LeaveIfError( iFile.Size( size ) );
- }
-
- // size or aSeeked cannot be 0 or negetive
- if( size <= 0 || aSeeked <= 0)
- {
- __TRACE(
- KInfo, ( _L( "STIFPARSER: NextSectionL method returns a NULL" ) ) );
- return NULL;
- }
-
- const TInt tmpSize = 128;//--UNICODE-- KMaxName; // 128 - set to even value, because KMaxName may change in the future
- TInt offset( 0 ); // Offset value to parts reading
-
- // Construct modifiable heap-based descriptor. tmp to CleanupStack
- HBufC* tmp = HBufC::NewLC( size );
- TPtr wholeSection = tmp->Des();
-
- // Construct modifiable heap-based descriptor. tmp2 to CleanupStack
- HBufC8* tmp2 = HBufC8::NewLC( tmpSize ); // 128
- TPtr8 buf = tmp2->Des();
-
- // Construct modifiable heap-based descriptor. tmp3 to CleanupStack
- HBufC* tmp3 = HBufC::NewLC( tmpSize ); // 128
- TPtr currentSection = tmp3->Des();
-
- // Parser is created straight with data
- if( iParsingMode == EBufferParsing )
- {
- // If 8 bit copy changes to 16
- wholeSection.Copy( iBuffer );
- }
- // Parser is created with path and file informations
- else
- {
- TPtrC16 currentSectionUnicode;
- do // Read data in parts(Maximum part size is KMaxName)
- {
- // Read data
- User::LeaveIfError( iFile.Read( offset, buf, tmpSize ) );
-
- // If file is unicode convert differently
- if(iIsUnicode)
- {
- // 8 bit to 16 with unicode conversion - simply point to byte array as to double-byte array
- currentSectionUnicode.Set((TUint16 *)(buf.Ptr()), buf.Length() / 2);
- // Appends current section to whole section
- wholeSection.Append( currentSectionUnicode );
- }
- else
- {
- // 8 bit to 16
- currentSection.Copy( buf );
- // Appends current section to whole section
- wholeSection.Append( currentSection );
- }
-
- offset += tmpSize;
-
- } while( offset < size );
- }
-
- CleanupStack::PopAndDestroy( tmp3 );
- CleanupStack::PopAndDestroy( tmp2 );
-
- // User wants section without c-style comments
- if( iCommentType == ECStyleComments )
- {
- ParseCommentsOff( wholeSection );
- }
-
- TLex lex( wholeSection );
- lex.SkipAndMark( iOffset );
-
- // For the required section length and positions
- TInt length( 0 );
- TInt lengthStartPos( 0 );
- TInt lengthEndPos( 0 );
- TBool eos( EFalse );
- TInt tagCount( 1 );
-
- // Check is aStartTag given
- if ( aStartTag.Length() == 0 )
- {
- // Skip line break, tabs, spaces etc.
- lex.SkipSpace();
- lengthStartPos = lex.Offset();
- }
- else
- {
- // While end of section
- while ( !lex.Eos() )
- {
- TPtrC ptr = lex.NextToken();
- // Start of the section is found and correct section
- if ( ptr == aStartTag && tagCount == aSeeked )
- {
- lengthStartPos = lex.Offset();
- break;
- }
- // Start tag is found but not correct section
- else if ( ptr == aStartTag )
- {
- tagCount++;
- }
- }
- }
-
- // If we are end of section lex.Eos() and eos will be ETrue
- eos = lex.Eos();
-
- // Seeked section is not found
- if ( tagCount != aSeeked )
- {
- __TRACE( KInfo, ( _L(
- "STIFPARSER: NextSectionL method: Seeked section is not found" ) ) );
- CleanupStack::PopAndDestroy( tmp );
- User::Leave( KErrNotFound );
- }
-
- // Check is aEndTag given
- if ( aEndTag.Length() == 0 )
- {
- lengthEndPos = wholeSection.Length();
- }
- else
- {
- // While end of section
- while ( !lex.Eos() )
- {
- TPtrC ptr = lex.NextToken();
- // End tag of the section is found
- if ( ptr == aEndTag )
- {
- lengthEndPos = lex.Offset();
- // Because Offset() position is after the aEndTag
- lengthEndPos -= aEndTag.Length();
- break;
- }
- }
- }
-
- // If we are end of section and lengthEndPos is 0
- if ( lengthEndPos == 0 )
- {
- // lex.Eos() and eos will be ETrue
- eos = lex.Eos();
- }
-
- // The length includes spaces and end of lines
- length = ( lengthEndPos - lengthStartPos );
-
- CStifSectionParser* section = NULL;
-
- // If eos is true or length is negative
- if ( eos || length <= 0 )
- {
- __TRACE(
- KInfo, ( _L( "STIFPARSER: NextSectionL method returns a NULL" ) ) );
- }
- else
- {
- // Make CStifSectionParser object and alloc required length
- section = CStifSectionParser::NewL( length );
- CleanupStack::PushL( section );
-
- // Copy required data to the section object
- section->SetData( wholeSection, lengthStartPos, length );
-
- //iOffset += lengthEndPos + aEndTag.Length();
- iOffset = lex.Offset();
-
- CleanupStack::Pop( section );
- }
- CleanupStack::PopAndDestroy( tmp );
-
- return section;
-
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: NextSectionFileL
-
- Description: Parses sections from configuration files.
-
- Open and read configuration source and parses a required section.
- If start tag is empty the parsing starts beginning of the configuration
- file. If end tag is empty the parsing goes end of configuration file.
- This method will parse next section after the earlier section if aSeeked
- parameter is not given.
- If configuration file includes several sections with both start and end
- tags so aSeeked parameter seeks the required section. The aSeeked
- parameters indicates section that will be parsed.
-
- Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
- const TDesC& aEndTag: in: Indicates an end tag for parsing
- TInt aSeeked: in: a seeked section which will be parsed
-
- Return Values: CStifSectionParser* : pointer to CStifSectionParser object
- NULL will return if file size or aSeeked is not positive
- NULL will return if start tag is not found
- NULL will return if end tag is not found
- NULL will return if parsed section length is not positive
-
- Errors/Exceptions: Leaves if called Size method fails
- Leaves if HBufC::NewLC method leaves
- Leaves if called Read method fails
- Leaves if CStifSectionParser::NewL methods leaves
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-CStifSectionParser* CStifParser::NextSectionFileL( const TDesC& aStartTag,
- const TDesC& aEndTag,
- TInt aSeeked )
- {
- HBufC *bufSection = iFileParser->NextSectionL(aStartTag, aEndTag, iOffset, aSeeked);
-
- if(bufSection)
- {
- CleanupStack::PushL(bufSection);
- TPtr bufSectionPtr(bufSection->Des());
-
- if(iCommentType == ECStyleComments)
- {
- ParseCommentsOff(bufSectionPtr);
- }
-
- // Make CStifSectionParser object and alloc required length
- CStifSectionParser* section = CStifSectionParser::NewL(bufSection->Length());
- CleanupStack::PushL(section);
-
- // Copy required data to the section object
- section->SetData(bufSectionPtr, 0, bufSection->Length());
-
- // Clean
- CleanupStack::Pop(section);
- CleanupStack::PopAndDestroy(bufSection);
-
- return section;
- }
-
- return NULL;
- }
-
-/*
--------------------------------------------------------------------------------
-
- Class: CStifParser
-
- Method: ParseCommentsOff
-
- Description: Convert a section without comments.
-
- Parameters: TPtr& aBuf: inout: section to parsed
-
- Return Values: None
-
- Errors/Exceptions: None
-
- Status: Proposal
-
--------------------------------------------------------------------------------
-*/
-void CStifParser::ParseCommentsOff( TPtr& aBuf )
- {
- TInt startPos( 0 );
- TInt endPos( 0 );
- TInt length( 0 );
- enum TSearchType
- {
- ENormalSearch, // Search a '//' or a '/*'
- ECStyleSlashs, // Search is '//'
- ECStyleSlashAndAsterisk,// Search is '/*'
- EDoRemove, // Remove comment
- };
-
- TSearchType searchType( ENormalSearch );
-
- TLex lex( aBuf );
-
- // Remove comments
- do
- {
- switch( searchType )
- {
- case ENormalSearch:
- {
- if( lex.Get() == '/' )
- {
- // Peek next character( '/' )
- if( lex.Peek() == '/' )
- {
- startPos = lex.Offset();
- startPos--;
- lex.Inc();
- searchType = ECStyleSlashs;
- }
- // Peek next character( '*' )
- else if( lex.Peek() == '*' )
- {
- startPos = lex.Offset();
- startPos--;
- lex.Inc();
- searchType = ECStyleSlashAndAsterisk;
- }
- }
- break;
- }
- case ECStyleSlashs:
- {
- // Peek next character(10 or '\n' in UNIX style )
- if( lex.Peek() == 0x0A )
- {
- // Don't remove line break!!( Else this fails:
- // 1st line:"this is parsed text 1"
- // 2nd line:"this is parsed text 2 // this is comments"
- // 1st and 2nd lines will be together and following
- // operations may fail)
- endPos = lex.Offset();
- searchType = EDoRemove;
- break;
- }
-
- // Peek next character(13 or '\r' in Symbian OS)
- if ( lex.Peek() == 0x0D )
- {
- // Increment the lex position
- lex.Inc();
- // Peek next character(10 or '\n' in Symbian OS)
- if ( lex.Peek() == 0x0A )
- {
- // Don't remove line break!!( Else this fails:
- // 1st line:"this is parsed text 1"
- // 2nd line:"this is parsed text 2 // this is comments"
- // 1st and 2nd lines will be together and following
- // operations may fail)
- endPos = lex.Offset();
- endPos = endPos - 1; // Two line break characters
- searchType = EDoRemove;
- break;
- }
- // 0x0A not found, decrement position
- lex.UnGet();
- }
- // Increment the lex position
- lex.Inc();
- // Take current end position
- endPos = lex.Offset();
- break;
- }
-
- case ECStyleSlashAndAsterisk:
- {
- // Peek next character( '*' )
- if ( lex.Peek() == '*' )
- {
- // Increment the lex position
- lex.Inc();
- // Peek next character( '/')
- if ( lex.Peek() == '/' )
- {
- // End of the section is found and increment the lex position
- lex.Inc();
- endPos = lex.Offset();
- searchType = EDoRemove;
- break;
- }
- // '/' not found, decrement position
- lex.UnGet();
- }
- // Increment the lex position
- lex.Inc();
-
- // Take current end position
- endPos = lex.Offset();
- break;
- }
- default:
- {
- searchType = ENormalSearch;
- break;
- }
-
- } // End of switch
-
- // Remove comment
- if( searchType == EDoRemove )
- {
- length = endPos - startPos;
- aBuf.Delete( startPos, length );
- lex = aBuf;
- searchType = ENormalSearch;
- }
-
- } while ( !lex.Eos() );
-
- // If comment is started and configure file ends to eof we remove
- // comments althougt there are no end of line or '*/' characters
- if( searchType == ECStyleSlashs || searchType == ECStyleSlashs )
- {
- length = lex.Offset() - startPos;
- aBuf.Delete( startPos, length );
- }
-
- HandleSpecialMarks( aBuf );
-
- }
-
-//
-//-----------------------------------------------------------------------------
-//
-// Class: CStifParser
-//
-// Method: HandleSpecialMarks
-//
-// Description: Handles special marks.( '\/' and '\*' ). This
-// is used when ECStyleComments comment type is used.
-//
-// Parameters: TPtr& aBuf: inout: section to parsed
-//
-// Return Values: None
-//
-// Errors/Exceptions: None
-//
-// Status: Proposal
-//
-//-----------------------------------------------------------------------------
-//
-void CStifParser::HandleSpecialMarks( TPtr& aBuf )
- {
- TLex lex( aBuf );
- TInt firstPos( 0 );
-
- // Replace \/ with /
- // Replace \* with *
-
- do
- {
- //RDebug::Print( _L("Print : %S"), &aBuf );
- firstPos = lex.Offset();
- TChar get = lex.Get();
- // Check is '\'
- if( get == '\\' )
- {
- firstPos = (lex.Offset()-1);
- // Peek next character( '/' or '*' )
- if( lex.Peek() == '/' || lex.Peek() == '*')
- {
- aBuf.Delete (firstPos,1);
- lex = aBuf;
- }
- }
-
- firstPos = 0;
- } while ( !lex.Eos() );
-
- }
-
-// End of File