stif/Parser/src/StifParser.cpp
branchRCL_3
changeset 59 8ad140f3dd41
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 "StifParser.h"
       
    22 #include "ParserTracing.h"
       
    23 #include "StifFileParser.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: CStifParser
       
    58 
       
    59     Method: CStifParser
       
    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 CStifParser::CStifParser( TCommentType aCommentType ) :
       
    77     iBuffer( 0, 0 )
       
    78     {
       
    79     iCommentType = aCommentType;
       
    80 
       
    81     iParsingMode = EFileParsing;
       
    82 
       
    83     iIsUnicode = EFalse;
       
    84     
       
    85     iFileParser = NULL;
       
    86     }
       
    87 
       
    88 /*
       
    89 -------------------------------------------------------------------------------
       
    90 
       
    91     Class: CStifParser
       
    92 
       
    93     Method: ConstructL
       
    94 
       
    95     Description: Symbian OS second phase constructor
       
    96 
       
    97     Symbian OS default constructor can leave.
       
    98 
       
    99     Connecting and opening configuration file if path and file information is 
       
   100     given. If path and file information is not given and information is given 
       
   101     in buffer then create parser according to the buffer.
       
   102     
       
   103     Parameters: const TDesC& aPath: in: Source path definition
       
   104                 const TDesC& aConfig: in: Configuration filename
       
   105                 const TDesC& aBuffer: in: Buffer of the parsed information
       
   106 
       
   107     Return Values: None
       
   108 
       
   109     Errors/Exceptions:  Leaves if called Connect method fails
       
   110                         Leaves if called SetSessionPath method fails
       
   111                         Leaves if called Open method fails
       
   112                         Leaves if HBufC::NewL operation leaves
       
   113 
       
   114     Status: Proposal
       
   115 
       
   116 -------------------------------------------------------------------------------
       
   117 */
       
   118 void CStifParser::ConstructL( const TDesC& aPath,
       
   119                                 const TDesC& aConfig,
       
   120                                 const TDesC& aBuffer)
       
   121     {
       
   122     if( aPath == KNullDesC && aConfig == KNullDesC && aBuffer != KNullDesC )
       
   123         {
       
   124         // Set mode
       
   125         iParsingMode = EBufferParsing;
       
   126 
       
   127         // Construct modifiable heap-based descriptor.
       
   128         iBufferTmp = HBufC::NewL( aBuffer.Length() );
       
   129         //iBuffer = iBufferTmp->Des();
       
   130         iBuffer.Set( iBufferTmp->Des() );
       
   131         // Copy content
       
   132         iBuffer.Copy( aBuffer );
       
   133         }
       
   134 
       
   135     else
       
   136         {
       
   137         User::LeaveIfError( iFileServer.Connect() );
       
   138     
       
   139         __TRACE( KInfo, ( _L( "STIFPARSER: Open configfile '%S%S'" ),
       
   140                 &aPath, &aConfig ) );
       
   141                 
       
   142         User::LeaveIfError( iFileServer.SetSessionPath( aPath ) );
       
   143         User::LeaveIfError( iFile.Open( 
       
   144                             iFileServer, aConfig, EFileRead | EFileShareAny ) );
       
   145 
       
   146         //Check whether the file is unicoded
       
   147         __TRACE(KInfo, (_L("STIFPARSER: Check if the file is unicode")));
       
   148         _LIT(KUnicode, "#UNICODE");
       
   149         const TInt KUnicodeLength(8 * 2 + 2); //times two, because we want to read unicode string using 8bit descriptor
       
   150                                               //two characters more because on some systems FEFF is always added on the beginning of unicode file
       
   151         TInt size(0);
       
   152 
       
   153         User::LeaveIfError(iFile.Size(size));
       
   154 
       
   155         if(size >= KUnicodeLength)
       
   156             {
       
   157             TBuf8<KUnicodeLength> buf;
       
   158 
       
   159             User::LeaveIfError(iFile.Read(0, buf));
       
   160             TPtrC16 bufuni((TUint16 *)(buf.Ptr()), buf.Length() / 2);
       
   161             if(bufuni.Find(KUnicode) != KErrNotFound)
       
   162                 {
       
   163                 iIsUnicode = ETrue;
       
   164                 __TRACE(KInfo, (_L("STIFPARSER: File is unicode")));
       
   165                 }
       
   166             }
       
   167         
       
   168         //Create file parser object
       
   169         iFileParser = CStifFileParser::NewL(iFileServer, iFile, iIsUnicode, iCommentType);
       
   170         }
       
   171 
       
   172     iOffset = 0;
       
   173 
       
   174     }
       
   175 
       
   176 /*
       
   177 -------------------------------------------------------------------------------
       
   178 
       
   179     Class: CStifParser
       
   180 
       
   181     Method: NewL
       
   182 
       
   183     Description: Two-phased constructor.
       
   184 
       
   185     Starting creating parser with path and file information.
       
   186 
       
   187     Parameters: const TDesC& aPath: in: Source path definition
       
   188                 const TDesC& aConfig: in: Configuration filename
       
   189                 TCommentType aCommentType: in: Comment type's indication
       
   190 
       
   191     Return Values: CStifParser* : pointer to CStifParser object
       
   192 
       
   193     Errors/Exceptions: Leaves if ConstructL leaves
       
   194 
       
   195     Status: Proposal
       
   196 
       
   197 -------------------------------------------------------------------------------
       
   198 */
       
   199 EXPORT_C CStifParser* CStifParser::NewL( const TDesC& aPath,
       
   200                                             const TDesC& aConfig,
       
   201                                             TCommentType aCommentType )
       
   202     {
       
   203     __TRACE( KInfo, ( _L( "STIFPARSER: Debug information is used" ) ) );
       
   204 
       
   205     // Create CStifParser object
       
   206     CStifParser* parser = new (ELeave) CStifParser( aCommentType );
       
   207 
       
   208     CleanupStack::PushL( parser );
       
   209     parser->ConstructL( aPath, aConfig );
       
   210     CleanupStack::Pop( parser );
       
   211 
       
   212     return parser;
       
   213 
       
   214     }
       
   215 
       
   216 /*
       
   217 -------------------------------------------------------------------------------
       
   218 
       
   219     Class: CStifParser
       
   220 
       
   221     Method: NewL
       
   222 
       
   223     Description: Two-phased constructor.
       
   224 
       
   225     Starting creating parser with buffer information.
       
   226 
       
   227     Parameters: const TDesC& aBuffer: in: Buffer of the parsed informations
       
   228                 TCommentType aCommentType: in: Comment type's indication
       
   229 
       
   230     Return Values: CStifParser* : pointer to CStifParser object
       
   231 
       
   232     Errors/Exceptions: Leaves if ConstructL leaves
       
   233 
       
   234     Status: Proposal
       
   235 
       
   236 -------------------------------------------------------------------------------
       
   237 */
       
   238 EXPORT_C CStifParser* CStifParser::NewL( const TDesC& aBuffer,
       
   239                                             TCommentType aCommentType )
       
   240     {
       
   241     __TRACE( KInfo, ( _L( "STIFPARSER: Debug information is used" ) ) );
       
   242 
       
   243     // Create CStifParser object
       
   244     CStifParser* parser = new (ELeave) CStifParser( aCommentType );
       
   245 
       
   246     CleanupStack::PushL( parser );
       
   247     // No path and file name informations. Buffer is given
       
   248     parser->ConstructL( KNullDesC, KNullDesC, aBuffer );
       
   249     CleanupStack::Pop( parser );
       
   250 
       
   251     return parser;
       
   252 
       
   253     }
       
   254 
       
   255 /*
       
   256 -------------------------------------------------------------------------------
       
   257 
       
   258     Class: CStifParser
       
   259 
       
   260     Method: ~CStifParser
       
   261 
       
   262     Description: Destructor
       
   263 
       
   264     Close file and the fileserver handles.
       
   265 
       
   266     Parameters: None
       
   267 
       
   268     Return Values: None
       
   269 
       
   270     Errors/Exceptions: None
       
   271 
       
   272     Status: Proposal
       
   273 
       
   274 -------------------------------------------------------------------------------
       
   275 */    
       
   276 EXPORT_C CStifParser::~CStifParser()
       
   277     {
       
   278 
       
   279     if( iParsingMode == EBufferParsing )
       
   280         {
       
   281         delete iBufferTmp;
       
   282         }
       
   283     else
       
   284         {
       
   285         delete iFileParser;
       
   286         iFile.Close();
       
   287         iFileServer.Close();
       
   288         }
       
   289 
       
   290     }
       
   291 
       
   292 /*
       
   293 -------------------------------------------------------------------------------
       
   294 
       
   295     Class: CStifParser
       
   296 
       
   297     Method: SectionL
       
   298 
       
   299     Description: Parses sections from configuration files.
       
   300 
       
   301     Open and read configuration source and parses a required section.
       
   302     If start tag is empty the parsing starts beginning of the configuration
       
   303     file. If end tag is empty the parsing goes end of configuration file.
       
   304     This method starts always from beginning of configuration file and parses
       
   305     first section if aSeeked parameters is not given.
       
   306     If configuration file includes several sections with both start and end
       
   307     tags so aSeeked parameter seeks the required section. The aSeeked
       
   308     parameters indicates section that will be parsed.
       
   309 
       
   310     Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
       
   311                 const TDesC& aEndTag: in: Indicates an end tag for parsing
       
   312                 TInt aSeeked: in: a seeked section which will be parsed
       
   313 
       
   314     Return Values:  See NextSectionL() method
       
   315 
       
   316     Errors/Exceptions:  See NextSectionL() method
       
   317 
       
   318     Status: Approved
       
   319 
       
   320 -------------------------------------------------------------------------------
       
   321 */
       
   322 EXPORT_C CStifSectionParser* CStifParser::SectionL( const TDesC& aStartTag,
       
   323                                                     const TDesC& aEndTag,
       
   324                                                     TInt aSeeked )
       
   325     {
       
   326     iOffset = 0;
       
   327     return NextSectionL( aStartTag, aEndTag, aSeeked );
       
   328 
       
   329     }
       
   330 
       
   331 /*
       
   332 -------------------------------------------------------------------------------
       
   333 
       
   334     Class: CStifParser
       
   335 
       
   336     Method: NextSectionL
       
   337 
       
   338     Description: Parses sections from configuration files.
       
   339 
       
   340     Open and read configuration source and parses a required section.
       
   341     If start tag is empty the parsing starts beginning of the configuration
       
   342     file. If end tag is empty the parsing goes end of configuration file.
       
   343     This method will parse next section after the earlier section if aSeeked
       
   344     parameter is not given.
       
   345     If configuration file includes several sections with both start and end
       
   346     tags so aSeeked parameter seeks the required section. The aSeeked
       
   347     parameters indicates section that will be parsed.
       
   348 
       
   349     Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
       
   350                 const TDesC& aEndTag: in: Indicates an end tag for parsing
       
   351                 TInt aSeeked: in: a seeked section which will be parsed
       
   352 
       
   353     Return Values:  CStifSectionParser* : pointer to CStifSectionParser object
       
   354                     NULL will return if NextSectionFileL (or NextSectionMemoryL) returns NULL
       
   355 
       
   356     Errors/Exceptions:  Leaves if NextSectionFileL leaves
       
   357                         Leaves if NextSectionMemoryL leaves
       
   358 
       
   359     Status: Proposal
       
   360 
       
   361 -------------------------------------------------------------------------------
       
   362 */
       
   363 EXPORT_C CStifSectionParser* CStifParser::NextSectionL( const TDesC& aStartTag,
       
   364                                                         const TDesC& aEndTag,
       
   365                                                         TInt aSeeked )
       
   366     {
       
   367 	//If parsing mode is set to file, we parse directly in the file
       
   368 	if(iParsingMode == EFileParsing)
       
   369 		{
       
   370 		return NextSectionFileL(aStartTag, aEndTag, aSeeked);
       
   371 		}
       
   372 
       
   373 	//If parsing mode is set to buffer, process in old way
       
   374     return NextSectionMemoryL(aStartTag, aEndTag, aSeeked);
       
   375     }
       
   376 
       
   377 /*
       
   378 -------------------------------------------------------------------------------
       
   379 
       
   380     Class: CStifParser
       
   381 
       
   382     Method: NextSectionMemoryL
       
   383 
       
   384     Description: Parses sections from configuration files.
       
   385 
       
   386     Open and read configuration source and parses a required section.
       
   387     If start tag is empty the parsing starts beginning of the configuration
       
   388     file. If end tag is empty the parsing goes end of configuration file.
       
   389     This method will parse next section after the earlier section if aSeeked
       
   390     parameter is not given.
       
   391     If configuration file includes several sections with both start and end
       
   392     tags so aSeeked parameter seeks the required section. The aSeeked
       
   393     parameters indicates section that will be parsed.
       
   394 
       
   395     Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
       
   396                 const TDesC& aEndTag: in: Indicates an end tag for parsing
       
   397                 TInt aSeeked: in: a seeked section which will be parsed
       
   398 
       
   399     Return Values:  CStifSectionParser* : pointer to CStifSectionParser object
       
   400                     NULL will return if file size or aSeeked is not positive
       
   401                     NULL will return if start tag is not found
       
   402                     NULL will return if end tag is not found
       
   403                     NULL will return if parsed section length is not positive
       
   404 
       
   405     Errors/Exceptions:  Leaves if called Size method fails
       
   406                         Leaves if HBufC::NewLC method leaves
       
   407                         Leaves if called Read method fails
       
   408                         Leaves if CStifSectionParser::NewL methods leaves
       
   409 
       
   410     Status: Proposal
       
   411 
       
   412 -------------------------------------------------------------------------------
       
   413 */
       
   414 CStifSectionParser* CStifParser::NextSectionMemoryL( const TDesC& aStartTag,
       
   415                                                  	 const TDesC& aEndTag,
       
   416                                                      TInt aSeeked )
       
   417     {
       
   418     TInt size( 0 );
       
   419     // Parser is created straight with data
       
   420     if( iParsingMode == EBufferParsing )
       
   421         {
       
   422         size = iBuffer.Length();
       
   423         }
       
   424     // Parser is created with path and file informations
       
   425     else
       
   426         {
       
   427         User::LeaveIfError( iFile.Size( size ) );
       
   428         }
       
   429 
       
   430     // size or aSeeked cannot be 0 or negetive
       
   431     if( size <= 0 || aSeeked <= 0)
       
   432         {
       
   433         __TRACE(
       
   434             KInfo, ( _L( "STIFPARSER: NextSectionL method returns a NULL" ) ) );
       
   435         return NULL;
       
   436         }
       
   437 
       
   438     const TInt tmpSize = 128;//--UNICODE-- KMaxName; // 128 - set to even value, because KMaxName may change in the future
       
   439     TInt offset( 0 ); // Offset value to parts reading
       
   440 
       
   441     // Construct modifiable heap-based descriptor. tmp to CleanupStack
       
   442     HBufC* tmp = HBufC::NewLC( size );
       
   443     TPtr wholeSection = tmp->Des();
       
   444 
       
   445     // Construct modifiable heap-based descriptor. tmp2 to CleanupStack
       
   446     HBufC8* tmp2 = HBufC8::NewLC( tmpSize );    // 128
       
   447     TPtr8 buf = tmp2->Des();
       
   448 
       
   449     // Construct modifiable heap-based descriptor. tmp3 to CleanupStack
       
   450     HBufC* tmp3 = HBufC::NewLC( tmpSize );      // 128
       
   451     TPtr currentSection = tmp3->Des();
       
   452 
       
   453     // Parser is created straight with data
       
   454     if( iParsingMode == EBufferParsing )
       
   455         {
       
   456         // If 8 bit copy changes to 16
       
   457         wholeSection.Copy( iBuffer );
       
   458         }
       
   459     // Parser is created with path and file informations
       
   460     else
       
   461         {
       
   462         TPtrC16 currentSectionUnicode;
       
   463         do // Read data in parts(Maximum part size is KMaxName)
       
   464             {
       
   465             // Read data
       
   466             User::LeaveIfError( iFile.Read( offset, buf, tmpSize ) );
       
   467 
       
   468             // If file is unicode convert differently
       
   469             if(iIsUnicode)
       
   470                 {
       
   471                 // 8 bit to 16 with unicode conversion - simply point to byte array as to double-byte array
       
   472                 currentSectionUnicode.Set((TUint16 *)(buf.Ptr()), buf.Length() / 2);
       
   473                 // Appends current section to whole section
       
   474                 wholeSection.Append( currentSectionUnicode );
       
   475                 }
       
   476             else
       
   477                 {
       
   478                 // 8 bit to 16
       
   479                 currentSection.Copy( buf );
       
   480                 // Appends current section to whole section
       
   481                 wholeSection.Append( currentSection );
       
   482                 }
       
   483 
       
   484             offset += tmpSize;
       
   485 
       
   486             } while( offset < size );
       
   487         }
       
   488 
       
   489     CleanupStack::PopAndDestroy( tmp3 );
       
   490     CleanupStack::PopAndDestroy( tmp2 );
       
   491 
       
   492     // User wants section without c-style comments
       
   493     if( iCommentType == ECStyleComments )
       
   494         {
       
   495         ParseCommentsOff( wholeSection );
       
   496         }
       
   497 
       
   498     TLex lex( wholeSection );
       
   499     lex.SkipAndMark( iOffset );
       
   500 
       
   501     // For the required section length and positions
       
   502     TInt length( 0 );
       
   503     TInt lengthStartPos( 0 );
       
   504     TInt lengthEndPos( 0 );
       
   505     TBool eos( EFalse );
       
   506     TInt tagCount( 1 );
       
   507 
       
   508     // Check is aStartTag given
       
   509     if ( aStartTag.Length() == 0 )
       
   510         {
       
   511         // Skip line break, tabs, spaces etc.
       
   512         lex.SkipSpace();
       
   513         lengthStartPos = lex.Offset();
       
   514         }
       
   515     else
       
   516         {
       
   517         // While end of section
       
   518         while ( !lex.Eos() )
       
   519             {
       
   520             TPtrC ptr = lex.NextToken();
       
   521             // Start of the section is found and correct section
       
   522             if ( ptr == aStartTag && tagCount == aSeeked )
       
   523                 {
       
   524                 lengthStartPos = lex.Offset();
       
   525                 break;
       
   526                 }
       
   527             // Start tag is found but not correct section
       
   528             else if ( ptr == aStartTag )
       
   529                 {
       
   530                 tagCount++;
       
   531                 }
       
   532             }
       
   533         }
       
   534 
       
   535     // If we are end of section lex.Eos() and eos will be ETrue
       
   536     eos = lex.Eos();
       
   537 
       
   538     // Seeked section is not found
       
   539     if ( tagCount != aSeeked )
       
   540         {
       
   541         __TRACE( KInfo, ( _L(
       
   542             "STIFPARSER: NextSectionL method: Seeked section is not found" ) ) );
       
   543         CleanupStack::PopAndDestroy( tmp );
       
   544         User::Leave( KErrNotFound );
       
   545         }
       
   546 
       
   547     // Check is aEndTag given
       
   548     if ( aEndTag.Length() == 0 )
       
   549         {
       
   550         lengthEndPos = wholeSection.Length();
       
   551         }
       
   552     else
       
   553         {
       
   554         // While end of section
       
   555         while ( !lex.Eos() )
       
   556             {
       
   557             TPtrC ptr = lex.NextToken();
       
   558             // End tag of the section is found
       
   559             if ( ptr == aEndTag )
       
   560                 {
       
   561                 lengthEndPos = lex.Offset();
       
   562                 // Because Offset() position is after the aEndTag
       
   563                 lengthEndPos -= aEndTag.Length();
       
   564                 break;
       
   565                 }
       
   566             }
       
   567         }
       
   568 
       
   569     // If we are end of section and lengthEndPos is 0
       
   570     if ( lengthEndPos == 0 )
       
   571         {
       
   572         // lex.Eos() and eos will be ETrue
       
   573         eos = lex.Eos();
       
   574         }
       
   575 
       
   576     // The length includes spaces and end of lines
       
   577     length = ( lengthEndPos - lengthStartPos );
       
   578 
       
   579     CStifSectionParser* section = NULL;
       
   580 
       
   581     // If eos is true or length is negative
       
   582     if ( eos || length <= 0  )
       
   583         {
       
   584         __TRACE(
       
   585             KInfo, ( _L( "STIFPARSER: NextSectionL method returns a NULL" ) ) );
       
   586         }
       
   587     else
       
   588         {
       
   589         // Make CStifSectionParser object and alloc required length
       
   590         section = CStifSectionParser::NewL( length );
       
   591         CleanupStack::PushL( section );
       
   592 
       
   593         // Copy required data to the section object
       
   594         section->SetData( wholeSection, lengthStartPos, length );
       
   595 
       
   596         //iOffset += lengthEndPos + aEndTag.Length();
       
   597         iOffset = lex.Offset();
       
   598 
       
   599         CleanupStack::Pop( section );
       
   600         }
       
   601     CleanupStack::PopAndDestroy( tmp );
       
   602 
       
   603     return section;
       
   604 
       
   605     }
       
   606 
       
   607 /*
       
   608 -------------------------------------------------------------------------------
       
   609 
       
   610     Class: CStifParser
       
   611 
       
   612     Method: NextSectionFileL
       
   613 
       
   614     Description: Parses sections from configuration files.
       
   615 
       
   616     Open and read configuration source and parses a required section.
       
   617     If start tag is empty the parsing starts beginning of the configuration
       
   618     file. If end tag is empty the parsing goes end of configuration file.
       
   619     This method will parse next section after the earlier section if aSeeked
       
   620     parameter is not given.
       
   621     If configuration file includes several sections with both start and end
       
   622     tags so aSeeked parameter seeks the required section. The aSeeked
       
   623     parameters indicates section that will be parsed.
       
   624 
       
   625     Parameters: const TDesC& aStartTag: in: Indicates a start tag for parsing
       
   626                 const TDesC& aEndTag: in: Indicates an end tag for parsing
       
   627                 TInt aSeeked: in: a seeked section which will be parsed
       
   628 
       
   629     Return Values:  CStifSectionParser* : pointer to CStifSectionParser object
       
   630                     NULL will return if file size or aSeeked is not positive
       
   631                     NULL will return if start tag is not found
       
   632                     NULL will return if end tag is not found
       
   633                     NULL will return if parsed section length is not positive
       
   634 
       
   635     Errors/Exceptions:  Leaves if called Size method fails
       
   636                         Leaves if HBufC::NewLC method leaves
       
   637                         Leaves if called Read method fails
       
   638                         Leaves if CStifSectionParser::NewL methods leaves
       
   639 
       
   640     Status: Proposal
       
   641 
       
   642 -------------------------------------------------------------------------------
       
   643 */
       
   644 CStifSectionParser* CStifParser::NextSectionFileL( const TDesC& aStartTag,
       
   645                                                    const TDesC& aEndTag,
       
   646                                                    TInt aSeeked )
       
   647     {
       
   648 	HBufC *bufSection = iFileParser->NextSectionL(aStartTag, aEndTag, iOffset, aSeeked);
       
   649 
       
   650 	if(bufSection)
       
   651 		{
       
   652 		CleanupStack::PushL(bufSection);
       
   653 		TPtr bufSectionPtr(bufSection->Des());
       
   654 
       
   655 		if(iCommentType == ECStyleComments)
       
   656 			{
       
   657 			ParseCommentsOff(bufSectionPtr);
       
   658 			}
       
   659 
       
   660 		// Make CStifSectionParser object and alloc required length
       
   661 		CStifSectionParser* section = CStifSectionParser::NewL(bufSection->Length());
       
   662 		CleanupStack::PushL(section);
       
   663 
       
   664 		// Copy required data to the section object
       
   665 		section->SetData(bufSectionPtr, 0, bufSection->Length());
       
   666 
       
   667 		// Clean
       
   668 		CleanupStack::Pop(section);
       
   669 		CleanupStack::PopAndDestroy(bufSection);
       
   670 
       
   671 		return section;
       
   672 		}
       
   673 
       
   674 	return NULL;
       
   675     }
       
   676 
       
   677 /*
       
   678 -------------------------------------------------------------------------------
       
   679 
       
   680     Class: CStifParser
       
   681 
       
   682     Method: ParseCommentsOff
       
   683 
       
   684     Description: Convert a section without comments.
       
   685 
       
   686     Parameters: TPtr& aBuf: inout: section to parsed
       
   687 
       
   688     Return Values: None
       
   689 
       
   690     Errors/Exceptions: None
       
   691 
       
   692     Status: Proposal
       
   693 
       
   694 -------------------------------------------------------------------------------
       
   695 */
       
   696 void CStifParser::ParseCommentsOff( TPtr& aBuf )
       
   697     {
       
   698     TInt startPos( 0 );
       
   699     TInt endPos( 0 );
       
   700     TInt length( 0 );
       
   701     enum TSearchType
       
   702         {
       
   703         ENormalSearch,          // Search a '//' or a '/*'
       
   704         ECStyleSlashs,          // Search is '//'
       
   705         ECStyleSlashAndAsterisk,// Search is '/*'
       
   706         EDoRemove,              // Remove comment
       
   707         };
       
   708 
       
   709     TSearchType searchType( ENormalSearch );
       
   710 
       
   711     TLex lex( aBuf );
       
   712 
       
   713     // Remove comments
       
   714     do
       
   715         {
       
   716         switch( searchType )
       
   717             {
       
   718             case ENormalSearch:
       
   719                 {
       
   720                 if( lex.Get() == '/' )
       
   721                     {
       
   722                     // Peek next character( '/' )
       
   723                     if( lex.Peek() == '/' )
       
   724                         {
       
   725                         startPos = lex.Offset();
       
   726                         startPos--;
       
   727                         lex.Inc();
       
   728                         searchType = ECStyleSlashs;
       
   729                         }
       
   730                     // Peek next character( '*' )
       
   731                     else if( lex.Peek() == '*' )
       
   732                         {
       
   733                         startPos = lex.Offset();
       
   734                         startPos--;
       
   735                         lex.Inc();
       
   736                         searchType = ECStyleSlashAndAsterisk;
       
   737                         }
       
   738                     }
       
   739                 break;
       
   740                 }
       
   741             case ECStyleSlashs:
       
   742                 {
       
   743                 // Peek next character(10 or '\n' in UNIX style )
       
   744                 if( lex.Peek() == 0x0A )
       
   745                     {
       
   746                     // Don't remove line break!!( Else this fails:
       
   747                     // 1st line:"this is parsed text 1"
       
   748                     // 2nd line:"this is parsed text 2 // this is comments"
       
   749                     // 1st and 2nd lines will be together and following
       
   750                     // operations may fail)
       
   751                     endPos = lex.Offset();
       
   752                     searchType = EDoRemove;
       
   753                     break;
       
   754                     }
       
   755 
       
   756                 // Peek next character(13 or '\r' in Symbian OS)
       
   757                 if ( lex.Peek() == 0x0D )
       
   758                     {
       
   759                     // Increment the lex position
       
   760                     lex.Inc();
       
   761                     // Peek next character(10 or '\n' in Symbian OS)
       
   762                     if ( lex.Peek() == 0x0A )
       
   763                         {
       
   764                         // Don't remove line break!!( Else this fails:
       
   765                         // 1st line:"this is parsed text 1"
       
   766                         // 2nd line:"this is parsed text 2 // this is comments"
       
   767                         // 1st and 2nd lines will be together and following
       
   768                         // operations may fail)
       
   769                         endPos = lex.Offset();
       
   770                         endPos = endPos - 1; // Two line break characters
       
   771                         searchType = EDoRemove;
       
   772                         break;
       
   773                         }
       
   774                     // 0x0A not found, decrement position
       
   775                     lex.UnGet();
       
   776                     }
       
   777                 // Increment the lex position
       
   778                 lex.Inc();
       
   779                 // Take current end position
       
   780                 endPos = lex.Offset();
       
   781                 break;
       
   782                 }
       
   783 
       
   784             case ECStyleSlashAndAsterisk:
       
   785                 {
       
   786                 // Peek next character( '*' )
       
   787                 if ( lex.Peek() == '*' )
       
   788                     {
       
   789                     // Increment the lex position
       
   790                     lex.Inc();
       
   791                     // Peek next character( '/')
       
   792                     if ( lex.Peek() == '/' )
       
   793                         {
       
   794                         // End of the section is found and increment the lex position
       
   795                         lex.Inc();
       
   796                         endPos = lex.Offset();
       
   797                         searchType = EDoRemove;
       
   798                         break;
       
   799                         }
       
   800                     // '/' not found, decrement position
       
   801                     lex.UnGet();
       
   802                     }
       
   803                 // Increment the lex position
       
   804                 lex.Inc();
       
   805 
       
   806                 // Take current end position
       
   807                 endPos = lex.Offset();
       
   808                 break;
       
   809                 }
       
   810             default:
       
   811                 {
       
   812                 searchType = ENormalSearch;
       
   813                 break;
       
   814                 }
       
   815 
       
   816             } // End of switch
       
   817 
       
   818             // Remove comment
       
   819             if( searchType == EDoRemove )
       
   820                 {
       
   821                 length = endPos - startPos;
       
   822                 aBuf.Delete( startPos, length );
       
   823                 lex = aBuf;
       
   824                 searchType = ENormalSearch;
       
   825                 }
       
   826 
       
   827         } while ( !lex.Eos() );
       
   828 
       
   829     // If comment is started and configure file ends to eof we remove
       
   830     // comments althougt there are no end of line or '*/' characters
       
   831     if( searchType == ECStyleSlashs || searchType == ECStyleSlashs )
       
   832         {
       
   833         length = lex.Offset() - startPos;
       
   834         aBuf.Delete( startPos, length );
       
   835         }
       
   836 
       
   837     HandleSpecialMarks( aBuf );
       
   838 
       
   839     }
       
   840 
       
   841 //
       
   842 //-----------------------------------------------------------------------------
       
   843 //
       
   844 //    Class: CStifParser
       
   845 //
       
   846 //    Method: HandleSpecialMarks
       
   847 //
       
   848 //    Description: Handles special marks.( '\/' and '\*' ). This
       
   849 //         		   is used when ECStyleComments comment type is used.
       
   850 //
       
   851 //    Parameters: TPtr& aBuf: inout: section to parsed
       
   852 //
       
   853 //    Return Values: None
       
   854 //
       
   855 //    Errors/Exceptions: None
       
   856 //
       
   857 //    Status: Proposal
       
   858 //
       
   859 //-----------------------------------------------------------------------------
       
   860 //
       
   861 void CStifParser::HandleSpecialMarks( TPtr& aBuf )
       
   862     {
       
   863     TLex lex( aBuf );
       
   864     TInt firstPos( 0 );
       
   865     
       
   866     //        Replace \/ with /
       
   867     //        Replace \* with *
       
   868     
       
   869     do
       
   870         {
       
   871         //RDebug::Print( _L("Print : %S"), &aBuf );
       
   872         firstPos = lex.Offset();
       
   873         TChar get = lex.Get();
       
   874         // Check is '\'
       
   875         if( get == '\\' ) 
       
   876             {
       
   877             firstPos = (lex.Offset()-1);
       
   878             // Peek next character( '/' or '*' )
       
   879             if( lex.Peek() == '/' || lex.Peek() == '*')
       
   880                 {
       
   881                 aBuf.Delete (firstPos,1);
       
   882                 lex = aBuf;
       
   883                 }
       
   884             }
       
   885            
       
   886         firstPos = 0;
       
   887         } while ( !lex.Eos() );
       
   888 
       
   889     }
       
   890 
       
   891 // End of File