landmarks/locationlandmarks/converter/src/epos_cposlmurlparser.cpp
changeset 0 667063e416a2
equal deleted inserted replaced
-1:000000000000 0:667063e416a2
       
     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: Class used for parsing a Landmarks URL & obtaining 
       
    15 *							 landmarks information from it.
       
    16 *
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include    <lbsposition.h>
       
    22 #include    <gulutil.h>
       
    23 #include    <uri8.h>
       
    24 #include    <escapeutils.h>
       
    25 #include    <EPos_LandmarksErrors.h>
       
    26 #include    "epos_cposlmurlparser.h"
       
    27 #include    "EPos_CPosLmCategoryManager.h"
       
    28 #include    "EPos_CPosLandmarkDatabase.h"
       
    29 #include    "epos_cposlmurlparseroperation.h"
       
    30 #include    "EPos_PosLmConverterUtils.h"
       
    31 #include    "EPos_PosLmImplExtension.h"
       
    32 #include    "EPos_CPosLandmarkCategory.h"
       
    33 
       
    34 
       
    35 // Constants for formatting the Real numbers
       
    36 const TInt KRealPoint = 46;
       
    37 const TInt KRealDecimalPlaces = 2;
       
    38 const TInt KCoordinateDecimalPlaces = 6;
       
    39 // constants for checking the range of the coordinates
       
    40 const TReal KMinLatitude = -90.0;
       
    41 const TReal KMaxLatitude = 90.0;
       
    42 const TReal KMinLongitude = -180.0;
       
    43 const TReal KMaxLongitude = 180.0;
       
    44 // constants that define the decode buffer length
       
    45 const TInt KDecodeBufferLength = 3;
       
    46 // constants defining the length for the date time buffers
       
    47 const TInt KMaxDateTimeBufferLength = 22;
       
    48 const TInt KMaxMicroSecondsLength = 6;
       
    49 const TInt KMaxDateFieldLength = 8;
       
    50 const TInt KMaxTimeFieldLength = 6;
       
    51 // constants defining the length of the delimeters
       
    52 const TInt KHostDelimeterLength = 3;
       
    53 const TInt KQueryStartDelimeterLength = 2;
       
    54 const TInt KLocationDelimeterLength = 2;
       
    55 const TInt KParameterDelimeterLength = 1;
       
    56 // constants defining length of chunk size
       
    57 const TInt KMaxChunkSize = 5012;
       
    58 
       
    59 
       
    60 // ============================ MEMBER FUNCTIONS ===============================
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CPosLmUrlParser::CPosLmUrlParser
       
    64 // Default Constructor
       
    65 //-----------------------------------------------------------------------------
       
    66 //
       
    67 CPosLmUrlParser::CPosLmUrlParser()
       
    68     {
       
    69     // initialize the TRealFormat variable for latitude & longitude formatting
       
    70     iRealFormatCoordinates.iPoint = KRealPoint;
       
    71     iRealFormatCoordinates.iType = KRealFormatFixed | KDoNotUseTriads;
       
    72     iRealFormatCoordinates.iPlaces = KCoordinateDecimalPlaces;
       
    73     iRealFormatCoordinates.iWidth = KRealWidth;
       
    74  
       
    75     // initialize the TRealFormat variable for formatting other real32 numbers
       
    76     iRealFormat.iPoint = KRealPoint;
       
    77     iRealFormat.iType = KRealFormatFixed | KDoNotUseTriads;
       
    78     iRealFormat.iPlaces = KRealDecimalPlaces;
       
    79     iRealFormat.iWidth = KRealWidth;
       
    80     
       
    81     ResetUrlParameters();
       
    82     }
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CPosLmUrlParser::NewL
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 CPosLmUrlParser* CPosLmUrlParser::NewL()
       
    89     {
       
    90     return  new (ELeave) CPosLmUrlParser;
       
    91     }
       
    92 // -----------------------------------------------------------------------------
       
    93 // CPosLmUrlParser::~CPosLmUrlParser 
       
    94 // Destructor
       
    95 //-----------------------------------------------------------------------------
       
    96 //
       
    97 CPosLmUrlParser::~CPosLmUrlParser()
       
    98     {
       
    99     ResetUrlParser();
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CPosLmUrlParser::SetInputBuffer 
       
   104 // 
       
   105 //-----------------------------------------------------------------------------
       
   106 //
       
   107 void CPosLmUrlParser::SetInputBuffer( const TDesC8&  aBuffer )
       
   108     {
       
   109     // Reset the parser first,so as to start parsing freshly
       
   110     ResetUrlParser();
       
   111     // Set the input buffer
       
   112     iInputBuffer.Set( aBuffer );
       
   113 
       
   114     // Set size of input buffer
       
   115     iContentSize = iInputBuffer.Length();
       
   116     
       
   117     // Change parser status to EStateInitialized
       
   118     iParserStatus = EStateInitialized;
       
   119     
       
   120     }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CPosLmUrlParser::SetInputFileL 
       
   124 // 
       
   125 //-----------------------------------------------------------------------------
       
   126 //
       
   127 void CPosLmUrlParser::SetInputFileL( const TDesC&  aFile )
       
   128     {
       
   129     // Reset the parser first,so as to start parsing freshly
       
   130     ResetUrlParser();
       
   131     // Connect to the file server
       
   132     User::LeaveIfError( iFs.Connect() );
       
   133     // Open the file in the read only mode
       
   134     User::LeaveIfError( iFile.Open( iFs, aFile,
       
   135             EFileShareReadersOnly | EFileRead ) );
       
   136     // Set the file handle
       
   137     iFileHandle = &iFile;
       
   138     // Set the file content size
       
   139     User::LeaveIfError( iFileHandle->Size( iContentSize ) );
       
   140     // Change parser status to EStateInitialized
       
   141     iParserStatus = EStateInitialized;
       
   142     
       
   143     
       
   144     }
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CPosLmUrlParser::SetInputFileHandleL 
       
   148 // 
       
   149 //-----------------------------------------------------------------------------
       
   150 //
       
   151 void CPosLmUrlParser::SetInputFileHandleL( RFile&  aFileHandle )
       
   152     {
       
   153     // Reset the parser first,so as to start parsing freshly
       
   154     ResetUrlParser();
       
   155     // set the file handle
       
   156     iFileHandle = &aFileHandle;
       
   157     // Set the file content size
       
   158     User::LeaveIfError( iFileHandle->Size( iContentSize ) );
       
   159     // Change parser status to EStateInitialized
       
   160     iParserStatus = EStateInitialized;
       
   161     
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // CPosLmUrlParser::ParseContentL 
       
   166 // 
       
   167 //-----------------------------------------------------------------------------
       
   168 //
       
   169 CPosLmOperation* CPosLmUrlParser::ParseContentL( TBool  aBuildIndex )
       
   170     {
       
   171     // Check that the parser status is EStateInitialized when this method is called,
       
   172     // if not panic with EPosLmProtocolBreak
       
   173     __ASSERT_ALWAYS( iParserStatus == EStateInitialized,
       
   174             Panic( KPosLandmarksClientPanic, EPosLmProtocolBreak ) );
       
   175     
       
   176     // Build index not supported ,hence leave with KErrNotSupported if specified
       
   177     if( aBuildIndex )
       
   178         {
       
   179         User::Leave( KErrNotSupported );
       
   180         }
       
   181     // Reset the url parameters
       
   182     ResetUrlParameters();
       
   183     
       
   184     // Delete any previous operation
       
   185     DisconnectUrlOperation();
       
   186     
       
   187     // Create a new instance of the operation class to be returned
       
   188     iUrlParserOp = CPosLmUrlParserOperation::NewL( *this );
       
   189     
       
   190     // change the parser status to EStateOperationCreated
       
   191     iParserStatus = EStateOperationCreated;
       
   192     
       
   193     return iUrlParserOp;
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CPosLmUrlParser::NumOfParsedLandmarks 
       
   198 // 
       
   199 //-----------------------------------------------------------------------------
       
   200 //
       
   201 TUint32 CPosLmUrlParser::NumOfParsedLandmarks() const
       
   202     {
       
   203     return iNumOfParsedLandmarks;
       
   204     }
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CPosLmUrlParser::FirstCollectionDataId 
       
   208 // 
       
   209 //-----------------------------------------------------------------------------
       
   210 //
       
   211 TPosLmCollectionDataId CPosLmUrlParser::FirstCollectionDataId() const
       
   212     {
       
   213     // Do nothing,as collection data is not supported in url parsing
       
   214     return EPosLmCollDataNone;
       
   215     }
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 // CPosLmUrlParser::NextCollectionDataId 
       
   219 // 
       
   220 //-----------------------------------------------------------------------------
       
   221 //
       
   222 TPosLmCollectionDataId CPosLmUrlParser::NextCollectionDataId( 
       
   223                        TPosLmCollectionDataId  /*aCollectionDataId*/ ) const
       
   224     {
       
   225     // Do nothing,as collection data is not supported in url parsing
       
   226     return EPosLmCollDataNone;                   
       
   227     }
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // CPosLmUrlParser::CollectionData 
       
   231 // 
       
   232 //-----------------------------------------------------------------------------
       
   233 //
       
   234 TPtrC CPosLmUrlParser::CollectionData( TPosLmCollectionDataId  /*aDataId*/ ) const
       
   235     {
       
   236     // Do nothing,as collection data is not supported in url parsing
       
   237     TPtrC nullDescriptor( KNullDesC );
       
   238     return nullDescriptor;
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CPosLmUrlParser::LandmarkLC 
       
   243 // 
       
   244 //-----------------------------------------------------------------------------
       
   245 //
       
   246 CPosLandmark* CPosLmUrlParser::LandmarkLC( TUint aLandmarkIndex ) const
       
   247     {
       
   248     // Check that index passed always equal to KPosLastParsedLandmark
       
   249     // or less than the number of parsed landmarks but not negative
       
   250     __ASSERT_ALWAYS(
       
   251             aLandmarkIndex < iNumOfParsedLandmarks ||aLandmarkIndex == KPosLastParsedLandmark,
       
   252             Panic( KPosLandmarksClientPanic, EPosInvalidIndex ) );
       
   253 
       
   254     // Check if there are any parsed landmarks before returning the landmark,
       
   255     // else return KErrNotFound
       
   256     if( !iNumOfParsedLandmarks )
       
   257         {
       
   258         User::Leave( KErrNotFound );
       
   259         }
       
   260     
       
   261     return CPosLandmark::NewLC( *iParsedLandmark );
       
   262     }
       
   263 
       
   264 // -----------------------------------------------------------------------------
       
   265 // CPosLmUrlParser::LandmarkCategoryLC 
       
   266 // 
       
   267 //-----------------------------------------------------------------------------
       
   268 //
       
   269 CPosLandmarkCategory* CPosLmUrlParser::LandmarkCategoryLC( TPosLmItemId  
       
   270                                                            aCategoryId  ) const
       
   271     {
       
   272     // indicates whether the category with the id specified is found or not
       
   273     TBool found = EFalse;
       
   274     TInt i = 0;
       
   275     // check that there is a parsed landmark before getting any categories associated
       
   276     // with it,else leave with KErrNotFound
       
   277     if( !iNumOfParsedLandmarks )
       
   278         {
       
   279         User::Leave( KErrNotFound );
       
   280         }
       
   281     // check that categories exist for the parsed landmark,else leave with KErrNotFound
       
   282     if( !iParsedCategories.Count() )
       
   283         {
       
   284         User::Leave( KErrNotFound );
       
   285         }
       
   286     else
       
   287         {
       
   288         // Find the category with the id provided ,from the parsed categories,if not found 
       
   289         // leave with KErrNotFound
       
   290         for(  i=0; i<iParsedCategories.Count();i++ )  
       
   291             {
       
   292             if( iParsedCategories[i]->CategoryId() ==  aCategoryId )
       
   293                 {
       
   294                 found = ETrue;
       
   295                 break;
       
   296                 }
       
   297             }
       
   298         if( !found )
       
   299             {
       
   300             User::Leave( KErrNotFound );
       
   301             }
       
   302         }
       
   303     return CPosLandmarkCategory::NewLC( *iParsedCategories[i] );
       
   304     }
       
   305 
       
   306 // -----------------------------------------------------------------------------
       
   307 // CPosLmUrlParser::ResetUrlParser 
       
   308 // 
       
   309 //-----------------------------------------------------------------------------
       
   310 //
       
   311 void CPosLmUrlParser::ResetUrlParser()
       
   312     {
       
   313     // set input buffer to NULL
       
   314     iInputBuffer.Set( NULL, 0 );
       
   315     // if any filehandle exists,close it 
       
   316     if( iFileHandle )
       
   317         {
       
   318         iFileHandle = NULL;
       
   319         iFile.Close();
       
   320         iFs.Close();
       
   321         // delete the file buffer
       
   322         delete iFileReadBuffer;
       
   323         iFileReadBuffer = NULL;
       
   324         }
       
   325     // delete the previously parsed landmark
       
   326     if( iParsedLandmark )
       
   327         {
       
   328         delete iParsedLandmark;
       
   329         iParsedLandmark = NULL;
       
   330         }
       
   331     // reset the number of parsed landmarks to 0
       
   332     iNumOfParsedLandmarks = 0;
       
   333     // reset the categories array
       
   334     iParsedCategories.ResetAndDestroy();
       
   335     // Reset the parser status to EStateUnitialized
       
   336     iParserStatus = EStateUnitialized;
       
   337     
       
   338     }
       
   339 
       
   340 // -----------------------------------------------------------------------------
       
   341 // CPosLmUrlParser::DisconnectUrlOperation 
       
   342 // -----------------------------------------------------------------------------
       
   343 //
       
   344 void CPosLmUrlParser::DisconnectUrlOperation()
       
   345     {
       
   346     if ( iUrlParserOp )
       
   347         {
       
   348         iUrlParserOp->DisconnectUrlParser();
       
   349         iUrlParserOp = NULL;
       
   350         }
       
   351     }
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CPosLmUrlParser::UrlOperationDestroyed
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 void CPosLmUrlParser::UrlOperationDestroyed()
       
   358     {
       
   359     iUrlParserOp = NULL;
       
   360     }
       
   361 
       
   362 // -----------------------------------------------------------------------------
       
   363 // CPosLmUrlParser::ParseUrlL
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 TInt CPosLmUrlParser::ParseUrlL()
       
   367     {
       
   368     TInt status = KPosLmOperationNotComplete;
       
   369     // Set the chunk size to be read from the file
       
   370     iChunkSize = iContentSize < KMaxChunkSize ? iContentSize : KMaxChunkSize;
       
   371 
       
   372     // Create instance of CPosLandmark to hold the parsed info
       
   373     iParsedLandmark = CPosLandmark::NewL();
       
   374     
       
   375     // Check on the parser status,if the status is EStateParsingPending
       
   376     // then continue with parsing the next location info
       
   377     if( iParserStatus == EStateParsingPending )
       
   378         {
       
   379         // Parse the next location info
       
   380         ParseUrlLocationL();
       
   381         // Now check the parsing status to confirm if its complete,if 
       
   382         // yes change the status to KErrNone
       
   383         if( iParserStatus == EStateParsingComplete )
       
   384             {
       
   385             status = KErrNone;
       
   386             }
       
   387         }
       
   388     else
       
   389         {
       
   390         // start parsing afresh by setting the input buffer/file
       
   391         // Check if the input is through a buffer or file
       
   392         if( iInputBuffer.Ptr() )
       
   393             {
       
   394             ParseBufferL( iInputBuffer );
       
   395             }
       
   396         else
       
   397             {
       
   398             // for file parsing read the file in parts & parse the chunks
       
   399             while(iSeek < iContentSize)
       
   400                 {
       
   401                 iFileReadBuffer = HBufC8::NewL( iChunkSize );
       
   402                 TPtr8 fileReadBufferPtr = iFileReadBuffer->Des();
       
   403                 User::LeaveIfError( iFileHandle->Read( iSeek, fileReadBufferPtr, iChunkSize ) );
       
   404                 ParseBufferL( iFileReadBuffer->Des() );
       
   405                 }
       
   406             }
       
   407         // Check on the parser status to set the status 
       
   408         if( iParserStatus == EStateParsingComplete )
       
   409             {
       
   410             status = KErrNone;
       
   411             }
       
   412         }
       
   413     return status;
       
   414 
       
   415     }
       
   416 
       
   417 // -----------------------------------------------------------------------------
       
   418 // CPosLmUrlParser::ParseBufferL
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 void CPosLmUrlParser::ParseBufferL( const TDesC8& aUrlBuffer )
       
   422     {
       
   423     // Check if the file parsing has already begun,if yes then parse
       
   424     // only the location params since the URL host is already parsed
       
   425     // in the beginning
       
   426     if( iSeek > 0 && iFileHandle )
       
   427         {
       
   428         iUrlLocation.Set( aUrlBuffer );
       
   429         // Parse & validate the URl location info
       
   430         ParseUrlLocationL();
       
   431         }
       
   432     else
       
   433         {
       
   434         // parse the buffer to find the query start delimeter
       
   435         TInt queryStartDelimeterPosition = aUrlBuffer.Find( KUrlQueryStartDelimeter );
       
   436         if( queryStartDelimeterPosition != KErrNotFound )
       
   437             {
       
   438             // Extract the url host 
       
   439             iUrlHost.Set( aUrlBuffer.Mid( 0, queryStartDelimeterPosition ) );
       
   440             // Increment the file seek position until the query start delimeter
       
   441             iSeek = iSeek + iUrlHost.Length()+ KQueryStartDelimeterLength;
       
   442             // Parse & validate the url host
       
   443             ParseUrlHostL();
       
   444             // Extract the Url location parameters
       
   445             iUrlLocation.Set( aUrlBuffer.Mid( queryStartDelimeterPosition+KQueryStartDelimeterLength, 
       
   446                               ( aUrlBuffer.Length() - 
       
   447                               ( queryStartDelimeterPosition+KQueryStartDelimeterLength ) ) ) );
       
   448             // Parse & validate the URl location info
       
   449             ParseUrlLocationL();
       
   450             }
       
   451         else
       
   452             {
       
   453             User::Leave( KErrPosLmUnknownFormat );
       
   454             }
       
   455         }
       
   456     }
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 // CPosLmUrlParser::ParseUrlHostL
       
   460 // -----------------------------------------------------------------------------
       
   461 //
       
   462 void CPosLmUrlParser::ParseUrlHostL()
       
   463     {
       
   464     // Holds the extracted scheme portion of the URl
       
   465     TPtrC8 parsedUriScheme ;
       
   466     // Holds the extracted host name portion of the URL
       
   467     TPtrC8 parsedUriHost;
       
   468     // Find the Url host delimeter position
       
   469     TInt urlHostDelimeterPosition = iUrlHost.Find( KUrlHostDelimeter );
       
   470     // Check if the delimeter is found,if yes then validate the scheme
       
   471     // & host name with the allowed values,else only validate the hostname 
       
   472     if( urlHostDelimeterPosition != KErrNotFound )
       
   473         {
       
   474         // Extract the scheme part of the Url
       
   475         parsedUriScheme.Set( iUrlHost.Mid( 0, urlHostDelimeterPosition ) );
       
   476         // Extract the host name
       
   477         parsedUriHost.Set( iUrlHost.Mid( urlHostDelimeterPosition+KHostDelimeterLength,
       
   478                            iUrlHost.Length() - 
       
   479                            ( urlHostDelimeterPosition+KHostDelimeterLength ) ) );
       
   480         // validate the uri scheme by Comparing with the allowed values for Url Scheme, 
       
   481         // if it does not match then leave with KErrPosLmUnknownFormat
       
   482         if( ( parsedUriScheme.CompareC( KUrlSchemeHttp ) ) &&
       
   483             ( parsedUriScheme.CompareC( KUrlSchemeHttps ) ) )
       
   484             {
       
   485             User::Leave( KErrPosLmUnknownFormat );
       
   486             }
       
   487         // validate the uri host by Comparing with the allowed values for Url Host, 
       
   488         // if it does not match then leave with KErrPosLmUnknownFormat
       
   489         if( ( parsedUriHost.CompareC( KUrlHostFull ) ) &&
       
   490             ( parsedUriHost.CompareC( KUrlHost ) ) )
       
   491             {
       
   492             User::Leave( KErrPosLmUnknownFormat );
       
   493             }
       
   494         }
       
   495     else
       
   496         {
       
   497         // validate the uri host by Comparing with the allowed values for Url Host, 
       
   498         // if it does not match then leave with KErrPosLmUnknownFormat
       
   499         if( ( iUrlHost.CompareC( KUrlHostFull ) ) &&
       
   500             ( iUrlHost.CompareC( KUrlHost ) ) )
       
   501             {
       
   502             User::Leave( KErrPosLmUnknownFormat );
       
   503             }
       
   504         }
       
   505     }
       
   506 
       
   507 
       
   508 // -----------------------------------------------------------------------------
       
   509 // CPosLmUrlParser::ParseUrlLocationL
       
   510 // -----------------------------------------------------------------------------
       
   511 //
       
   512 void CPosLmUrlParser::ParseUrlLocationL()
       
   513     {
       
   514     // Holds the extracted location info
       
   515     TPtrC8 parsedUrlLocation;
       
   516     // Get the location delimeter position
       
   517     TInt locationDelimeterPosition = iUrlLocation.Find( KUrlLocationDelimeter );
       
   518     // Continue parsing till the next delimeter is not found
       
   519     if( locationDelimeterPosition != KErrNotFound )
       
   520         {
       
   521         // Reset the URL parameters
       
   522         ResetUrlParameters();
       
   523         // Extract the location information for a single landmark
       
   524         parsedUrlLocation.Set( iUrlLocation.Mid( 0, locationDelimeterPosition ) );
       
   525         // Remove the extracted location from iUrlLocation
       
   526         iUrlLocation.Set( iUrlLocation.Mid( locationDelimeterPosition+KLocationDelimeterLength,  
       
   527                        ( iUrlLocation.Length() -
       
   528                        ( locationDelimeterPosition+KLocationDelimeterLength ) ) ) );
       
   529         // parse the url parameters for the extracted location
       
   530         ParseUrlParametersL( parsedUrlLocation );
       
   531         // Set parser status to EStateParsingPending since there could 
       
   532         // be more location info following the location delimeter
       
   533         // iParserStatus = EStateParsingPending;
       
   534         
       
   535         // Currently since multiple URL parsing is not supported,the rest
       
   536         // of the location info is ignored. Therefore,
       
   537         // set parser status to EStateParsingComplete so as to complete
       
   538         // the parsing for the first location info found
       
   539         SetParserStatusL( EStateParsingComplete );
       
   540         }
       
   541     else
       
   542         {
       
   543         // Check that there is another set of location info before parsing
       
   544         if( iUrlLocation != KNullDesC8 )
       
   545             {
       
   546             // Parse the url parameters for the location information
       
   547             ParseUrlParametersL( iUrlLocation );
       
   548             }
       
   549         else
       
   550             {
       
   551             iFileparsed = ETrue;
       
   552             }
       
   553         SetParserStatusL( EStateParsingComplete );
       
   554         }
       
   555     }
       
   556 
       
   557 // -----------------------------------------------------------------------------
       
   558 // CPosLmUrlParser::SetParserStatusL
       
   559 // -----------------------------------------------------------------------------
       
   560 //
       
   561 void CPosLmUrlParser::SetParserStatusL( TInt aStatus )
       
   562     {
       
   563     // Check that there are no more chunks left before changing parser 
       
   564     // status to EStateParsingComplete incase of file parsing
       
   565     if( iFileHandle )
       
   566         {
       
   567         // 
       
   568         if( iSeek+iChunkSize >= iContentSize && iFileparsed )
       
   569             {
       
   570             // Set parser status to EStateParsingComplete since no more
       
   571             // location info present in the URL
       
   572             iParserStatus = aStatus;
       
   573             SetLocalityL();
       
   574             }
       
   575         }
       
   576     else
       
   577         {
       
   578         // Set parser status to EStateParsingComplete since no more
       
   579         // location info present in the URL
       
   580         iParserStatus = aStatus;
       
   581         SetLocalityL();
       
   582         }
       
   583     
       
   584     }
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 // CPosLmUrlParser::SetLocalityL
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 void CPosLmUrlParser::SetLocalityL()
       
   591     {
       
   592     // Set the coordinates for the parsed landmark.If the latitude & longitude 
       
   593     // cannot be set then leave with KErrPosLmUnknownFormat
       
   594     TLocality position( TCoordinate(iParsedLatitudeValue, iParsedLongitudeValue,iParsedAltitudeValue ),
       
   595               iParsedPositionAccuracyValue,iParsedAltitudeAccuracyValue );
       
   596     TRAPD( error, iParsedLandmark->SetPositionL( position ) );
       
   597     if( error == KErrArgument )
       
   598         {
       
   599         User::Leave( KErrPosLmUnknownFormat );
       
   600         }
       
   601     else
       
   602         {
       
   603         // increment the number of landmarks parsed
       
   604         ++iNumOfParsedLandmarks;
       
   605         }    
       
   606     }
       
   607 
       
   608 
       
   609 // -----------------------------------------------------------------------------
       
   610 // CPosLmUrlParser::ParseUrlParametersL
       
   611 // -----------------------------------------------------------------------------
       
   612 //
       
   613 void CPosLmUrlParser::ParseUrlParametersL( const TDesC8& aUrlParameters )
       
   614     {
       
   615     // Holds the extracted parameter value pair
       
   616     TPtrC parsedUrlParameters;
       
   617     // Holds the next Url parameter value pairs
       
   618     TPtrC urlParameters ;
       
   619     TInt result = KErrNone;
       
   620     TInt column = 0;
       
   621     // Get the parameter delimeter position
       
   622     TInt parameterDelimeterPosition = aUrlParameters.Find( KUrlParameterDelimeter );
       
   623     // Holds the the url chunk in TDesC type
       
   624     HBufC *sourceUrl = HBufC::NewLC( aUrlParameters.Length() );
       
   625     sourceUrl->Des().Copy( aUrlParameters );
       
   626     //Check if the Param Delimiter exists in the URL
       
   627     if( parameterDelimeterPosition != KErrNotFound )
       
   628         {
       
   629         iParamDelimiterParsed= ETrue;
       
   630         while( result != KErrNotFound )
       
   631         	{
       
   632         	//Extract the location parameter from the url
       
   633         	result = TextUtils::ColumnText( parsedUrlParameters, column, sourceUrl, KParamSeperator );
       
   634             //Check if the input is from the file
       
   635             if( iFileHandle )
       
   636                 {
       
   637                 //Skip the last location parameter in the url, it should come with the next url chunk
       
   638                 if( TextUtils::ColumnText( urlParameters, (column+1), sourceUrl, KParamSeperator )!= KErrNotFound )
       
   639                     {
       
   640                     //increase the seek with the length of the parsed param and delimeter length
       
   641                     iSeek = iSeek + parsedUrlParameters.Length()+ KParameterDelimeterLength;
       
   642                     //check if the parsed parameter is a valid tag value pair
       
   643                     if( parsedUrlParameters.Find( KUrlParameterValueDelimeter ) != KErrNotFound )
       
   644                         {
       
   645                         ParseParamValueL( parsedUrlParameters );
       
   646                         }
       
   647                     }
       
   648                 //Check if the last param is ending with &
       
   649                 else if( parameterDelimeterPosition == parsedUrlParameters.Length() )
       
   650                     {
       
   651                     ParseParamValueL( parsedUrlParameters );
       
   652                     iSeek = iSeek + parsedUrlParameters.Length()+ KParameterDelimeterLength;
       
   653                     // Check if it is the last chunk in the file
       
   654                     if( iSeek+iChunkSize >= iContentSize && !iFileparsed )
       
   655                         {
       
   656                         iFileparsed = ETrue;
       
   657                         }
       
   658                     }
       
   659                 }
       
   660             //if input is from buffer
       
   661             else
       
   662                 if ( parsedUrlParameters != KNullDesC )
       
   663                     {
       
   664                     ParseParamValueL( parsedUrlParameters );
       
   665                     }
       
   666         	column++;
       
   667         	}
       
   668         }
       
   669     else
       
   670         {
       
   671         // Check if the parsing is from file,if yes then check if there
       
   672         // are more chunks left
       
   673         if( iFileHandle )
       
   674             {
       
   675             if( iSeek+iChunkSize >= iContentSize && !iFileparsed )
       
   676                 {
       
   677                 // Parse the param values if any
       
   678                 ParseParamValueL( *sourceUrl );
       
   679                 iSeek = iSeek + sourceUrl->Length();
       
   680                 iFileparsed = ETrue;
       
   681                 }
       
   682             else
       
   683             	{
       
   684             	if( sourceUrl->Find( KUrlParameterValueDelimeter ) != KErrNotFound && 
       
   685             			( sourceUrl->Length() == iChunkSize ) )
       
   686 					{
       
   687 					ParseParamValueL( *sourceUrl );
       
   688 					iSeek = iSeek + sourceUrl->Length()+ KParameterDelimeterLength; 
       
   689 					}
       
   690             	else if( sourceUrl->Find( KUrlParameterValueDelimeter ) == KErrNotFound && ( iParamDelimiterParsed == EFalse ) )
       
   691             	    {
       
   692             	    iSeek = iSeek + sourceUrl->Length()+ KParameterDelimeterLength;
       
   693             	    }
       
   694             	}
       
   695             }
       
   696          }
       
   697     CleanupStack::PopAndDestroy( sourceUrl );
       
   698     }
       
   699 
       
   700 // -----------------------------------------------------------------------------
       
   701 // CPosLmUrlParser::ParseParamValueL
       
   702 // -----------------------------------------------------------------------------
       
   703 //
       
   704 void CPosLmUrlParser::ParseParamValueL( const TDesC& aParamValue )
       
   705     {
       
   706     // holds the extracted  parameter name
       
   707     TPtrC paramName;
       
   708     // holds the extracted parameter value
       
   709     TPtrC paramValue;
       
   710     // Get the param value delimeter position
       
   711     TInt paramValueDelimeterPosition = aParamValue.Find( KUrlParameterValueDelimeter );
       
   712     // Check that the delimeter is found,else leave with KErrPosLmUnknownFormat
       
   713     if( paramValueDelimeterPosition != KErrNotFound )
       
   714         {
       
   715         // Extract the param name
       
   716         paramName.Set( aParamValue.Mid( 0, paramValueDelimeterPosition ) );
       
   717         // Extract the param value
       
   718         paramValue.Set( aParamValue.Mid( paramValueDelimeterPosition+KParameterDelimeterLength,
       
   719                        ( aParamValue.Length() -
       
   720                        ( paramValueDelimeterPosition+KParameterDelimeterLength ) ) ) );
       
   721         //Coverting the paramname to TDesC8
       
   722         HBufC8* paramName8 = HBufC8::NewLC( paramName.Length() );
       
   723         paramName8->Des().Copy( paramName );
       
   724         //Convering the paramValue to TDesC8
       
   725         HBufC8* paramValue8 = HBufC8::NewLC( paramValue.Length() );
       
   726         paramValue8->Des().Copy( paramValue );
       
   727         // Compare the param values
       
   728         CompareParamValueL( *paramName8,*paramValue8 );
       
   729         CleanupStack::PopAndDestroy( 2, paramName8 );
       
   730         }
       
   731     else
       
   732         {
       
   733         User::Leave( KErrPosLmUnknownFormat );
       
   734         }
       
   735     
       
   736     }
       
   737 
       
   738 // -----------------------------------------------------------------------------
       
   739 // CPosLmUrlParser::CompareParamValueL
       
   740 // -----------------------------------------------------------------------------
       
   741 //
       
   742 void CPosLmUrlParser::CompareParamValueL( const TDesC8& aParam, const TDesC8& aValue )
       
   743     {
       
   744     iParamDelimiterParsed = EFalse;
       
   745 
       
   746     // Compare the param name with the possible parameter values
       
   747     if( !aParam.CompareC( KUrlLatitude ) )
       
   748         {
       
   749         // Check if the latitude param has already been parsed once,to avoid 
       
   750         // setting the values again incase of repetition of params
       
   751         if( !iLatitudeParsed )
       
   752             {
       
   753             // Indicates that the latitude has been parsed once
       
   754             iLatitudeParsed = ETrue;
       
   755             SetLatLongParamL( aValue, iParsedLatitudeValue, ELatitude );
       
   756             }
       
   757         }
       
   758     else if( !aParam.CompareC( KUrlLongitude ) )
       
   759             {
       
   760             // Check if the longitude param has already been parsed once,to avoid 
       
   761             // setting the values again incase of repetition of params
       
   762             if( !iLongitudeParsed )
       
   763                 {
       
   764                 // Indicates that the longitude has been parsed once
       
   765                 iLongitudeParsed = ETrue;
       
   766                 SetLatLongParamL( aValue, iParsedLongitudeValue, ELongitude );
       
   767                 }
       
   768             }
       
   769     else if( !aParam.CompareC( KUrlAltitude ) )
       
   770             {
       
   771             // Check if the altitude param has already been parsed once,to avoid 
       
   772             // setting the values again incase of repetition of params
       
   773             if( !iAltitudeParsed )
       
   774                 {
       
   775                 // Indicates that the altitude has been parsed once
       
   776                 iAltitudeParsed = ETrue;
       
   777                 SetNumberParamL( aValue, iParsedAltitudeValue );
       
   778                 }
       
   779             }
       
   780     else if( !aParam.CompareC( KUrlPositionAccuracy ) )
       
   781             {
       
   782             // Check if the position accuracy param has already been parsed once,to avoid 
       
   783             // setting the values again incase of repetition of params
       
   784             if( !iPositionAccuracyParsed )
       
   785                 {
       
   786                 // Indicates that the position accuracy has been parsed once
       
   787                 iPositionAccuracyParsed = ETrue;
       
   788                 SetNumberParamL( aValue, iParsedPositionAccuracyValue );
       
   789                 }
       
   790             }
       
   791     else if( !aParam.CompareC( KUrlAltitudeAccuracy ) )
       
   792             {
       
   793             // Check if the altiude accuracy param has already been parsed once,to avoid 
       
   794             // setting the values again incase of repetition of params
       
   795             if( !iAltitudeAccuracyParsed )
       
   796                 {
       
   797                 // Indicates that the altitude accuracy has been parsed once
       
   798                 iAltitudeAccuracyParsed = ETrue;
       
   799                 SetNumberParamL( aValue, iParsedAltitudeAccuracyValue );
       
   800                 }
       
   801             }
       
   802     else if( !aParam.CompareC( KUrlSpeed ) )
       
   803             {
       
   804             // Check if the speed param has already been parsed once,to avoid 
       
   805             // setting the values again incase of repetition of params
       
   806             if( !iSpeedParsed )
       
   807                 {
       
   808                 // Indicates that the speed has been parsed once
       
   809                 iSpeedParsed = ETrue;
       
   810                 SetPositionFieldNumberParamL( aValue, ESpeed );
       
   811                 }
       
   812             }
       
   813     else if( !aParam.CompareC( KUrlHeading ) )
       
   814             {
       
   815             // Check if the heading param has already been parsed once,to avoid 
       
   816             // setting the values again incase of repetition of params
       
   817             if( !iHeadingParsed )
       
   818                 {
       
   819                 // Indicates that the heading has been parsed once
       
   820                 iHeadingParsed = ETrue;
       
   821                 SetPositionFieldNumberParamL( aValue, EHeading );
       
   822                 }
       
   823             }
       
   824     else if ( !aParam.CompareC( KUrlName ) )
       
   825             {
       
   826             // Check if the name param has already been parsed once,to avoid 
       
   827             // setting the values again incase of repetition of params
       
   828             if( !iNameParsed )
       
   829                 {
       
   830                 // Indicates that the name has been parsed once
       
   831                 iNameParsed = ETrue;
       
   832                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EName );
       
   833                 }
       
   834             }
       
   835     else if ( !aParam.CompareC( KUrlStreet ) )
       
   836             {
       
   837             // Check if the street param has already been parsed once,to avoid 
       
   838             // setting the values again incase of repetition of params
       
   839             if( !iStreetParsed )
       
   840                 {
       
   841                 // Indicates that the street has been parsed once
       
   842                 iStreetParsed = ETrue;
       
   843                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EStreet );
       
   844                 }
       
   845             }
       
   846     else if ( !aParam.CompareC( KUrlHouseNumber ) )
       
   847             {
       
   848             // Check if the housenumber param has already been parsed once,to avoid 
       
   849             // setting the values again incase of repetition of params
       
   850             if( !iHouseNumberParsed )
       
   851                 {
       
   852                 // Indicates that the housenumber has been parsed once
       
   853                 iHouseNumberParsed = ETrue;
       
   854                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EHouseNumber );
       
   855                 }
       
   856             }
       
   857     else if ( !aParam.CompareC( KUrlPostalCode ) )
       
   858             {
       
   859             // Check if the PostalCode param has already been parsed once,to avoid 
       
   860             // setting the values again incase of repetition of params
       
   861             if( !iPostalCodeParsed )
       
   862                 {
       
   863                 // Indicates that the PostalCode has been parsed once
       
   864                 iPostalCodeParsed = ETrue;
       
   865                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EPostalCode );
       
   866                 }
       
   867             }
       
   868     else if ( !aParam.CompareC( KUrlCity ) )
       
   869             {
       
   870             // Check if the city param has already been parsed once,to avoid 
       
   871             // setting the values again incase of repetition of params
       
   872             if( !iCityParsed )
       
   873                 {
       
   874                 // Indicates that the city has been parsed once
       
   875                 iCityParsed = ETrue;
       
   876                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, ECity );
       
   877                 }
       
   878             }
       
   879     else if ( !aParam.CompareC( KUrlState ) )
       
   880             {
       
   881             // Check if the State param has already been parsed once,to avoid 
       
   882             // setting the values again incase of repetition of params
       
   883             if( !iStateParsed )
       
   884                 {
       
   885                 // Indicates that the State has been parsed once
       
   886                 iStateParsed = ETrue;
       
   887                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EState );
       
   888                 }
       
   889             }
       
   890     else if ( !aParam.CompareC( KUrlCountry ) )
       
   891             {
       
   892             // Check if the Country param has already been parsed once,to avoid 
       
   893             // setting the values again incase of repetition of params
       
   894             if( !iCountryParsed )
       
   895                 {
       
   896                 // Indicates that the Country has been parsed once
       
   897                 iCountryParsed = ETrue;
       
   898                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, ECountry );
       
   899                 }
       
   900             }
       
   901     else if ( !aParam.CompareC( KUrlTelephone ) )
       
   902             {
       
   903             // Check if the Telephone param has already been parsed once,to avoid 
       
   904             // setting the values again incase of repetition of params
       
   905             if( !iTelephoneParsed )
       
   906                 {
       
   907                 // Indicates that the Telephone has been parsed once
       
   908                 iTelephoneParsed = ETrue;
       
   909                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, ETelephone );
       
   910                 }
       
   911             }
       
   912     else if ( !aParam.CompareC( KUrlWebUrl ) )
       
   913             {
       
   914             // Check if the WebUrl param has already been parsed once,to avoid 
       
   915             // setting the values again incase of repetition of params
       
   916             if( !iWebUrlParsed )
       
   917                 {
       
   918                 // Indicates that the WebUrl has been parsed once
       
   919                 iWebUrlParsed = ETrue;
       
   920                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EWebUrl );
       
   921                 }
       
   922             }
       
   923     else if ( !aParam.CompareC( KUrlDescription ) )
       
   924             {
       
   925             // Check if the Description param has already been parsed once,to avoid 
       
   926             // setting the values again incase of repetition of params
       
   927             if( !iDescriptionParsed )
       
   928                 {
       
   929                 // Indicates that the Description has been parsed once
       
   930                 iDescriptionParsed = ETrue;
       
   931                 SetTextParamL( aValue, KPosLmMaxDescriptionLength, EDescription );
       
   932                 }
       
   933             }
       
   934     else if ( !aParam.CompareC( KUrlPlaceId ) )
       
   935             {
       
   936             // Check if the PlaceId param has already been parsed once,to avoid 
       
   937             // setting the values again incase of repetition of params
       
   938             if( !iPlaceIdParsed )
       
   939                 {
       
   940                 // Indicates that the PlaceId has been parsed once
       
   941                 iPlaceIdParsed = ETrue;
       
   942                 SetTextParamL( aValue, KPosLmMaxTextFieldLength, EPlaceId );
       
   943                 }
       
   944             }
       
   945     else if ( !aParam.CompareC( KUrlTimestamp ) )
       
   946             {
       
   947             SetTimestampParamL( aValue );
       
   948             }
       
   949     else if ( !aParam.CompareC( KUrlCategory ) )
       
   950             {
       
   951             SetCategoryParamL( aValue );
       
   952             }
       
   953     }
       
   954 
       
   955 
       
   956 // -----------------------------------------------------------------------------
       
   957 // CPosLmUrlParser::SetLatLongParamL
       
   958 // -----------------------------------------------------------------------------
       
   959 //
       
   960 void CPosLmUrlParser::SetLatLongParamL( const TDesC8& aParsedValue, TReal64& aValue, 
       
   961                                         TInt aField  )
       
   962     {
       
   963     // holds the parsed number in text form
       
   964     TBuf<KRealWidth> parsedNumber;
       
   965     // Check that value exists,else leave with KErrPosLmUnknownFormat since the
       
   966     // latitude & longitude field is mandatory
       
   967     if( aParsedValue == KNullDesC8 )
       
   968         {
       
   969         User::Leave( KErrPosLmUnknownFormat );
       
   970         }
       
   971     // Convert the descriptor obtained into real and check if the value is 
       
   972     // indeed real.
       
   973     TRAPD( error, PosLmConverterUtils::DesToRealL( aParsedValue, aValue ) );
       
   974     if( error != KErrNone )
       
   975         {
       
   976         User::Leave( KErrPosLmUnknownFormat );
       
   977         }
       
   978     TInt length = parsedNumber.Num( aValue, iRealFormatCoordinates );
       
   979     if( !length )
       
   980         {
       
   981         User::Leave( length );
       
   982         }
       
   983     TRAPD( err, PosLmConverterUtils::DesToRealL( parsedNumber, aValue ) );
       
   984     // check the value with the allowed range for latitude & longitude
       
   985     switch( aField )
       
   986         {
       
   987         case ELatitude :
       
   988              {
       
   989              if( err || !( aValue >= KMinLatitude 
       
   990                  && aValue <= KMaxLatitude ) ) 
       
   991                  {
       
   992                  User::Leave( KErrPosLmUnknownFormat );
       
   993                  }
       
   994              break;
       
   995              }
       
   996         case ELongitude :
       
   997              {
       
   998              if( err || !( aValue >= KMinLongitude 
       
   999                  && aValue <= KMaxLongitude ) ) 
       
  1000                  {
       
  1001                  User::Leave( KErrPosLmUnknownFormat );
       
  1002                  }
       
  1003              break;
       
  1004              }
       
  1005         default :
       
  1006             {
       
  1007             break;
       
  1008             }
       
  1009         }
       
  1010     }
       
  1011 
       
  1012 
       
  1013 // -----------------------------------------------------------------------------
       
  1014 // CPosLmUrlParser::SetNumberParamL
       
  1015 // -----------------------------------------------------------------------------
       
  1016 //
       
  1017 void CPosLmUrlParser::SetNumberParamL( const TDesC8& aParsedValue, TReal32& aValue )
       
  1018     {
       
  1019     // holds the parsed number in text form
       
  1020     TBuf<KRealWidth> parsedValue;
       
  1021     // Check that value exists
       
  1022     if( aParsedValue != KNullDesC8 )
       
  1023         {
       
  1024         // Convert the descriptor obtained into real and check if the value is 
       
  1025         // indeed real.
       
  1026         TRAPD( error, PosLmConverterUtils::DesToRealL( aParsedValue, aValue ) );
       
  1027         if( !error )
       
  1028             {
       
  1029             TInt length = parsedValue.Num( aValue, iRealFormat );
       
  1030             if( length != KErrGeneral )
       
  1031                 {
       
  1032                 TRAPD( error, PosLmConverterUtils::DesToRealL( parsedValue, aValue ) );
       
  1033                 if( error ) 
       
  1034                     {
       
  1035                     PosLmConverterUtils::SetNaN( aValue );
       
  1036                     }
       
  1037                  }
       
  1038             else
       
  1039                 {
       
  1040                 PosLmConverterUtils::SetNaN( aValue );
       
  1041                 }  
       
  1042             }
       
  1043         else
       
  1044             {
       
  1045             PosLmConverterUtils::SetNaN( aValue );
       
  1046             }
       
  1047         }        
       
  1048     }
       
  1049 
       
  1050 // -----------------------------------------------------------------------------
       
  1051 // CPosLmUrlParser::SetPositionFieldNumberParamL
       
  1052 // -----------------------------------------------------------------------------
       
  1053 //
       
  1054 void CPosLmUrlParser::SetPositionFieldNumberParamL( const TDesC8& aParsedValue, TInt aField  )
       
  1055     {
       
  1056     // holds the parsed number in text form
       
  1057     TBuf<KRealWidth> parsedValue;
       
  1058     // holds the number value in real32
       
  1059     TReal32 number;
       
  1060     // Check that value exists
       
  1061     if( aParsedValue != KNullDesC8 )
       
  1062         {
       
  1063         // Convert the descriptor obtained into real and check if the value is 
       
  1064         // indeed real.
       
  1065         TRAPD( error, PosLmConverterUtils::DesToRealL( aParsedValue, number ) );
       
  1066         if( !error )
       
  1067             {
       
  1068             TInt length = parsedValue.Num( number, iRealFormat );
       
  1069             if( length != KErrGeneral )
       
  1070                 {
       
  1071                 // set the position field for apped or heading depending 
       
  1072                 // on the field value that is passed
       
  1073                 switch( aField )
       
  1074                     {
       
  1075                     case ESpeed :
       
  1076                         {
       
  1077                         TInt error = KErrNone;
       
  1078                         TRAP( error, iParsedLandmark->SetPositionFieldL( 
       
  1079                                EPositionFieldHorizontalSpeed, parsedValue ) );
       
  1080                         break;
       
  1081                         }
       
  1082                     case EHeading :
       
  1083                         {
       
  1084                         TInt err = KErrNone;
       
  1085                         TRAP( err, iParsedLandmark->SetPositionFieldL( 
       
  1086                                 EPositionFieldHeading, parsedValue ) );
       
  1087                         break;
       
  1088                         }
       
  1089                     default :
       
  1090                         {
       
  1091                         break;
       
  1092                         }
       
  1093                     }
       
  1094                 }
       
  1095             }
       
  1096         }
       
  1097     }
       
  1098 
       
  1099 
       
  1100 // -----------------------------------------------------------------------------
       
  1101 // CPosLmUrlParser::SetTextParamL
       
  1102 // -----------------------------------------------------------------------------
       
  1103 // 
       
  1104 void CPosLmUrlParser::SetTextParamL( const TDesC8& aParsedValue, const TInt aMaxParseValueLength,
       
  1105                                      TInt aField )
       
  1106     {
       
  1107     // parse the text value
       
  1108     HBufC* parsedText = ParseTextL( aParsedValue, aMaxParseValueLength );
       
  1109     CleanupStack::PushL( parsedText );
       
  1110     // switch on the field & set the corresponding field values
       
  1111     switch( aField )
       
  1112         {
       
  1113         case EName :
       
  1114             {
       
  1115             iParsedLandmark->SetLandmarkNameL( *parsedText );
       
  1116             break;
       
  1117             }
       
  1118         case EStreet :
       
  1119             {
       
  1120             iParsedLandmark->SetPositionFieldL( EPositionFieldStreet, *parsedText );
       
  1121             break;
       
  1122             }
       
  1123         case EHouseNumber :
       
  1124             {
       
  1125             iParsedLandmark->SetPositionFieldL( EPositionFieldStreetExtension, *parsedText );            
       
  1126             break;
       
  1127             }
       
  1128         case EPostalCode :
       
  1129             {
       
  1130             iParsedLandmark->SetPositionFieldL( EPositionFieldPostalCode, *parsedText );
       
  1131             break;
       
  1132             }
       
  1133         case ECity :
       
  1134             {
       
  1135             iParsedLandmark->SetPositionFieldL( EPositionFieldCity, *parsedText );
       
  1136             break;
       
  1137             }
       
  1138         case EState :
       
  1139             {
       
  1140             iParsedLandmark->SetPositionFieldL( EPositionFieldState, *parsedText );
       
  1141             break;
       
  1142             }
       
  1143         case ECountry :
       
  1144             {
       
  1145             iParsedLandmark->SetPositionFieldL( EPositionFieldCountry, *parsedText );
       
  1146             break;
       
  1147             }
       
  1148         case ETelephone :
       
  1149             {
       
  1150             iParsedLandmark->SetPositionFieldL( EPositionFieldBuildingTelephone, *parsedText );
       
  1151             break;
       
  1152             }
       
  1153         case EWebUrl :
       
  1154             {
       
  1155             iParsedLandmark->SetPositionFieldL( EPositionFieldMediaLinksStart, *parsedText );
       
  1156             break;
       
  1157             }
       
  1158         case EDescription :
       
  1159             {
       
  1160             iParsedLandmark->SetLandmarkDescriptionL( *parsedText );
       
  1161             break;
       
  1162             }
       
  1163         case EPlaceId :
       
  1164             {
       
  1165             iParsedLandmark->SetPlaceIdL( *parsedText );
       
  1166             break;
       
  1167             }
       
  1168         default :
       
  1169             {
       
  1170             break;
       
  1171             }
       
  1172         }
       
  1173     CleanupStack::PopAndDestroy( parsedText );
       
  1174     }
       
  1175 
       
  1176 // -----------------------------------------------------------------------------
       
  1177 // CPosLmUrlParser::ParseTextL
       
  1178 // -----------------------------------------------------------------------------
       
  1179 //
       
  1180 HBufC* CPosLmUrlParser::ParseTextL( const TDesC8& aParseValue, const TInt aMaxParseValueLength )
       
  1181     {
       
  1182     // use a TLex instance to parse the text
       
  1183     TLex8 string( aParseValue );
       
  1184     // Holds the parsed text value that is returned
       
  1185     HBufC* parsedText = HBufC::NewL( aMaxParseValueLength );
       
  1186     CleanupStack::PushL( parsedText );
       
  1187 
       
  1188     // Extract each character & validate to check if it is alphadigit,if not then
       
  1189     // check for the encoded triplet & decode it 
       
  1190     while( !string.Eos() )
       
  1191         {
       
  1192         // Check that the length of the parsed string is not beyond 
       
  1193         // the max allowed length,if yes then stop parsing.
       
  1194         if( parsedText->Length() == aMaxParseValueLength )
       
  1195             {
       
  1196             break;
       
  1197             }
       
  1198         TChar character = string.Get();
       
  1199 
       
  1200         // Check if character is alpha digit
       
  1201         if( !character.IsAlphaDigit() )
       
  1202             {
       
  1203             // check for the url escape character
       
  1204             if(  character == '%' )
       
  1205                 {
       
  1206                 // Holds the string to be decoded
       
  1207                 HBufC* decodeBuffer = HBufC::NewL( KDecodeBufferLength );
       
  1208                 CleanupStack::PushL( decodeBuffer );
       
  1209                 // holds the decoded data
       
  1210                 HBufC* decodedBuffer =NULL;
       
  1211                 // extract the next 2 characters that follows the escape character
       
  1212                 decodeBuffer->Des().Append( character );
       
  1213                 decodeBuffer->Des().Append( string.Get() );
       
  1214                 decodeBuffer->Des().Append( string.Get() );
       
  1215                 // decode the escaped sequence and append to parsed buufer if no errors
       
  1216                  TRAPD( error, decodedBuffer = 
       
  1217                        EscapeUtils::EscapeDecodeL( decodeBuffer->Des() );
       
  1218                         );
       
  1219                 if( !error )
       
  1220                     {
       
  1221                     parsedText->Des().Append( decodedBuffer->Des() );
       
  1222                     CleanupStack::PopAndDestroy(  decodeBuffer );
       
  1223                     delete decodedBuffer;
       
  1224                     }
       
  1225                 else
       
  1226                     {
       
  1227                     User::Leave( KErrPosLmUnknownFormat );
       
  1228                     }
       
  1229                 }
       
  1230             else
       
  1231                 {
       
  1232                 // stop the parsing if any other special character 
       
  1233                 // is encountered.
       
  1234                 break;
       
  1235                 }
       
  1236             
       
  1237             }
       
  1238         else
       
  1239             {
       
  1240             // append the aplha digit character to parsed buffer
       
  1241             parsedText->Des().Append( character );
       
  1242             }
       
  1243         }
       
  1244     
       
  1245     CleanupStack::Pop( parsedText );
       
  1246     
       
  1247     return parsedText;
       
  1248     }
       
  1249 
       
  1250 
       
  1251 // -----------------------------------------------------------------------------
       
  1252 // CPosLmUrlParser::SetTimestampParamL
       
  1253 // -----------------------------------------------------------------------------
       
  1254 //
       
  1255 void CPosLmUrlParser::SetTimestampParamL( const TDesC8& aParsedValue )
       
  1256     {
       
  1257     // Check if the timeStamp param has already been parsed once,to avoid 
       
  1258     // setting the values again incase of repetition of params
       
  1259     if( !iTimeStampParsed )
       
  1260         {
       
  1261         // Indicates that the TimeStamp has been parsed once
       
  1262         iTimeStampParsed = ETrue;
       
  1263         // holds the extracted date
       
  1264         TPtrC8 parsedDate;
       
  1265         // holds the extracted full time including microseconds
       
  1266         TPtrC8 parsedFullTime;
       
  1267         // hold only the time part
       
  1268         TPtrC8 parsedTime;
       
  1269         // holds the extracted microseconds field
       
  1270         TPtrC8 parsedMicroseconds;
       
  1271         // Indicates if any error during parsing of date field
       
  1272         TInt dateError = KErrNone;
       
  1273         // Indicates if any error during parsing of time field
       
  1274         TInt timeError = KErrNone;
       
  1275         // Indicates if any error during parsing of microseconds field
       
  1276         TInt microsecondsError = KErrNone;
       
  1277         // holds the parsed date field
       
  1278         HBufC* parsedDateBuffer = HBufC::NewL( KMaxDateFieldLength );
       
  1279         CleanupStack::PushL( parsedDateBuffer );
       
  1280         // holds the parsed time field
       
  1281         HBufC* parsedTimeBuffer = HBufC::NewL( KMaxTimeFieldLength );
       
  1282         CleanupStack::PushL( parsedTimeBuffer );
       
  1283         // holds the parsed microseconds field
       
  1284         HBufC* parsedMicrosecondsBuffer = HBufC::NewL( KMaxMicroSecondsLength );
       
  1285         CleanupStack::PushL( parsedMicrosecondsBuffer );
       
  1286         // holds the parsed date time 
       
  1287         HBufC* parsedDateTime = HBufC::NewL( KMaxDateTimeBufferLength );
       
  1288         CleanupStack::PushL( parsedDateTime );
       
  1289         
       
  1290         // Find the date time delimeter
       
  1291         TInt dateTimeDelimeterPosition = aParsedValue.Find( KUrlDateTimeDelimeter );
       
  1292         if( dateTimeDelimeterPosition != KErrNotFound )
       
  1293             {
       
  1294             parsedDate.Set( aParsedValue.Mid( 0, dateTimeDelimeterPosition ) );
       
  1295             parsedFullTime.Set( aParsedValue.Mid( dateTimeDelimeterPosition+1,
       
  1296                           ( aParsedValue.Length() -( dateTimeDelimeterPosition+1 ) ) ) );
       
  1297             // Parse the date Field
       
  1298             dateError = ParseDate( parsedDate, *parsedDateBuffer );
       
  1299             
       
  1300             // Check that there is no error during date parsing
       
  1301             if( !dateError )
       
  1302                 {
       
  1303                 // Find the next time delimeter position
       
  1304                 TInt timeDelimeterPosition = parsedFullTime.Find( KUrlTimeDelimeter );
       
  1305                 if( timeDelimeterPosition != KErrNotFound )
       
  1306                     {
       
  1307                     // Extract the time & microseconds fields separately & parse them
       
  1308                     parsedTime.Set( parsedFullTime.Mid( 0, timeDelimeterPosition ) );
       
  1309                     parsedMicroseconds.Set( parsedFullTime.Mid( timeDelimeterPosition+1, 
       
  1310                             parsedFullTime.Length() - ( timeDelimeterPosition+1 ) ) );
       
  1311                     // parse the time field
       
  1312                     timeError = ParseTime( parsedTime, *parsedTimeBuffer );
       
  1313                     // Check that there is no error during time parsing
       
  1314                     if( !timeError )
       
  1315                         {
       
  1316                         // parse  the value of microseconds upto 6 digits
       
  1317                         TLex8 microsecondsString( parsedMicroseconds );
       
  1318                         while( !microsecondsString.Eos() && ( parsedMicrosecondsBuffer->Length() 
       
  1319                                                          <= KMaxMicroSecondsLength ) )
       
  1320                             {
       
  1321                             // get each character & check if it is a digit 
       
  1322                             TChar microsecondCharacter = microsecondsString.Get();
       
  1323                             if( microsecondCharacter.IsDigit() )
       
  1324                                  {
       
  1325                                  parsedMicrosecondsBuffer->Des().Append( microsecondCharacter );
       
  1326                                  }
       
  1327                              else
       
  1328                                  {
       
  1329                                  microsecondsError = KErrGeneral;
       
  1330                                  break;
       
  1331                                  }               
       
  1332                             }
       
  1333                         }
       
  1334                     }
       
  1335                 
       
  1336                 else
       
  1337                     {
       
  1338                     timeError = ParseTime( parsedFullTime, *parsedTimeBuffer );
       
  1339                     }
       
  1340                 }
       
  1341             }
       
  1342         else
       
  1343             {
       
  1344             dateError = ParseDate( aParsedValue, *parsedDateBuffer );
       
  1345             }
       
  1346         
       
  1347         // Check if there are any errors during the date parsing before appending
       
  1348         // to buffer and setting the timestamp
       
  1349         if( !dateError )
       
  1350             {
       
  1351             parsedDateTime->Des().Append( parsedDateBuffer->Des() );
       
  1352             // Check if there are any errors in time parsing before appending
       
  1353             if( !timeError )
       
  1354                 {
       
  1355                 // Check that the time field exists before appending to buffer
       
  1356                 if( parsedTimeBuffer->Des() != KNullDesC16 )
       
  1357                     {
       
  1358                     parsedDateTime->Des().Append( KDateTimeSeparator );
       
  1359                     parsedDateTime->Des().Append( parsedTimeBuffer->Des() );
       
  1360                     // Check if there are no errors inmicroseconds parsing before
       
  1361                     // appending
       
  1362                     if( !microsecondsError )
       
  1363                         {
       
  1364                         // Check that the microseconds field exists before
       
  1365                         // appending to the buffer
       
  1366                         if( parsedMicrosecondsBuffer->Des() != KNullDesC16 )
       
  1367                             {
       
  1368                             parsedDateTime->Des().Append( KTimeMicroSecondSeparator );
       
  1369                             parsedDateTime->Des().Append( parsedMicrosecondsBuffer->Des() );
       
  1370                             }
       
  1371                         }
       
  1372                     }
       
  1373                 }
       
  1374             // convert the parsed date time buffer into a TTime object & set the timestamp 
       
  1375             // for the parsed landmark
       
  1376             TTime timestamp;
       
  1377             TInt error = timestamp.Set( parsedDateTime->Des() );
       
  1378             // Check that there is no error returned while setting the time
       
  1379             if ( !error )
       
  1380                 {
       
  1381                 TDateTime dateTime = timestamp.DateTime();
       
  1382                 // Check that the year & day fields are not zero to avoid 
       
  1383                 // SetTimeStampL from leaving with KErrArgument
       
  1384                 if( dateTime.Year() && dateTime.Day() )
       
  1385                     {
       
  1386                     iParsedLandmark->SetTimeStampL( timestamp );
       
  1387                     }
       
  1388                 }
       
  1389             }
       
  1390         // delete all items on cleanupstack
       
  1391         CleanupStack::PopAndDestroy( 4, parsedDateBuffer );
       
  1392         }
       
  1393     }
       
  1394 
       
  1395 // -----------------------------------------------------------------------------
       
  1396 // CPosLmUrlParser::SetCategoryParamL
       
  1397 // -----------------------------------------------------------------------------
       
  1398 //
       
  1399 void CPosLmUrlParser::SetCategoryParamL( const TDesC8& aParsedValue )
       
  1400     {
       
  1401     TBool categoryPresent = EFalse;
       
  1402     // parse the category name
       
  1403     HBufC* parsedCategoryValue = ParseTextL( aParsedValue, KPosLmMaxCategoryNameLength );
       
  1404     CleanupStack::PushL( parsedCategoryValue );
       
  1405 
       
  1406     // Check that the category name exists before creating a category instance
       
  1407     if( *parsedCategoryValue != KNullDesC )
       
  1408         {
       
  1409         // Check that there are categories present in the parsed category array
       
  1410         if ( !iParsedCategories.Count() )
       
  1411             {
       
  1412             categoryPresent = EFalse;
       
  1413             }
       
  1414         // Check that the parsed category name is not already present,create
       
  1415         // category only with unique names
       
  1416         for( TInt i=0;i<iParsedCategories.Count();i++ )
       
  1417             {
       
  1418             TPtrC existingCategoryName;
       
  1419             // Get category name of each of the parsed categories
       
  1420             if( !( iParsedCategories[i]->GetCategoryName( existingCategoryName ) ) )
       
  1421                 {
       
  1422                 // Compare the existing category name with the newly parsed category
       
  1423                 // name
       
  1424                 if( !parsedCategoryValue->Des().CompareC( existingCategoryName ) ) 
       
  1425                     {
       
  1426                     categoryPresent = ETrue;
       
  1427                     }
       
  1428                 else
       
  1429                     {
       
  1430                     categoryPresent = EFalse;
       
  1431                     }
       
  1432                 }
       
  1433             }
       
  1434         // if the category is not present then create the category instance
       
  1435         if( !categoryPresent )
       
  1436             {
       
  1437             // Create a category instance
       
  1438             CPosLandmarkCategory* parsedCategory = CPosLandmarkCategory::NewL();
       
  1439             CleanupStack::PushL( parsedCategory );
       
  1440             // Check that category id is not equal to any of the reserved global
       
  1441             // category ids.If so then increment the id before setting it.
       
  1442             if( iParsedCategoryId%3000 == 0 )
       
  1443                 {
       
  1444                 iParsedCategoryId++;
       
  1445                 }
       
  1446             // set the category id for the parsed categories
       
  1447             PosLmImplExtension::SetCategoryIdL( *parsedCategory, iParsedCategoryId++ );
       
  1448             
       
  1449             // set the category name that has been parsed
       
  1450             TPtrC categoryName;
       
  1451             categoryName.Set( *parsedCategoryValue );
       
  1452             parsedCategory->SetCategoryNameL( categoryName );
       
  1453             // Add the category to the parsed landmark
       
  1454             iParsedLandmark->AddCategoryL( parsedCategory->CategoryId() );
       
  1455             User::LeaveIfError( iParsedCategories.Append( CPosLandmarkCategory::NewL(
       
  1456                                                           *parsedCategory ) ) );
       
  1457             CleanupStack::PopAndDestroy( parsedCategory );
       
  1458             }
       
  1459         }
       
  1460    CleanupStack::PopAndDestroy( parsedCategoryValue );
       
  1461    }
       
  1462 
       
  1463 // -----------------------------------------------------------------------------
       
  1464 // CPosLmUrlParser::ParseDate
       
  1465 // -----------------------------------------------------------------------------
       
  1466 //
       
  1467 TInt CPosLmUrlParser::ParseDate( const TDesC8& aParsedDate , 
       
  1468                                  HBufC& aParsedDateBuffer )
       
  1469     {
       
  1470     TInt error = KErrNone;
       
  1471     // parse the date field
       
  1472     if( aParsedDate.Length() != KMaxDateFieldLength )
       
  1473         {
       
  1474         error = KErrGeneral;
       
  1475         }
       
  1476     else
       
  1477         {
       
  1478         TLex8 dateString( aParsedDate );
       
  1479         while ( !dateString.Eos() )
       
  1480             {
       
  1481             TChar character = dateString.Get();
       
  1482             if( character.IsDigit() )
       
  1483                 {
       
  1484                 aParsedDateBuffer.Des().Append( character );
       
  1485                 }
       
  1486             else
       
  1487                 {
       
  1488                 error = KErrGeneral;
       
  1489                 break;
       
  1490                 }
       
  1491             }
       
  1492         }
       
  1493     return error;    
       
  1494     }
       
  1495     
       
  1496 // -----------------------------------------------------------------------------
       
  1497 // CPosLmUrlParser::ParseTime
       
  1498 // -----------------------------------------------------------------------------
       
  1499 //
       
  1500 TInt CPosLmUrlParser::ParseTime( const TDesC8& aParsedTime , 
       
  1501                                  HBufC& aParsedTimeBuffer )
       
  1502     {
       
  1503     TInt error = KErrNone;
       
  1504     // parse the date field
       
  1505     if( aParsedTime.Length() != KMaxTimeFieldLength )
       
  1506         {
       
  1507         error = KErrGeneral;
       
  1508         }
       
  1509     else
       
  1510         {
       
  1511         TLex8 timeString( aParsedTime );
       
  1512         while ( !timeString.Eos() )
       
  1513             {
       
  1514             TChar character = timeString.Get();
       
  1515             if( character.IsDigit() )
       
  1516                 {
       
  1517                 aParsedTimeBuffer.Des().Append( character );
       
  1518                 }
       
  1519             else
       
  1520                 {
       
  1521                 error = KErrGeneral;
       
  1522                 break;
       
  1523                 }
       
  1524             }
       
  1525         }
       
  1526     return error;    
       
  1527     }
       
  1528 
       
  1529 // -----------------------------------------------------------------------------
       
  1530 // CPosLmUrlParser::ResetUrlParameters
       
  1531 // -----------------------------------------------------------------------------
       
  1532 //
       
  1533 void CPosLmUrlParser::ResetUrlParameters()
       
  1534     {
       
  1535     // Initialize the coordinate values to NaN
       
  1536     PosLmConverterUtils::SetNaN( iParsedLatitudeValue );
       
  1537     PosLmConverterUtils::SetNaN( iParsedLongitudeValue );
       
  1538     PosLmConverterUtils::SetNaN( iParsedAltitudeValue );
       
  1539     PosLmConverterUtils::SetNaN( iParsedPositionAccuracyValue );
       
  1540     PosLmConverterUtils::SetNaN( iParsedAltitudeAccuracyValue );
       
  1541     // Initialize all the parameters parsed value to be EFalse
       
  1542     // during the start of parsing,indicating that the params have
       
  1543     // not been parsed yet.
       
  1544     iLatitudeParsed = EFalse;
       
  1545     iLongitudeParsed = EFalse;
       
  1546     iAltitudeParsed = EFalse;
       
  1547     iPositionAccuracyParsed = EFalse;
       
  1548     iAltitudeAccuracyParsed = EFalse;
       
  1549     iSpeedParsed = EFalse;
       
  1550     iHeadingParsed = EFalse;
       
  1551     iNameParsed = EFalse;
       
  1552     iStreetParsed = EFalse;
       
  1553     iHouseNumberParsed = EFalse;
       
  1554     iPostalCodeParsed = EFalse;
       
  1555     iCityParsed = EFalse;
       
  1556     iStateParsed = EFalse;
       
  1557     iCountryParsed = EFalse;
       
  1558     iTelephoneParsed = EFalse;
       
  1559     iWebUrlParsed = EFalse;
       
  1560     iDescriptionParsed = EFalse;
       
  1561     iPlaceIdParsed = EFalse;
       
  1562     iTimeStampParsed = EFalse;
       
  1563     // initializing the category id 
       
  1564     iParsedCategoryId = 1;
       
  1565     // Reset the parsed categories array
       
  1566     iParsedCategories.Reset();
       
  1567     iSeek = 0;
       
  1568     iFileparsed = EFalse;
       
  1569     iParamDelimiterParsed = ETrue;
       
  1570     }
       
  1571