testexecfw/stf/stffw/parser/src/StifSectionParser.cpp
changeset 2 8bb370ba6d1d
equal deleted inserted replaced
1:bbd31066657e 2:8bb370ba6d1d
       
     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 
       
    15 * CStifSectionParser class member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include "StifSectionParser.h"
       
    22 #include "ParserTracing.h"
       
    23 
       
    24 // EXTERNAL DATA STRUCTURES
       
    25 // None
       
    26 
       
    27 // EXTERNAL FUNCTION PROTOTYPES
       
    28 // None
       
    29 
       
    30 // CONSTANTS
       
    31 // None
       
    32 
       
    33 // MACROS
       
    34 // None
       
    35 
       
    36 // LOCAL CONSTANTS AND MACROS
       
    37 // None
       
    38 
       
    39 // MODULE DATA STRUCTURES
       
    40 // None
       
    41 
       
    42 // LOCAL FUNCTION PROTOTYPES
       
    43 // None
       
    44 
       
    45 // FORWARD DECLARATIONS
       
    46 // None
       
    47 
       
    48 // ==================== LOCAL FUNCTIONS =======================================
       
    49 // None
       
    50 
       
    51 // ================= MEMBER FUNCTIONS =========================================
       
    52 
       
    53 /*
       
    54 -------------------------------------------------------------------------------
       
    55 
       
    56     Class: CStifSectionParser
       
    57 
       
    58     Method: CStifSectionParser
       
    59 
       
    60     Description: Default constructor.
       
    61 
       
    62     C++ default constructor can NOT contain any code, that
       
    63     might leave.
       
    64 
       
    65     Parameters: const TInt aLength: in: Parsed section length
       
    66 
       
    67     Return Values: None
       
    68 
       
    69     Errors/Exceptions: None
       
    70 
       
    71     Status: Approved
       
    72 
       
    73 -------------------------------------------------------------------------------
       
    74 */
       
    75 CStifSectionParser::CStifSectionParser( const TInt aLength ) :
       
    76     iSection( 0, 0 ),
       
    77     iLength( aLength ),
       
    78     iSkipAndMarkPos( 0 ),
       
    79     iLineIndicator( EFalse )
       
    80     {
       
    81 
       
    82     }
       
    83 
       
    84 /*
       
    85 -------------------------------------------------------------------------------
       
    86 
       
    87     Class: CStifSectionParser
       
    88 
       
    89     Method: ConstructL
       
    90 
       
    91     Description: Symbian OS second phase constructor.
       
    92 
       
    93     Symbian OS default constructor can leave.
       
    94 
       
    95     Parameters: None
       
    96 
       
    97     Return Values: None
       
    98 
       
    99     Errors/Exceptions:  Leaves if iLength is negative
       
   100                         Leaves if called NewL method fails
       
   101 
       
   102     Status: Approved
       
   103 
       
   104 -------------------------------------------------------------------------------
       
   105 */
       
   106 void CStifSectionParser::ConstructL()
       
   107     {
       
   108     // Construct modifiable heap-based descriptor
       
   109     iHBufferSection = HBufC::NewL( iLength );
       
   110     iSection.Set(iHBufferSection->Des());
       
   111 
       
   112     iSubOffset = 0;
       
   113 
       
   114     }
       
   115 
       
   116 /*
       
   117 -------------------------------------------------------------------------------
       
   118 
       
   119     Class: CStifSectionParser
       
   120 
       
   121     Method: NewL
       
   122 
       
   123     Description: Two-phased constructor.
       
   124 
       
   125     Parameters: const TInt aLength: in: Parsed section length
       
   126 
       
   127     Return Values: CStifSectionParser* : pointer to CStifSectionParser object
       
   128 
       
   129     Errors/Exceptions:  Leaves if section length is negative
       
   130                         Leaves if construction fails
       
   131 
       
   132     Status: Approved
       
   133 
       
   134 -------------------------------------------------------------------------------
       
   135 */
       
   136 CStifSectionParser* CStifSectionParser::NewL( const TInt aLength )
       
   137     {
       
   138     __TRACE( KInfo, ( _L( "STIFPARSER: Create a section" ) ) );
       
   139     __ASSERT_ALWAYS( aLength > 0, User::Leave( KErrArgument ) );
       
   140 
       
   141     CStifSectionParser* item = new (ELeave) CStifSectionParser( aLength );
       
   142 
       
   143     CleanupStack::PushL( item );
       
   144     item->ConstructL();
       
   145     CleanupStack::Pop( item );
       
   146 
       
   147     return item;
       
   148 
       
   149     }
       
   150 
       
   151 /*
       
   152 -------------------------------------------------------------------------------
       
   153 
       
   154     Class: CStifSectionParser
       
   155 
       
   156     Method: ~CStifSectionParser
       
   157 
       
   158     Description: Destructor
       
   159 
       
   160     Parameters: None
       
   161 
       
   162     Return Values: None
       
   163 
       
   164     Errors/Exceptions: None
       
   165 
       
   166     Status: Approved
       
   167 
       
   168 -------------------------------------------------------------------------------
       
   169 */    
       
   170 CStifSectionParser::~CStifSectionParser()
       
   171     {
       
   172     __TRACE( KInfo, ( _L( "STIFPARSER: Call destructor '~CStifSectionParser'" ) ) );
       
   173 
       
   174     delete iHBufferSection;
       
   175 
       
   176     }
       
   177 
       
   178 /*
       
   179 -------------------------------------------------------------------------------
       
   180 
       
   181     Class: CStifSectionParser
       
   182 
       
   183     Method: ParseStartAndEndPos
       
   184 
       
   185     Description: Start and end position parser.
       
   186 
       
   187     Parameters: TPtrC aSection: in: Parsed section
       
   188                 const TDesC& aStartTag: in: Start tag of parsing
       
   189                 TTagToReturnValue aTagIndicator: in: Will aStartTag included to
       
   190                 the returned values
       
   191                 TInt& aStartPos: inout: Start point of parsing
       
   192                 TInt& aEndPos: inout: End point of parsing
       
   193                 TInt& aLength: inout: Length of parsed section
       
   194 
       
   195     Return Values: TInt: Error code
       
   196 
       
   197     Errors/Exceptions: None
       
   198 
       
   199     Status: Proposal
       
   200 
       
   201 -------------------------------------------------------------------------------
       
   202 */
       
   203 TInt CStifSectionParser::ParseStartAndEndPos( TPtrC aSection,
       
   204                                             const TDesC& aStartTag,
       
   205                                             TTagToReturnValue aTagIndicator,
       
   206                                             TInt& aStartPos,
       
   207                                             TInt& aEndPos,
       
   208                                             TInt& aLength )
       
   209     {
       
   210     TLex lex( aSection );
       
   211     lex.SkipAndMark( iSkipAndMarkPos );
       
   212 
       
   213     // Check is aStartTag given
       
   214     if ( aStartTag.Length() == 0 )
       
   215         {
       
   216         // Skip line break, tabs, spaces etc.
       
   217         lex.SkipSpace();
       
   218         aStartPos = lex.Offset();
       
   219         }
       
   220     else
       
   221         {
       
   222         // While end of section and aStartTag is given
       
   223         while ( !lex.Eos() )
       
   224             {
       
   225             lex.SkipSpace();
       
   226             TPtrC line = SubstractLine( lex.Remainder() );
       
   227             TInt tagStartPos = 0;
       
   228             TInt tagEndPos = 0;
       
   229             if ( FindTag( line, aStartTag, tagStartPos, tagEndPos ) == KErrNone )
       
   230             	{
       
   231             	if ( aTagIndicator == ETag )
       
   232             		{
       
   233             		aStartPos = lex.Offset();
       
   234             		}
       
   235             	else
       
   236             		{
       
   237             		aStartPos = lex.Offset() + tagEndPos;
       
   238             		if ( line.Length() - tagEndPos == 0 )
       
   239             			{
       
   240             			return KErrNotFound;
       
   241             			}
       
   242             		}
       
   243             	break;
       
   244             	}
       
   245                 
       
   246             GotoEndOfLine( lex );
       
   247             }
       
   248         }
       
   249 
       
   250     // End tag parsing starts and if we are end of the section
       
   251     if( lex.Eos() )
       
   252         {
       
   253         return KErrNotFound;
       
   254         }
       
   255 
       
   256     // "Delete" white spaces(includes line break) 
       
   257     aEndPos = GotoEndOfLine( lex );
       
   258     // Position where start next parsing.(End position, includes white spaces)
       
   259     iSkipAndMarkPos = lex.Offset();
       
   260     // The length includes spaces and end of lines
       
   261     aLength = ( aEndPos - aStartPos );
       
   262 
       
   263     return KErrNone;
       
   264 
       
   265     }
       
   266 
       
   267 /*
       
   268 -------------------------------------------------------------------------------
       
   269 
       
   270     Class: CStifSectionParser
       
   271 
       
   272     Method: SubstractLine
       
   273 
       
   274     Description: Substracts line from selected text
       
   275 
       
   276     Parameters: TPtrC& aText: in: text.
       
   277 
       
   278     Return Values: TPtrC: Substracted line.
       
   279 
       
   280     Errors/Exceptions: None
       
   281 
       
   282     Status: Proposal
       
   283 
       
   284 -------------------------------------------------------------------------------
       
   285 */
       
   286 TPtrC CStifSectionParser::SubstractLine( const TPtrC& aText )
       
   287 	{
       
   288 	TLex lex( aText );
       
   289 	
       
   290 	while( !lex.Eos() )
       
   291 		{
       
   292 		if ( lex.Get() == 0x0A ) // "\n" character. Unix style
       
   293 			{
       
   294 			break;
       
   295 			}		
       
   296 		}
       
   297 	
       
   298 	return aText.Left( lex.Offset() );
       
   299 	}
       
   300 
       
   301 /*
       
   302 -------------------------------------------------------------------------------
       
   303 
       
   304     Class: CStifSectionParser
       
   305 
       
   306     Method: FindTag
       
   307 
       
   308     Description: Searches for selected tag in text
       
   309 
       
   310     Parameters: const TPtrC& aText: in: text,
       
   311 				const TPtrC& aTag: in: tag,
       
   312 				TInt& aStartPos: out: tag start position,
       
   313 				TInt& aEndPos: out: tag end position.
       
   314 
       
   315     Return Values: TInt: KErrNone, if tag was found. KErrNotFound if it was not found. 
       
   316 
       
   317     Errors/Exceptions: None
       
   318 
       
   319     Status: Proposal
       
   320 
       
   321 -------------------------------------------------------------------------------
       
   322 */
       
   323 TInt CStifSectionParser::FindTag( const TDesC& aText, const TDesC& aTag, TInt& aStartPos, TInt& aEndPos ) {
       
   324 	TBool tagWithEqualChar = EFalse;
       
   325 
       
   326 	HBufC* tagBuf = NULL;
       
   327 	TRAPD( err, tagBuf = aTag.AllocL() );
       
   328 	if ( err != KErrNone )
       
   329 		{
       
   330 		return err;
       
   331 		}
       
   332 
       
   333 	RBuf tag( tagBuf );
       
   334 	tag.Trim();
       
   335 	if ( tag.Right( 1 ) == _L("=") )
       
   336 		{
       
   337 		tagWithEqualChar = ETrue;
       
   338 		tag.SetLength( tag.Length() - 1 );
       
   339 		}
       
   340 	
       
   341 	TLex lex(aText);
       
   342 	lex.SkipSpaceAndMark();
       
   343 	TInt startPos = lex.Offset();
       
   344 	TPtrC token = lex.NextToken(); 
       
   345 	
       
   346 	
       
   347 	if ( !tagWithEqualChar )
       
   348 		{
       
   349 		if ( token == tag )
       
   350 			{
       
   351 			aStartPos = startPos;
       
   352 			lex.SkipSpace();
       
   353 			aEndPos = lex.Offset();
       
   354 			tag.Close();
       
   355 			return KErrNone;
       
   356 			}
       
   357 		}
       
   358 	else
       
   359 		{
       
   360 		lex.UnGetToMark();
       
   361 		TPtrC remText = lex.Remainder();
       
   362 		if ( remText.Find( tag ) == 0 )
       
   363 			{
       
   364 			lex.SkipAndMark( tag.Length() );
       
   365 			lex.SkipSpaceAndMark();
       
   366 			if ( !lex.Eos() )
       
   367 				{
       
   368 				if ( lex.Get() == '=' )
       
   369 					{
       
   370 					aStartPos = startPos;
       
   371 					lex.SkipSpace();					
       
   372 					aEndPos = lex.Offset();
       
   373 					tag.Close();
       
   374 					return KErrNone;
       
   375 					}
       
   376 				}
       
   377 			}
       
   378 		}
       
   379 	
       
   380 	tag.Close();
       
   381 	return KErrNotFound;
       
   382 }
       
   383 
       
   384 /*
       
   385 -------------------------------------------------------------------------------
       
   386 
       
   387     Class: CStifSectionParser
       
   388 
       
   389     Method: GotoEndOfLine
       
   390 
       
   391     Description: Goes end of the line.
       
   392 
       
   393     Parameters: TLex& lex: inout: Parsed line.
       
   394 
       
   395     Return Values: TInt: Last item's end position.
       
   396 
       
   397     Errors/Exceptions: None
       
   398 
       
   399     Status: Proposal
       
   400 
       
   401 -------------------------------------------------------------------------------
       
   402 */
       
   403 TInt CStifSectionParser::GotoEndOfLine( TLex& lex )
       
   404     {
       
   405     // End position of the last token(Initialized with current position)
       
   406     TInt lastItemPosition( lex.Offset() );
       
   407 
       
   408     // LINE BREAK NOTE:
       
   409     // Line break in SOS, WIN:  '\r\n'
       
   410     // Line break in UNIX:      '\n'
       
   411 
       
   412     do
       
   413         {
       
   414         // Peek next character(10 or '\n' in UNIX style )
       
   415         if( lex.Peek() == 0x0A )
       
   416             {
       
   417             lex.Inc();
       
   418             break;
       
   419             }
       
   420 
       
   421         // Peek next character(13 or '\r' in Symbian OS)
       
   422         if ( lex.Peek() == 0x0D )
       
   423             {
       
   424             // Increment the lex position
       
   425             lex.Inc();
       
   426             // Peek next character(10 or '\n' in Symbian OS)
       
   427             if ( lex.Peek() == 0x0A )
       
   428                 {
       
   429                 // End of the section is found and increment the lex position
       
   430                 lex.Inc();
       
   431                 break;
       
   432                 }
       
   433             // 0x0A not found, decrement position
       
   434             lex.UnGet();
       
   435             }
       
   436         // Peek for tabulator(0x09) and space(0x20)
       
   437         else if ( lex.Peek() == 0x09 || lex.Peek() == 0x20 )
       
   438             {
       
   439             // Increment the lex position
       
   440             lex.Inc();
       
   441             continue;
       
   442             }
       
   443         
       
   444         // If white spaces not found take next token
       
   445         lex.NextToken();
       
   446         lastItemPosition = lex.Offset();    
       
   447         
       
   448         } while ( !lex.Eos() );
       
   449         
       
   450     return lastItemPosition;
       
   451 
       
   452     }
       
   453 
       
   454 /*
       
   455 -------------------------------------------------------------------------------
       
   456 
       
   457     Class: CStifSectionParser
       
   458 
       
   459     Method: GetItemLineL
       
   460 
       
   461     Description: Parses a line for items parsing.
       
   462 
       
   463     If start tag is empty the parsing starts beging of the section.
       
   464 
       
   465     Parameters: const TDesC& aTag: in: Indicates parsing start point.
       
   466                 TTagToReturnValue aTagIndicator: in: Will aTag included to the
       
   467                 returned object(For default the tag will be added)
       
   468 
       
   469     Return Values:  CStifItemParser* : pointer to CStifItemParser object
       
   470                     NULL will return if ParseStartAndEndPos() method returns -1
       
   471                     NULL will return if length is 0 or negative
       
   472                     NULL will return if iStartPos is 0
       
   473 
       
   474     Errors/Exceptions: Leaves if called CStifItemParser::NewL method fails
       
   475 
       
   476     Status: Approved
       
   477 
       
   478 -------------------------------------------------------------------------------
       
   479 */
       
   480 EXPORT_C CStifItemParser* CStifSectionParser::GetItemLineL( const TDesC& aTag,
       
   481                                             TTagToReturnValue aTagIndicator )
       
   482     {
       
   483     TInt startPos( 0 );
       
   484     TInt endPos( 0 );
       
   485     TInt length( 0 );
       
   486 
       
   487     // Indicator that GetItemLineL has been used
       
   488     iLineIndicator = ETrue;
       
   489 
       
   490     iSkipAndMarkPos = 0;
       
   491 
       
   492     TInt ret = ParseStartAndEndPos( iSection, aTag, aTagIndicator,
       
   493                                     startPos, endPos, length );
       
   494 
       
   495     // No parsing found
       
   496     if ( KErrNone != ret || length <= 0 || startPos < 0 )
       
   497         {
       
   498         __TRACE( 
       
   499             KInfo, ( _L( "STIFPARSER: GetItemLineL method returns a NULL" ) ) );
       
   500         return NULL;
       
   501         }
       
   502 
       
   503     CStifItemParser* line = CStifItemParser::NewL(
       
   504                                             iSection, startPos, length );
       
   505 
       
   506     return line;
       
   507 
       
   508     }
       
   509 
       
   510 /*
       
   511 -------------------------------------------------------------------------------
       
   512 
       
   513     Class: CStifSectionParser
       
   514 
       
   515     Method: GetNextItemLineL
       
   516 
       
   517     Description: Parses a next line for items parsing.
       
   518 
       
   519     Parameters: None
       
   520 
       
   521     Return Values:  CStifItemParser* : pointer to CStifItemParser object
       
   522                     NULL will return if iLineIndicator is false
       
   523                     NULL will return if ParseStartAndEndPos() method returns -1
       
   524                     NULL will return if length is 0 or negative
       
   525                     NULL will return if iStartPos is 0
       
   526 
       
   527     Errors/Exceptions: Leaves if called CStifItemParser::NewL method fails
       
   528 
       
   529     Status: Approved
       
   530 
       
   531 -------------------------------------------------------------------------------
       
   532 */
       
   533 EXPORT_C CStifItemParser* CStifSectionParser::GetNextItemLineL()
       
   534     {
       
   535     // GetLine() or GetItemLineL() method is not called
       
   536     if ( !iLineIndicator )
       
   537         {
       
   538         __TRACE( KInfo, 
       
   539             ( _L( "STIFPARSER: GetNextItemLineL method returns a NULL" ) ) );
       
   540         return NULL;
       
   541         }
       
   542 
       
   543     TInt startPos( 0 );
       
   544     TInt endPos( 0 );
       
   545     TInt length( 0 );
       
   546 
       
   547     // tagIndicator has no meaning in this method
       
   548     TTagToReturnValue tagIndicator( ETag );
       
   549 
       
   550     TInt ret = ParseStartAndEndPos( iSection, KNullDesC, tagIndicator,
       
   551                                     startPos, endPos, length );
       
   552 
       
   553     // No parsing found
       
   554     if ( KErrNone != ret || length <= 0 || startPos < 0 )
       
   555         {
       
   556         __TRACE( KInfo, 
       
   557             ( _L( "STIFPARSER: GetNextItemLineL method returns a NULL" ) ) );
       
   558         return NULL;
       
   559         }
       
   560 
       
   561     CStifItemParser* line = CStifItemParser::NewL(
       
   562                                             iSection, startPos, length );
       
   563 
       
   564     return line;
       
   565 
       
   566     }
       
   567 
       
   568 /*
       
   569 -------------------------------------------------------------------------------
       
   570 
       
   571     Class: CStifSectionParser
       
   572 
       
   573     Method: GetNextItemLineL
       
   574 
       
   575     Description: Parses a next line for items parsing with a tag.
       
   576 
       
   577     If start tag is empty the parsing starts beging of the section.
       
   578 
       
   579     Parameters: const TDesC& aTag: in: Indicates parsing start point
       
   580                 TTagToReturnValue aTagIndicator: in: Will aTag included to the
       
   581                 returned object(For default the tag will be added)
       
   582 
       
   583     Return Values:  CStifItemParser* : pointer to CStifItemParser object
       
   584                     NULL will return if iLineIndicator is false
       
   585                     NULL will return if ParseStartAndEndPos() method returns -1
       
   586                     NULL will return if length is 0 or negative
       
   587                     NULL will return if iStartPos is 0
       
   588 
       
   589     Errors/Exceptions: Leaves if called CStifItemParser::NewL method fails
       
   590 
       
   591     Status: Approved
       
   592 
       
   593 -------------------------------------------------------------------------------
       
   594 */
       
   595 EXPORT_C CStifItemParser* CStifSectionParser::GetNextItemLineL(
       
   596                                             const TDesC& aTag,
       
   597                                             TTagToReturnValue aTagIndicator )
       
   598     {
       
   599     // GetLine() or GetItemLineL() method is not called
       
   600     if ( !iLineIndicator )
       
   601         {
       
   602         __TRACE( KInfo, 
       
   603             ( _L( "STIFPARSER: GetNextItemLineL method returns a NULL" ) ) );
       
   604         return NULL;
       
   605         }
       
   606 
       
   607     TInt startPos( 0 );
       
   608     TInt endPos( 0 );
       
   609     TInt length( 0 );
       
   610 
       
   611     TInt ret = ParseStartAndEndPos( iSection, aTag, aTagIndicator,
       
   612                                     startPos, endPos, length );
       
   613     // No parsing found
       
   614     if ( KErrNone != ret || length <= 0 || startPos < 0 )
       
   615         {
       
   616         __TRACE( KInfo, 
       
   617             ( _L( "STIFPARSER: GetNextItemLineL method returns a NULL" )  ) );
       
   618         return NULL;
       
   619         }
       
   620 
       
   621     CStifItemParser* line = CStifItemParser::NewL(
       
   622                                             iSection, startPos, length );
       
   623 
       
   624     return line;
       
   625 
       
   626     }
       
   627 
       
   628 /*
       
   629 -------------------------------------------------------------------------------
       
   630 
       
   631     Class: CStifSectionParser
       
   632 
       
   633     Method: SubSectionL
       
   634 
       
   635     Description: Parses sub sections from the main section.
       
   636 
       
   637     If start tag is empty the parsing starts begin of the section.
       
   638     If end tag is empty the parsing goes end of section.
       
   639     This method starts always from beginning of parsed section and parses
       
   640     first subsection if aSeeked parameters is not given.
       
   641     If parsed section includes several subsections with both start and end
       
   642     tags so aSeeked parameter seeks the required subsection. The aSeeked
       
   643     parameters indicates subsection that will be parsed.
       
   644 
       
   645     Parameters: const TDesC& aStartTag: in: Indicates parsing start point
       
   646                 const TDesC& aEndTag: in: Indicates parsing end point
       
   647                 TInt aSeeked: in: a seeked subsection which will be parsed
       
   648 
       
   649     Return Values:  CStifItemParser* : pointer to CStifItemParser object
       
   650                     NULL will return if end tag is not found
       
   651                     NULL will return if length is 0 or negative
       
   652                     NULL will return if lengthStart is 0
       
   653 
       
   654     Errors/Exceptions: Leaves if called CStifSectionParser::NewL method fails
       
   655 
       
   656     Status: Proposal
       
   657 
       
   658 -------------------------------------------------------------------------------
       
   659 */
       
   660 EXPORT_C CStifSectionParser* CStifSectionParser::SubSectionL( 
       
   661                                                         const TDesC& aStartTag,
       
   662                                                         const TDesC& aEndTag,
       
   663                                                         TInt aSeeked )
       
   664     {
       
   665     
       
   666     iSubOffset = 0;
       
   667     return NextSubSectionL( aStartTag, aEndTag, aSeeked );
       
   668 
       
   669     }
       
   670 
       
   671 /*
       
   672 -------------------------------------------------------------------------------
       
   673 
       
   674     Class: CStifSectionParser
       
   675 
       
   676     Method: SubSectionL
       
   677 
       
   678     Description: Parses subsections from the main section.
       
   679 
       
   680     If start tag is empty the parsing starts begin of the section.
       
   681     If end tag is empty the parsing goes end of section.
       
   682     This method will parse next subsection after the earlier subsection if
       
   683     aSeeked parameter is not given.
       
   684     If parser section includes several subsections with both start and end
       
   685     tags so aSeeked parameter seeks the required subsection. The aSeeked
       
   686     parameter indicates subsection that will be parsed.
       
   687 
       
   688     Parameters: const TDesC& aStartTag: in: Indicates parsing start point
       
   689                 const TDesC& aEndTag: in: Indicates parsing end point
       
   690                 TInt aSeeked: in: a seeked subsection which will be parsed
       
   691 
       
   692     Return Values:  CStifItemParser* : pointer to CStifItemParser object
       
   693                     NULL will return if end tag is not found
       
   694                     NULL will return if length is 0 or negative
       
   695                     NULL will return if lengthStart is 0
       
   696 
       
   697     Errors/Exceptions: Leaves if called CStifSectionParser::NewL method fails
       
   698 
       
   699     Status: Proposal
       
   700 
       
   701 -------------------------------------------------------------------------------
       
   702 */
       
   703 EXPORT_C CStifSectionParser* CStifSectionParser::NextSubSectionL( 
       
   704                                                     const TDesC& aStartTag,
       
   705                                                     const TDesC& aEndTag,
       
   706                                                     TInt aSeeked )
       
   707     {
       
   708     
       
   709     TLex lex( iSection );
       
   710 
       
   711     lex.SkipAndMark( iSubOffset );
       
   712 
       
   713     // Get the required sub section length
       
   714     TInt length( 0 );
       
   715     TInt lengthStartPos( 0 );
       
   716     TInt lengthEndPos( 0 );
       
   717     TBool eos( EFalse );
       
   718     TInt tagCount( 1 );
       
   719 
       
   720     // Check is aStartTag given
       
   721     if ( aStartTag.Length() == 0 )
       
   722         {
       
   723         // Skip line break, tabs, spaces etc.
       
   724         lex.SkipSpace();
       
   725         lengthStartPos = lex.Offset();
       
   726         }
       
   727     else
       
   728         {
       
   729         // While end of section and aStartTag is given
       
   730         while ( !lex.Eos() )
       
   731             {
       
   732             TPtrC ptr = lex.NextToken();
       
   733             // Start of the section is found and correct section
       
   734             if ( ptr == aStartTag && tagCount == aSeeked )
       
   735                 {
       
   736                 // Start position
       
   737                 lengthStartPos = lex.Offset();
       
   738                 break;
       
   739                 }
       
   740             // Start tag is found but not correct section
       
   741             else if ( ptr == aStartTag )
       
   742                 {
       
   743                 tagCount++;
       
   744                 }
       
   745             }
       
   746         }
       
   747 
       
   748     // If we are end of section lex.Eos() and eos will be ETrue
       
   749     eos = lex.Eos();
       
   750 
       
   751     // Seeked section is not found
       
   752     if ( tagCount != aSeeked )
       
   753         {
       
   754         __TRACE( KInfo, ( _L( "STIFPARSER: NextSubSectionL method: Seeked subsection is not found" ) ) );
       
   755         User::Leave( KErrNotFound );
       
   756         }
       
   757 
       
   758     // Check is aEndTag given
       
   759     if ( aEndTag.Length() == 0 )
       
   760         {
       
   761         lengthEndPos = iSection.MaxLength();
       
   762         }
       
   763     else
       
   764         {
       
   765         // While end of section and aEndTag is given
       
   766         while ( !lex.Eos() )
       
   767             {
       
   768             TPtrC ptr = lex.NextToken();
       
   769             // End tag of the section is found
       
   770             if ( ptr == aEndTag )
       
   771                 {
       
   772                 // End position
       
   773                 lengthEndPos = lex.Offset();
       
   774                 // Because Offset() position is after the aEndTag
       
   775                 lengthEndPos -= aEndTag.Length();
       
   776                 break;
       
   777                 }
       
   778             }
       
   779         }
       
   780 
       
   781     // If we are end of section and lengthEndPos is 0
       
   782     if ( lengthEndPos == 0 )
       
   783         {
       
   784         // lex.Eos() and eos will be ETrue
       
   785         eos = lex.Eos();
       
   786         }
       
   787 
       
   788     // The length includes spaces and end of lines
       
   789     length = ( lengthEndPos - lengthStartPos );
       
   790 
       
   791     CStifSectionParser* section = NULL;
       
   792 
       
   793     // If eos is true or length is negative
       
   794     if ( eos || length <= 0  ) 
       
   795         {
       
   796         __TRACE( KInfo, 
       
   797             ( _L( "STIFPARSER: SubSectionL method returns a NULL" ) ) );
       
   798         }    
       
   799     else
       
   800         {
       
   801         // Position where start next parsing.(End position,
       
   802         // includes white spaces)
       
   803         iSubOffset = lex.Offset();
       
   804         
       
   805         // Make CStifSectionParser object and alloc required length
       
   806         section = CStifSectionParser::NewL( length );
       
   807         CleanupStack::PushL( section );
       
   808 
       
   809         // Copy required data to the section object
       
   810         section->SetData( iSection, lengthStartPos, length );
       
   811 
       
   812         CleanupStack::Pop( section );
       
   813         }
       
   814 
       
   815     return section;
       
   816 
       
   817     }
       
   818 
       
   819 /*
       
   820 -------------------------------------------------------------------------------
       
   821 
       
   822     Class: CStifSectionParser
       
   823 
       
   824     Method: GetLine
       
   825 
       
   826     Description: Get a line.
       
   827 
       
   828     Search an item from the section and return rest of the line. If start tag 
       
   829     is empty the parsing starts beging of the section.
       
   830 
       
   831     Parameters: const TDesC& aTag: in: Indicates parsing start point
       
   832                 TPtr& aLine: inout: Parsed line
       
   833                 TTagToReturnValue aTagIndicator: in: Will aTag included to the
       
   834                 returned value(For default the tag will be added)
       
   835 
       
   836     Return Values: TInt: Error code
       
   837 
       
   838     Errors/Exceptions: None
       
   839 
       
   840     Status: Approved
       
   841 
       
   842 -------------------------------------------------------------------------------
       
   843 */
       
   844 EXPORT_C TInt CStifSectionParser::GetLine( const TDesC& aTag,
       
   845                                             TPtrC& aLine,
       
   846                                             TTagToReturnValue aTagIndicator )
       
   847     {
       
   848     TInt ret( KErrNone );
       
   849 
       
   850     if ( 0 == iSection.Length() )
       
   851         {
       
   852         return KErrNotFound;
       
   853         }
       
   854 
       
   855     // Indicator that GetLine has been used
       
   856     iLineIndicator = ETrue;
       
   857 
       
   858     TInt startPos( 0 );
       
   859     TInt endPos( 0 );
       
   860     TInt length( 0 );
       
   861 
       
   862     iSkipAndMarkPos = 0;
       
   863 
       
   864     ret = ParseStartAndEndPos( iSection, aTag, aTagIndicator,
       
   865                                 startPos, endPos, length );
       
   866 
       
   867     if ( KErrNone != ret )
       
   868         {
       
   869         // Nothing to parse
       
   870         return ret;
       
   871         }
       
   872 
       
   873     aLine.Set( &iSection[startPos], length );
       
   874 
       
   875     return KErrNone;
       
   876 
       
   877     }
       
   878 
       
   879 /*
       
   880 -------------------------------------------------------------------------------
       
   881 
       
   882     Class: CStifSectionParser
       
   883 
       
   884     Method: GetNextLine
       
   885 
       
   886     Description: Get a line
       
   887 
       
   888     Search an item from the section and return rest of the line.
       
   889 
       
   890     Parameters: TPtr& aLine: inout: Parsed line
       
   891 
       
   892     Return Values: TInt: Error code
       
   893 
       
   894     Errors/Exceptions: None
       
   895 
       
   896     Status: Approved
       
   897 
       
   898 -------------------------------------------------------------------------------
       
   899 */
       
   900 EXPORT_C TInt CStifSectionParser::GetNextLine( TPtrC& aLine )
       
   901     {
       
   902     TInt ret( KErrNone );
       
   903 
       
   904     // GetLine() or GetItemLineL() method is not called
       
   905     if ( !iLineIndicator )
       
   906         {
       
   907         return KErrNotReady;
       
   908         }
       
   909 
       
   910     TInt startPos( 0 );
       
   911     TInt endPos( 0 );
       
   912     TInt length( 0 );
       
   913 
       
   914     // tagIndicator has no meaning in this method
       
   915     TTagToReturnValue tagIndicator( ETag );
       
   916 
       
   917     ret = ParseStartAndEndPos( iSection, KNullDesC, tagIndicator,
       
   918                                 startPos, endPos, length );
       
   919     if ( KErrNone != ret )
       
   920         {
       
   921         // Nothing to parse
       
   922         return ret;
       
   923         }
       
   924 
       
   925     aLine.Set( &iSection[startPos], length );
       
   926 
       
   927     return KErrNone;
       
   928 
       
   929     }
       
   930 
       
   931 /*
       
   932 -------------------------------------------------------------------------------
       
   933 
       
   934     Class: CStifSectionParser
       
   935 
       
   936     Method: GetNextLine
       
   937 
       
   938     Description: Get a line with tag
       
   939 
       
   940     Search a next line with the required tag from the section. If start tag
       
   941     is empty the parsing starts beging of the section.
       
   942 
       
   943     Parameters: const TDesC& aTag: in: Indicates parsing start point
       
   944                 TPtr& aLine: inout: Parsed line
       
   945                 TTagToReturnValue aTagIndicator: in: Will aTag included to the
       
   946                 returned value(For default the tag will be added)
       
   947 
       
   948     Return Values: TInt: Error code
       
   949 
       
   950     Errors/Exceptions: None
       
   951 
       
   952     Status: Approved
       
   953 
       
   954 -------------------------------------------------------------------------------
       
   955 */
       
   956 EXPORT_C TInt CStifSectionParser::GetNextLine( const TDesC& aTag, TPtrC& aLine,
       
   957                                             TTagToReturnValue aTagIndicator )
       
   958     {
       
   959     TInt ret( KErrNone );
       
   960 
       
   961     // GetLine() or GetItemLineL() method is not called
       
   962     if ( !iLineIndicator )
       
   963         {
       
   964         return KErrNotReady;
       
   965         }
       
   966 
       
   967     TInt startPos( 0 );
       
   968     TInt endPos( 0 );
       
   969     TInt length( 0 );
       
   970 
       
   971     ret = ParseStartAndEndPos( iSection, aTag, aTagIndicator,
       
   972                                 startPos, endPos, length );
       
   973     if ( KErrNone != ret )
       
   974         {
       
   975         // Nothing to parse
       
   976         return ret;
       
   977         }
       
   978 
       
   979     aLine.Set( &iSection[startPos], length );
       
   980 
       
   981     return KErrNone;
       
   982 
       
   983     }
       
   984 
       
   985  /*
       
   986 -------------------------------------------------------------------------------
       
   987 
       
   988     Class: CStifSectionParser
       
   989 
       
   990     Method: GetPosition
       
   991 
       
   992     Description: Get current position.
       
   993 
       
   994     Returns current parsing position, which
       
   995     can be used as parameter for SetPosition afterwards to go back
       
   996     to old parsing position.
       
   997 
       
   998     Parameters: None
       
   999     
       
  1000     Return Values: TInt: Current parsing position.
       
  1001 
       
  1002     Errors/Exceptions: None
       
  1003 
       
  1004     Status: Proposal
       
  1005 
       
  1006 -------------------------------------------------------------------------------
       
  1007 */
       
  1008 EXPORT_C TInt CStifSectionParser::GetPosition()
       
  1009     {
       
  1010     
       
  1011     return iSkipAndMarkPos;
       
  1012     
       
  1013     }
       
  1014 
       
  1015 /*
       
  1016 -------------------------------------------------------------------------------
       
  1017 
       
  1018     Class: CStifSectionParser
       
  1019 
       
  1020     Method: SetPosition
       
  1021 
       
  1022     Description: Set current position.
       
  1023                 
       
  1024     SetPosition can be used to set parsing position, e.g. to rewind 
       
  1025     back to some old position retrieved with GetPosition.
       
  1026     
       
  1027     Parameters: TInt aPos: in: new parsing position.
       
  1028     
       
  1029     Return Values: TInt: Error code
       
  1030 
       
  1031     Errors/Exceptions: None
       
  1032 
       
  1033     Status: Proposal
       
  1034 
       
  1035 -------------------------------------------------------------------------------
       
  1036 */
       
  1037 EXPORT_C TInt CStifSectionParser::SetPosition( TInt aPos )  
       
  1038     {
       
  1039     
       
  1040     if( aPos < 0 || aPos >= iSection.Length() )
       
  1041         {
       
  1042         return KErrArgument;
       
  1043         }
       
  1044         
       
  1045     iSkipAndMarkPos = aPos;    
       
  1046     
       
  1047     return KErrNone;
       
  1048     
       
  1049     }        
       
  1050         
       
  1051 /*
       
  1052 -------------------------------------------------------------------------------
       
  1053 
       
  1054     Class: CStifSectionParser
       
  1055 
       
  1056     Method: SetData
       
  1057 
       
  1058     Description: Create a section.
       
  1059 
       
  1060     Parameters: const TPtr aData: in: Data to be parsed
       
  1061                 TInt aStartPos: in: Indicates parsing start position
       
  1062                 TInt aLength: in: Indicates length of parsed section
       
  1063     
       
  1064     Return Values: None
       
  1065 
       
  1066     Errors/Exceptions: None
       
  1067 
       
  1068     Status: Approved
       
  1069     
       
  1070 -------------------------------------------------------------------------------
       
  1071 */
       
  1072 void CStifSectionParser::SetData( TPtr aData,
       
  1073                                     TInt aStartPos,
       
  1074                                     TInt aLength )
       
  1075     {
       
  1076     iSection.Copy( aData.Mid( aStartPos, aLength ) );
       
  1077 
       
  1078     }
       
  1079 
       
  1080 /*
       
  1081 -------------------------------------------------------------------------------
       
  1082 
       
  1083     Class: CStifSectionParser
       
  1084 
       
  1085     Method: Des
       
  1086 
       
  1087     Description: Returns a section.
       
  1088 
       
  1089     Parameters: None
       
  1090 
       
  1091     Return Values: const TPtrC: Returns a current section
       
  1092 
       
  1093     Errors/Exceptions: None
       
  1094 
       
  1095     Status: Approved
       
  1096 
       
  1097 -------------------------------------------------------------------------------
       
  1098 */
       
  1099 const TPtrC CStifSectionParser::Des()
       
  1100     {
       
  1101     return (TPtrC)iSection;
       
  1102 
       
  1103     }
       
  1104 
       
  1105 // ================= OTHER EXPORTED FUNCTIONS =================================
       
  1106 
       
  1107 //  End of File