--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/Parser/src/StifParser.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,931 @@
+/*
+* 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 );
+ TInt secondPos( 0 );
+
+ // // => \/\/ => //
+ // /* => \/\* => /*
+ // */ => \*\/ => */
+
+ do
+ {
+ firstPos = lex.Offset();
+ TChar get = lex.Get();
+ // Check is '\'
+ if( get == '\\' )
+ {
+ // Peek next character( '/' )
+ if( lex.Peek() == '/' )
+ {
+ lex.Inc();
+ secondPos = lex.Offset();
+ // Peek next character( '\' )
+ if( lex.Peek() == '\\' )
+ {
+ lex.Inc();
+ // Peek next character( '/' )
+ if( lex.Peek() == '/' )
+ {
+ // Delete mark '\/\/' and replace this with '//'
+ aBuf.Delete( secondPos, 1 );
+ aBuf.Delete( firstPos, 1 );
+ lex = aBuf;
+ }
+ // Peek next character( '/' )
+ else if( lex.Peek() == '*' )
+ {
+ // Delete mark '\/\*' and replace this with '/*'
+ aBuf.Delete( secondPos, 1 );
+ aBuf.Delete( firstPos, 1 );
+ lex = aBuf;
+ }
+ }
+ }
+ // Peek next character( '/' )
+ else if( lex.Peek() == '*' )
+ {
+ lex.Inc();
+ secondPos = lex.Offset();
+ // Peek next character( '\' )
+ if( lex.Peek() == '\\' )
+ {
+ lex.Inc();
+ // Peek next character( '/' )
+ if( lex.Peek() == '/' )
+ {
+ // Delete mark '\*\/' and replace this with '*\'
+ aBuf.Delete( secondPos, 1 );
+ aBuf.Delete( firstPos, 1 );
+ lex = aBuf;
+ }
+ }
+ }
+ }
+ firstPos = 0;
+ secondPos = 0;
+ } while ( !lex.Eos() );
+
+ }
+
+// End of File