--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarks/locationlandmarks/converter/src/epos_cposlmurlparser.cpp Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,1571 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class used for parsing a Landmarks URL & obtaining
+* landmarks information from it.
+*
+*
+*/
+
+
+#include <lbsposition.h>
+#include <gulutil.h>
+#include <uri8.h>
+#include <escapeutils.h>
+#include <EPos_LandmarksErrors.h>
+#include "epos_cposlmurlparser.h"
+#include "EPos_CPosLmCategoryManager.h"
+#include "EPos_CPosLandmarkDatabase.h"
+#include "epos_cposlmurlparseroperation.h"
+#include "EPos_PosLmConverterUtils.h"
+#include "EPos_PosLmImplExtension.h"
+#include "EPos_CPosLandmarkCategory.h"
+
+
+// Constants for formatting the Real numbers
+const TInt KRealPoint = 46;
+const TInt KRealDecimalPlaces = 2;
+const TInt KCoordinateDecimalPlaces = 6;
+// constants for checking the range of the coordinates
+const TReal KMinLatitude = -90.0;
+const TReal KMaxLatitude = 90.0;
+const TReal KMinLongitude = -180.0;
+const TReal KMaxLongitude = 180.0;
+// constants that define the decode buffer length
+const TInt KDecodeBufferLength = 3;
+// constants defining the length for the date time buffers
+const TInt KMaxDateTimeBufferLength = 22;
+const TInt KMaxMicroSecondsLength = 6;
+const TInt KMaxDateFieldLength = 8;
+const TInt KMaxTimeFieldLength = 6;
+// constants defining the length of the delimeters
+const TInt KHostDelimeterLength = 3;
+const TInt KQueryStartDelimeterLength = 2;
+const TInt KLocationDelimeterLength = 2;
+const TInt KParameterDelimeterLength = 1;
+// constants defining length of chunk size
+const TInt KMaxChunkSize = 5012;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::CPosLmUrlParser
+// Default Constructor
+//-----------------------------------------------------------------------------
+//
+CPosLmUrlParser::CPosLmUrlParser()
+ {
+ // initialize the TRealFormat variable for latitude & longitude formatting
+ iRealFormatCoordinates.iPoint = KRealPoint;
+ iRealFormatCoordinates.iType = KRealFormatFixed | KDoNotUseTriads;
+ iRealFormatCoordinates.iPlaces = KCoordinateDecimalPlaces;
+ iRealFormatCoordinates.iWidth = KRealWidth;
+
+ // initialize the TRealFormat variable for formatting other real32 numbers
+ iRealFormat.iPoint = KRealPoint;
+ iRealFormat.iType = KRealFormatFixed | KDoNotUseTriads;
+ iRealFormat.iPlaces = KRealDecimalPlaces;
+ iRealFormat.iWidth = KRealWidth;
+
+ ResetUrlParameters();
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::NewL
+// -----------------------------------------------------------------------------
+//
+CPosLmUrlParser* CPosLmUrlParser::NewL()
+ {
+ return new (ELeave) CPosLmUrlParser;
+ }
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::~CPosLmUrlParser
+// Destructor
+//-----------------------------------------------------------------------------
+//
+CPosLmUrlParser::~CPosLmUrlParser()
+ {
+ ResetUrlParser();
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetInputBuffer
+//
+//-----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetInputBuffer( const TDesC8& aBuffer )
+ {
+ // Reset the parser first,so as to start parsing freshly
+ ResetUrlParser();
+ // Set the input buffer
+ iInputBuffer.Set( aBuffer );
+
+ // Set size of input buffer
+ iContentSize = iInputBuffer.Length();
+
+ // Change parser status to EStateInitialized
+ iParserStatus = EStateInitialized;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetInputFileL
+//
+//-----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetInputFileL( const TDesC& aFile )
+ {
+ // Reset the parser first,so as to start parsing freshly
+ ResetUrlParser();
+ // Connect to the file server
+ User::LeaveIfError( iFs.Connect() );
+ // Open the file in the read only mode
+ User::LeaveIfError( iFile.Open( iFs, aFile,
+ EFileShareReadersOnly | EFileRead ) );
+ // Set the file handle
+ iFileHandle = &iFile;
+ // Set the file content size
+ User::LeaveIfError( iFileHandle->Size( iContentSize ) );
+ // Change parser status to EStateInitialized
+ iParserStatus = EStateInitialized;
+
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetInputFileHandleL
+//
+//-----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetInputFileHandleL( RFile& aFileHandle )
+ {
+ // Reset the parser first,so as to start parsing freshly
+ ResetUrlParser();
+ // set the file handle
+ iFileHandle = &aFileHandle;
+ // Set the file content size
+ User::LeaveIfError( iFileHandle->Size( iContentSize ) );
+ // Change parser status to EStateInitialized
+ iParserStatus = EStateInitialized;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseContentL
+//
+//-----------------------------------------------------------------------------
+//
+CPosLmOperation* CPosLmUrlParser::ParseContentL( TBool aBuildIndex )
+ {
+ // Check that the parser status is EStateInitialized when this method is called,
+ // if not panic with EPosLmProtocolBreak
+ __ASSERT_ALWAYS( iParserStatus == EStateInitialized,
+ Panic( KPosLandmarksClientPanic, EPosLmProtocolBreak ) );
+
+ // Build index not supported ,hence leave with KErrNotSupported if specified
+ if( aBuildIndex )
+ {
+ User::Leave( KErrNotSupported );
+ }
+ // Reset the url parameters
+ ResetUrlParameters();
+
+ // Delete any previous operation
+ DisconnectUrlOperation();
+
+ // Create a new instance of the operation class to be returned
+ iUrlParserOp = CPosLmUrlParserOperation::NewL( *this );
+
+ // change the parser status to EStateOperationCreated
+ iParserStatus = EStateOperationCreated;
+
+ return iUrlParserOp;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::NumOfParsedLandmarks
+//
+//-----------------------------------------------------------------------------
+//
+TUint32 CPosLmUrlParser::NumOfParsedLandmarks() const
+ {
+ return iNumOfParsedLandmarks;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::FirstCollectionDataId
+//
+//-----------------------------------------------------------------------------
+//
+TPosLmCollectionDataId CPosLmUrlParser::FirstCollectionDataId() const
+ {
+ // Do nothing,as collection data is not supported in url parsing
+ return EPosLmCollDataNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::NextCollectionDataId
+//
+//-----------------------------------------------------------------------------
+//
+TPosLmCollectionDataId CPosLmUrlParser::NextCollectionDataId(
+ TPosLmCollectionDataId /*aCollectionDataId*/ ) const
+ {
+ // Do nothing,as collection data is not supported in url parsing
+ return EPosLmCollDataNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::CollectionData
+//
+//-----------------------------------------------------------------------------
+//
+TPtrC CPosLmUrlParser::CollectionData( TPosLmCollectionDataId /*aDataId*/ ) const
+ {
+ // Do nothing,as collection data is not supported in url parsing
+ TPtrC nullDescriptor( KNullDesC );
+ return nullDescriptor;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::LandmarkLC
+//
+//-----------------------------------------------------------------------------
+//
+CPosLandmark* CPosLmUrlParser::LandmarkLC( TUint aLandmarkIndex ) const
+ {
+ // Check that index passed always equal to KPosLastParsedLandmark
+ // or less than the number of parsed landmarks but not negative
+ __ASSERT_ALWAYS(
+ aLandmarkIndex < iNumOfParsedLandmarks ||aLandmarkIndex == KPosLastParsedLandmark,
+ Panic( KPosLandmarksClientPanic, EPosInvalidIndex ) );
+
+ // Check if there are any parsed landmarks before returning the landmark,
+ // else return KErrNotFound
+ if( !iNumOfParsedLandmarks )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ return CPosLandmark::NewLC( *iParsedLandmark );
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::LandmarkCategoryLC
+//
+//-----------------------------------------------------------------------------
+//
+CPosLandmarkCategory* CPosLmUrlParser::LandmarkCategoryLC( TPosLmItemId
+ aCategoryId ) const
+ {
+ // indicates whether the category with the id specified is found or not
+ TBool found = EFalse;
+ TInt i = 0;
+ // check that there is a parsed landmark before getting any categories associated
+ // with it,else leave with KErrNotFound
+ if( !iNumOfParsedLandmarks )
+ {
+ User::Leave( KErrNotFound );
+ }
+ // check that categories exist for the parsed landmark,else leave with KErrNotFound
+ if( !iParsedCategories.Count() )
+ {
+ User::Leave( KErrNotFound );
+ }
+ else
+ {
+ // Find the category with the id provided ,from the parsed categories,if not found
+ // leave with KErrNotFound
+ for( i=0; i<iParsedCategories.Count();i++ )
+ {
+ if( iParsedCategories[i]->CategoryId() == aCategoryId )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ if( !found )
+ {
+ User::Leave( KErrNotFound );
+ }
+ }
+ return CPosLandmarkCategory::NewLC( *iParsedCategories[i] );
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ResetUrlParser
+//
+//-----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ResetUrlParser()
+ {
+ // set input buffer to NULL
+ iInputBuffer.Set( NULL, 0 );
+ // if any filehandle exists,close it
+ if( iFileHandle )
+ {
+ iFileHandle = NULL;
+ iFile.Close();
+ iFs.Close();
+ // delete the file buffer
+ delete iFileReadBuffer;
+ iFileReadBuffer = NULL;
+ }
+ // delete the previously parsed landmark
+ if( iParsedLandmark )
+ {
+ delete iParsedLandmark;
+ iParsedLandmark = NULL;
+ }
+ // reset the number of parsed landmarks to 0
+ iNumOfParsedLandmarks = 0;
+ // reset the categories array
+ iParsedCategories.ResetAndDestroy();
+ // Reset the parser status to EStateUnitialized
+ iParserStatus = EStateUnitialized;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::DisconnectUrlOperation
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::DisconnectUrlOperation()
+ {
+ if ( iUrlParserOp )
+ {
+ iUrlParserOp->DisconnectUrlParser();
+ iUrlParserOp = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::UrlOperationDestroyed
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::UrlOperationDestroyed()
+ {
+ iUrlParserOp = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseUrlL
+// -----------------------------------------------------------------------------
+//
+TInt CPosLmUrlParser::ParseUrlL()
+ {
+ TInt status = KPosLmOperationNotComplete;
+ // Set the chunk size to be read from the file
+ iChunkSize = iContentSize < KMaxChunkSize ? iContentSize : KMaxChunkSize;
+
+ // Create instance of CPosLandmark to hold the parsed info
+ iParsedLandmark = CPosLandmark::NewL();
+
+ // Check on the parser status,if the status is EStateParsingPending
+ // then continue with parsing the next location info
+ if( iParserStatus == EStateParsingPending )
+ {
+ // Parse the next location info
+ ParseUrlLocationL();
+ // Now check the parsing status to confirm if its complete,if
+ // yes change the status to KErrNone
+ if( iParserStatus == EStateParsingComplete )
+ {
+ status = KErrNone;
+ }
+ }
+ else
+ {
+ // start parsing afresh by setting the input buffer/file
+ // Check if the input is through a buffer or file
+ if( iInputBuffer.Ptr() )
+ {
+ ParseBufferL( iInputBuffer );
+ }
+ else
+ {
+ // for file parsing read the file in parts & parse the chunks
+ while(iSeek < iContentSize)
+ {
+ iFileReadBuffer = HBufC8::NewL( iChunkSize );
+ TPtr8 fileReadBufferPtr = iFileReadBuffer->Des();
+ User::LeaveIfError( iFileHandle->Read( iSeek, fileReadBufferPtr, iChunkSize ) );
+ ParseBufferL( iFileReadBuffer->Des() );
+ }
+ }
+ // Check on the parser status to set the status
+ if( iParserStatus == EStateParsingComplete )
+ {
+ status = KErrNone;
+ }
+ }
+ return status;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseBufferL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ParseBufferL( const TDesC8& aUrlBuffer )
+ {
+ // Check if the file parsing has already begun,if yes then parse
+ // only the location params since the URL host is already parsed
+ // in the beginning
+ if( iSeek > 0 && iFileHandle )
+ {
+ iUrlLocation.Set( aUrlBuffer );
+ // Parse & validate the URl location info
+ ParseUrlLocationL();
+ }
+ else
+ {
+ // parse the buffer to find the query start delimeter
+ TInt queryStartDelimeterPosition = aUrlBuffer.Find( KUrlQueryStartDelimeter );
+ if( queryStartDelimeterPosition != KErrNotFound )
+ {
+ // Extract the url host
+ iUrlHost.Set( aUrlBuffer.Mid( 0, queryStartDelimeterPosition ) );
+ // Increment the file seek position until the query start delimeter
+ iSeek = iSeek + iUrlHost.Length()+ KQueryStartDelimeterLength;
+ // Parse & validate the url host
+ ParseUrlHostL();
+ // Extract the Url location parameters
+ iUrlLocation.Set( aUrlBuffer.Mid( queryStartDelimeterPosition+KQueryStartDelimeterLength,
+ ( aUrlBuffer.Length() -
+ ( queryStartDelimeterPosition+KQueryStartDelimeterLength ) ) ) );
+ // Parse & validate the URl location info
+ ParseUrlLocationL();
+ }
+ else
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseUrlHostL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ParseUrlHostL()
+ {
+ // Holds the extracted scheme portion of the URl
+ TPtrC8 parsedUriScheme ;
+ // Holds the extracted host name portion of the URL
+ TPtrC8 parsedUriHost;
+ // Find the Url host delimeter position
+ TInt urlHostDelimeterPosition = iUrlHost.Find( KUrlHostDelimeter );
+ // Check if the delimeter is found,if yes then validate the scheme
+ // & host name with the allowed values,else only validate the hostname
+ if( urlHostDelimeterPosition != KErrNotFound )
+ {
+ // Extract the scheme part of the Url
+ parsedUriScheme.Set( iUrlHost.Mid( 0, urlHostDelimeterPosition ) );
+ // Extract the host name
+ parsedUriHost.Set( iUrlHost.Mid( urlHostDelimeterPosition+KHostDelimeterLength,
+ iUrlHost.Length() -
+ ( urlHostDelimeterPosition+KHostDelimeterLength ) ) );
+ // validate the uri scheme by Comparing with the allowed values for Url Scheme,
+ // if it does not match then leave with KErrPosLmUnknownFormat
+ if( ( parsedUriScheme.CompareC( KUrlSchemeHttp ) ) &&
+ ( parsedUriScheme.CompareC( KUrlSchemeHttps ) ) )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ // validate the uri host by Comparing with the allowed values for Url Host,
+ // if it does not match then leave with KErrPosLmUnknownFormat
+ if( ( parsedUriHost.CompareC( KUrlHostFull ) ) &&
+ ( parsedUriHost.CompareC( KUrlHost ) ) )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ }
+ else
+ {
+ // validate the uri host by Comparing with the allowed values for Url Host,
+ // if it does not match then leave with KErrPosLmUnknownFormat
+ if( ( iUrlHost.CompareC( KUrlHostFull ) ) &&
+ ( iUrlHost.CompareC( KUrlHost ) ) )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseUrlLocationL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ParseUrlLocationL()
+ {
+ // Holds the extracted location info
+ TPtrC8 parsedUrlLocation;
+ // Get the location delimeter position
+ TInt locationDelimeterPosition = iUrlLocation.Find( KUrlLocationDelimeter );
+ // Continue parsing till the next delimeter is not found
+ if( locationDelimeterPosition != KErrNotFound )
+ {
+ // Reset the URL parameters
+ ResetUrlParameters();
+ // Extract the location information for a single landmark
+ parsedUrlLocation.Set( iUrlLocation.Mid( 0, locationDelimeterPosition ) );
+ // Remove the extracted location from iUrlLocation
+ iUrlLocation.Set( iUrlLocation.Mid( locationDelimeterPosition+KLocationDelimeterLength,
+ ( iUrlLocation.Length() -
+ ( locationDelimeterPosition+KLocationDelimeterLength ) ) ) );
+ // parse the url parameters for the extracted location
+ ParseUrlParametersL( parsedUrlLocation );
+ // Set parser status to EStateParsingPending since there could
+ // be more location info following the location delimeter
+ // iParserStatus = EStateParsingPending;
+
+ // Currently since multiple URL parsing is not supported,the rest
+ // of the location info is ignored. Therefore,
+ // set parser status to EStateParsingComplete so as to complete
+ // the parsing for the first location info found
+ SetParserStatusL( EStateParsingComplete );
+ }
+ else
+ {
+ // Check that there is another set of location info before parsing
+ if( iUrlLocation != KNullDesC8 )
+ {
+ // Parse the url parameters for the location information
+ ParseUrlParametersL( iUrlLocation );
+ }
+ else
+ {
+ iFileparsed = ETrue;
+ }
+ SetParserStatusL( EStateParsingComplete );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetParserStatusL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetParserStatusL( TInt aStatus )
+ {
+ // Check that there are no more chunks left before changing parser
+ // status to EStateParsingComplete incase of file parsing
+ if( iFileHandle )
+ {
+ //
+ if( iSeek+iChunkSize >= iContentSize && iFileparsed )
+ {
+ // Set parser status to EStateParsingComplete since no more
+ // location info present in the URL
+ iParserStatus = aStatus;
+ SetLocalityL();
+ }
+ }
+ else
+ {
+ // Set parser status to EStateParsingComplete since no more
+ // location info present in the URL
+ iParserStatus = aStatus;
+ SetLocalityL();
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetLocalityL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetLocalityL()
+ {
+ // Set the coordinates for the parsed landmark.If the latitude & longitude
+ // cannot be set then leave with KErrPosLmUnknownFormat
+ TLocality position( TCoordinate(iParsedLatitudeValue, iParsedLongitudeValue,iParsedAltitudeValue ),
+ iParsedPositionAccuracyValue,iParsedAltitudeAccuracyValue );
+ TRAPD( error, iParsedLandmark->SetPositionL( position ) );
+ if( error == KErrArgument )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ else
+ {
+ // increment the number of landmarks parsed
+ ++iNumOfParsedLandmarks;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseUrlParametersL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ParseUrlParametersL( const TDesC8& aUrlParameters )
+ {
+ // Holds the extracted parameter value pair
+ TPtrC parsedUrlParameters;
+ // Holds the next Url parameter value pairs
+ TPtrC urlParameters ;
+ TInt result = KErrNone;
+ TInt column = 0;
+ // Get the parameter delimeter position
+ TInt parameterDelimeterPosition = aUrlParameters.Find( KUrlParameterDelimeter );
+ // Holds the the url chunk in TDesC type
+ HBufC *sourceUrl = HBufC::NewLC( aUrlParameters.Length() );
+ sourceUrl->Des().Copy( aUrlParameters );
+ //Check if the Param Delimiter exists in the URL
+ if( parameterDelimeterPosition != KErrNotFound )
+ {
+ iParamDelimiterParsed= ETrue;
+ while( result != KErrNotFound )
+ {
+ //Extract the location parameter from the url
+ result = TextUtils::ColumnText( parsedUrlParameters, column, sourceUrl, KParamSeperator );
+ //Check if the input is from the file
+ if( iFileHandle )
+ {
+ //Skip the last location parameter in the url, it should come with the next url chunk
+ if( TextUtils::ColumnText( urlParameters, (column+1), sourceUrl, KParamSeperator )!= KErrNotFound )
+ {
+ //increase the seek with the length of the parsed param and delimeter length
+ iSeek = iSeek + parsedUrlParameters.Length()+ KParameterDelimeterLength;
+ //check if the parsed parameter is a valid tag value pair
+ if( parsedUrlParameters.Find( KUrlParameterValueDelimeter ) != KErrNotFound )
+ {
+ ParseParamValueL( parsedUrlParameters );
+ }
+ }
+ //Check if the last param is ending with &
+ else if( parameterDelimeterPosition == parsedUrlParameters.Length() )
+ {
+ ParseParamValueL( parsedUrlParameters );
+ iSeek = iSeek + parsedUrlParameters.Length()+ KParameterDelimeterLength;
+ // Check if it is the last chunk in the file
+ if( iSeek+iChunkSize >= iContentSize && !iFileparsed )
+ {
+ iFileparsed = ETrue;
+ }
+ }
+ }
+ //if input is from buffer
+ else
+ if ( parsedUrlParameters != KNullDesC )
+ {
+ ParseParamValueL( parsedUrlParameters );
+ }
+ column++;
+ }
+ }
+ else
+ {
+ // Check if the parsing is from file,if yes then check if there
+ // are more chunks left
+ if( iFileHandle )
+ {
+ if( iSeek+iChunkSize >= iContentSize && !iFileparsed )
+ {
+ // Parse the param values if any
+ ParseParamValueL( *sourceUrl );
+ iSeek = iSeek + sourceUrl->Length();
+ iFileparsed = ETrue;
+ }
+ else
+ {
+ if( sourceUrl->Find( KUrlParameterValueDelimeter ) != KErrNotFound &&
+ ( sourceUrl->Length() == iChunkSize ) )
+ {
+ ParseParamValueL( *sourceUrl );
+ iSeek = iSeek + sourceUrl->Length()+ KParameterDelimeterLength;
+ }
+ else if( sourceUrl->Find( KUrlParameterValueDelimeter ) == KErrNotFound && ( iParamDelimiterParsed == EFalse ) )
+ {
+ iSeek = iSeek + sourceUrl->Length()+ KParameterDelimeterLength;
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( sourceUrl );
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseParamValueL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ParseParamValueL( const TDesC& aParamValue )
+ {
+ // holds the extracted parameter name
+ TPtrC paramName;
+ // holds the extracted parameter value
+ TPtrC paramValue;
+ // Get the param value delimeter position
+ TInt paramValueDelimeterPosition = aParamValue.Find( KUrlParameterValueDelimeter );
+ // Check that the delimeter is found,else leave with KErrPosLmUnknownFormat
+ if( paramValueDelimeterPosition != KErrNotFound )
+ {
+ // Extract the param name
+ paramName.Set( aParamValue.Mid( 0, paramValueDelimeterPosition ) );
+ // Extract the param value
+ paramValue.Set( aParamValue.Mid( paramValueDelimeterPosition+KParameterDelimeterLength,
+ ( aParamValue.Length() -
+ ( paramValueDelimeterPosition+KParameterDelimeterLength ) ) ) );
+ //Coverting the paramname to TDesC8
+ HBufC8* paramName8 = HBufC8::NewLC( paramName.Length() );
+ paramName8->Des().Copy( paramName );
+ //Convering the paramValue to TDesC8
+ HBufC8* paramValue8 = HBufC8::NewLC( paramValue.Length() );
+ paramValue8->Des().Copy( paramValue );
+ // Compare the param values
+ CompareParamValueL( *paramName8,*paramValue8 );
+ CleanupStack::PopAndDestroy( 2, paramName8 );
+ }
+ else
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::CompareParamValueL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::CompareParamValueL( const TDesC8& aParam, const TDesC8& aValue )
+ {
+ iParamDelimiterParsed = EFalse;
+
+ // Compare the param name with the possible parameter values
+ if( !aParam.CompareC( KUrlLatitude ) )
+ {
+ // Check if the latitude param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iLatitudeParsed )
+ {
+ // Indicates that the latitude has been parsed once
+ iLatitudeParsed = ETrue;
+ SetLatLongParamL( aValue, iParsedLatitudeValue, ELatitude );
+ }
+ }
+ else if( !aParam.CompareC( KUrlLongitude ) )
+ {
+ // Check if the longitude param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iLongitudeParsed )
+ {
+ // Indicates that the longitude has been parsed once
+ iLongitudeParsed = ETrue;
+ SetLatLongParamL( aValue, iParsedLongitudeValue, ELongitude );
+ }
+ }
+ else if( !aParam.CompareC( KUrlAltitude ) )
+ {
+ // Check if the altitude param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iAltitudeParsed )
+ {
+ // Indicates that the altitude has been parsed once
+ iAltitudeParsed = ETrue;
+ SetNumberParamL( aValue, iParsedAltitudeValue );
+ }
+ }
+ else if( !aParam.CompareC( KUrlPositionAccuracy ) )
+ {
+ // Check if the position accuracy param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iPositionAccuracyParsed )
+ {
+ // Indicates that the position accuracy has been parsed once
+ iPositionAccuracyParsed = ETrue;
+ SetNumberParamL( aValue, iParsedPositionAccuracyValue );
+ }
+ }
+ else if( !aParam.CompareC( KUrlAltitudeAccuracy ) )
+ {
+ // Check if the altiude accuracy param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iAltitudeAccuracyParsed )
+ {
+ // Indicates that the altitude accuracy has been parsed once
+ iAltitudeAccuracyParsed = ETrue;
+ SetNumberParamL( aValue, iParsedAltitudeAccuracyValue );
+ }
+ }
+ else if( !aParam.CompareC( KUrlSpeed ) )
+ {
+ // Check if the speed param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iSpeedParsed )
+ {
+ // Indicates that the speed has been parsed once
+ iSpeedParsed = ETrue;
+ SetPositionFieldNumberParamL( aValue, ESpeed );
+ }
+ }
+ else if( !aParam.CompareC( KUrlHeading ) )
+ {
+ // Check if the heading param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iHeadingParsed )
+ {
+ // Indicates that the heading has been parsed once
+ iHeadingParsed = ETrue;
+ SetPositionFieldNumberParamL( aValue, EHeading );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlName ) )
+ {
+ // Check if the name param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iNameParsed )
+ {
+ // Indicates that the name has been parsed once
+ iNameParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EName );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlStreet ) )
+ {
+ // Check if the street param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iStreetParsed )
+ {
+ // Indicates that the street has been parsed once
+ iStreetParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EStreet );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlHouseNumber ) )
+ {
+ // Check if the housenumber param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iHouseNumberParsed )
+ {
+ // Indicates that the housenumber has been parsed once
+ iHouseNumberParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EHouseNumber );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlPostalCode ) )
+ {
+ // Check if the PostalCode param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iPostalCodeParsed )
+ {
+ // Indicates that the PostalCode has been parsed once
+ iPostalCodeParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EPostalCode );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlCity ) )
+ {
+ // Check if the city param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iCityParsed )
+ {
+ // Indicates that the city has been parsed once
+ iCityParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, ECity );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlState ) )
+ {
+ // Check if the State param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iStateParsed )
+ {
+ // Indicates that the State has been parsed once
+ iStateParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EState );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlCountry ) )
+ {
+ // Check if the Country param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iCountryParsed )
+ {
+ // Indicates that the Country has been parsed once
+ iCountryParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, ECountry );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlTelephone ) )
+ {
+ // Check if the Telephone param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iTelephoneParsed )
+ {
+ // Indicates that the Telephone has been parsed once
+ iTelephoneParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, ETelephone );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlWebUrl ) )
+ {
+ // Check if the WebUrl param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iWebUrlParsed )
+ {
+ // Indicates that the WebUrl has been parsed once
+ iWebUrlParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EWebUrl );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlDescription ) )
+ {
+ // Check if the Description param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iDescriptionParsed )
+ {
+ // Indicates that the Description has been parsed once
+ iDescriptionParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxDescriptionLength, EDescription );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlPlaceId ) )
+ {
+ // Check if the PlaceId param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iPlaceIdParsed )
+ {
+ // Indicates that the PlaceId has been parsed once
+ iPlaceIdParsed = ETrue;
+ SetTextParamL( aValue, KPosLmMaxTextFieldLength, EPlaceId );
+ }
+ }
+ else if ( !aParam.CompareC( KUrlTimestamp ) )
+ {
+ SetTimestampParamL( aValue );
+ }
+ else if ( !aParam.CompareC( KUrlCategory ) )
+ {
+ SetCategoryParamL( aValue );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetLatLongParamL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetLatLongParamL( const TDesC8& aParsedValue, TReal64& aValue,
+ TInt aField )
+ {
+ // holds the parsed number in text form
+ TBuf<KRealWidth> parsedNumber;
+ // Check that value exists,else leave with KErrPosLmUnknownFormat since the
+ // latitude & longitude field is mandatory
+ if( aParsedValue == KNullDesC8 )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ // Convert the descriptor obtained into real and check if the value is
+ // indeed real.
+ TRAPD( error, PosLmConverterUtils::DesToRealL( aParsedValue, aValue ) );
+ if( error != KErrNone )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ TInt length = parsedNumber.Num( aValue, iRealFormatCoordinates );
+ if( !length )
+ {
+ User::Leave( length );
+ }
+ TRAPD( err, PosLmConverterUtils::DesToRealL( parsedNumber, aValue ) );
+ // check the value with the allowed range for latitude & longitude
+ switch( aField )
+ {
+ case ELatitude :
+ {
+ if( err || !( aValue >= KMinLatitude
+ && aValue <= KMaxLatitude ) )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ break;
+ }
+ case ELongitude :
+ {
+ if( err || !( aValue >= KMinLongitude
+ && aValue <= KMaxLongitude ) )
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ break;
+ }
+ default :
+ {
+ break;
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetNumberParamL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetNumberParamL( const TDesC8& aParsedValue, TReal32& aValue )
+ {
+ // holds the parsed number in text form
+ TBuf<KRealWidth> parsedValue;
+ // Check that value exists
+ if( aParsedValue != KNullDesC8 )
+ {
+ // Convert the descriptor obtained into real and check if the value is
+ // indeed real.
+ TRAPD( error, PosLmConverterUtils::DesToRealL( aParsedValue, aValue ) );
+ if( !error )
+ {
+ TInt length = parsedValue.Num( aValue, iRealFormat );
+ if( length != KErrGeneral )
+ {
+ TRAPD( error, PosLmConverterUtils::DesToRealL( parsedValue, aValue ) );
+ if( error )
+ {
+ PosLmConverterUtils::SetNaN( aValue );
+ }
+ }
+ else
+ {
+ PosLmConverterUtils::SetNaN( aValue );
+ }
+ }
+ else
+ {
+ PosLmConverterUtils::SetNaN( aValue );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetPositionFieldNumberParamL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetPositionFieldNumberParamL( const TDesC8& aParsedValue, TInt aField )
+ {
+ // holds the parsed number in text form
+ TBuf<KRealWidth> parsedValue;
+ // holds the number value in real32
+ TReal32 number;
+ // Check that value exists
+ if( aParsedValue != KNullDesC8 )
+ {
+ // Convert the descriptor obtained into real and check if the value is
+ // indeed real.
+ TRAPD( error, PosLmConverterUtils::DesToRealL( aParsedValue, number ) );
+ if( !error )
+ {
+ TInt length = parsedValue.Num( number, iRealFormat );
+ if( length != KErrGeneral )
+ {
+ // set the position field for apped or heading depending
+ // on the field value that is passed
+ switch( aField )
+ {
+ case ESpeed :
+ {
+ TInt error = KErrNone;
+ TRAP( error, iParsedLandmark->SetPositionFieldL(
+ EPositionFieldHorizontalSpeed, parsedValue ) );
+ break;
+ }
+ case EHeading :
+ {
+ TInt err = KErrNone;
+ TRAP( err, iParsedLandmark->SetPositionFieldL(
+ EPositionFieldHeading, parsedValue ) );
+ break;
+ }
+ default :
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetTextParamL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetTextParamL( const TDesC8& aParsedValue, const TInt aMaxParseValueLength,
+ TInt aField )
+ {
+ // parse the text value
+ HBufC* parsedText = ParseTextL( aParsedValue, aMaxParseValueLength );
+ CleanupStack::PushL( parsedText );
+ // switch on the field & set the corresponding field values
+ switch( aField )
+ {
+ case EName :
+ {
+ iParsedLandmark->SetLandmarkNameL( *parsedText );
+ break;
+ }
+ case EStreet :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldStreet, *parsedText );
+ break;
+ }
+ case EHouseNumber :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldStreetExtension, *parsedText );
+ break;
+ }
+ case EPostalCode :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldPostalCode, *parsedText );
+ break;
+ }
+ case ECity :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldCity, *parsedText );
+ break;
+ }
+ case EState :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldState, *parsedText );
+ break;
+ }
+ case ECountry :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldCountry, *parsedText );
+ break;
+ }
+ case ETelephone :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldBuildingTelephone, *parsedText );
+ break;
+ }
+ case EWebUrl :
+ {
+ iParsedLandmark->SetPositionFieldL( EPositionFieldMediaLinksStart, *parsedText );
+ break;
+ }
+ case EDescription :
+ {
+ iParsedLandmark->SetLandmarkDescriptionL( *parsedText );
+ break;
+ }
+ case EPlaceId :
+ {
+ iParsedLandmark->SetPlaceIdL( *parsedText );
+ break;
+ }
+ default :
+ {
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( parsedText );
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseTextL
+// -----------------------------------------------------------------------------
+//
+HBufC* CPosLmUrlParser::ParseTextL( const TDesC8& aParseValue, const TInt aMaxParseValueLength )
+ {
+ // use a TLex instance to parse the text
+ TLex8 string( aParseValue );
+ // Holds the parsed text value that is returned
+ HBufC* parsedText = HBufC::NewL( aMaxParseValueLength );
+ CleanupStack::PushL( parsedText );
+
+ // Extract each character & validate to check if it is alphadigit,if not then
+ // check for the encoded triplet & decode it
+ while( !string.Eos() )
+ {
+ // Check that the length of the parsed string is not beyond
+ // the max allowed length,if yes then stop parsing.
+ if( parsedText->Length() == aMaxParseValueLength )
+ {
+ break;
+ }
+ TChar character = string.Get();
+
+ // Check if character is alpha digit
+ if( !character.IsAlphaDigit() )
+ {
+ // check for the url escape character
+ if( character == '%' )
+ {
+ // Holds the string to be decoded
+ HBufC* decodeBuffer = HBufC::NewL( KDecodeBufferLength );
+ CleanupStack::PushL( decodeBuffer );
+ // holds the decoded data
+ HBufC* decodedBuffer =NULL;
+ // extract the next 2 characters that follows the escape character
+ decodeBuffer->Des().Append( character );
+ decodeBuffer->Des().Append( string.Get() );
+ decodeBuffer->Des().Append( string.Get() );
+ // decode the escaped sequence and append to parsed buufer if no errors
+ TRAPD( error, decodedBuffer =
+ EscapeUtils::EscapeDecodeL( decodeBuffer->Des() );
+ );
+ if( !error )
+ {
+ parsedText->Des().Append( decodedBuffer->Des() );
+ CleanupStack::PopAndDestroy( decodeBuffer );
+ delete decodedBuffer;
+ }
+ else
+ {
+ User::Leave( KErrPosLmUnknownFormat );
+ }
+ }
+ else
+ {
+ // stop the parsing if any other special character
+ // is encountered.
+ break;
+ }
+
+ }
+ else
+ {
+ // append the aplha digit character to parsed buffer
+ parsedText->Des().Append( character );
+ }
+ }
+
+ CleanupStack::Pop( parsedText );
+
+ return parsedText;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetTimestampParamL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetTimestampParamL( const TDesC8& aParsedValue )
+ {
+ // Check if the timeStamp param has already been parsed once,to avoid
+ // setting the values again incase of repetition of params
+ if( !iTimeStampParsed )
+ {
+ // Indicates that the TimeStamp has been parsed once
+ iTimeStampParsed = ETrue;
+ // holds the extracted date
+ TPtrC8 parsedDate;
+ // holds the extracted full time including microseconds
+ TPtrC8 parsedFullTime;
+ // hold only the time part
+ TPtrC8 parsedTime;
+ // holds the extracted microseconds field
+ TPtrC8 parsedMicroseconds;
+ // Indicates if any error during parsing of date field
+ TInt dateError = KErrNone;
+ // Indicates if any error during parsing of time field
+ TInt timeError = KErrNone;
+ // Indicates if any error during parsing of microseconds field
+ TInt microsecondsError = KErrNone;
+ // holds the parsed date field
+ HBufC* parsedDateBuffer = HBufC::NewL( KMaxDateFieldLength );
+ CleanupStack::PushL( parsedDateBuffer );
+ // holds the parsed time field
+ HBufC* parsedTimeBuffer = HBufC::NewL( KMaxTimeFieldLength );
+ CleanupStack::PushL( parsedTimeBuffer );
+ // holds the parsed microseconds field
+ HBufC* parsedMicrosecondsBuffer = HBufC::NewL( KMaxMicroSecondsLength );
+ CleanupStack::PushL( parsedMicrosecondsBuffer );
+ // holds the parsed date time
+ HBufC* parsedDateTime = HBufC::NewL( KMaxDateTimeBufferLength );
+ CleanupStack::PushL( parsedDateTime );
+
+ // Find the date time delimeter
+ TInt dateTimeDelimeterPosition = aParsedValue.Find( KUrlDateTimeDelimeter );
+ if( dateTimeDelimeterPosition != KErrNotFound )
+ {
+ parsedDate.Set( aParsedValue.Mid( 0, dateTimeDelimeterPosition ) );
+ parsedFullTime.Set( aParsedValue.Mid( dateTimeDelimeterPosition+1,
+ ( aParsedValue.Length() -( dateTimeDelimeterPosition+1 ) ) ) );
+ // Parse the date Field
+ dateError = ParseDate( parsedDate, *parsedDateBuffer );
+
+ // Check that there is no error during date parsing
+ if( !dateError )
+ {
+ // Find the next time delimeter position
+ TInt timeDelimeterPosition = parsedFullTime.Find( KUrlTimeDelimeter );
+ if( timeDelimeterPosition != KErrNotFound )
+ {
+ // Extract the time & microseconds fields separately & parse them
+ parsedTime.Set( parsedFullTime.Mid( 0, timeDelimeterPosition ) );
+ parsedMicroseconds.Set( parsedFullTime.Mid( timeDelimeterPosition+1,
+ parsedFullTime.Length() - ( timeDelimeterPosition+1 ) ) );
+ // parse the time field
+ timeError = ParseTime( parsedTime, *parsedTimeBuffer );
+ // Check that there is no error during time parsing
+ if( !timeError )
+ {
+ // parse the value of microseconds upto 6 digits
+ TLex8 microsecondsString( parsedMicroseconds );
+ while( !microsecondsString.Eos() && ( parsedMicrosecondsBuffer->Length()
+ <= KMaxMicroSecondsLength ) )
+ {
+ // get each character & check if it is a digit
+ TChar microsecondCharacter = microsecondsString.Get();
+ if( microsecondCharacter.IsDigit() )
+ {
+ parsedMicrosecondsBuffer->Des().Append( microsecondCharacter );
+ }
+ else
+ {
+ microsecondsError = KErrGeneral;
+ break;
+ }
+ }
+ }
+ }
+
+ else
+ {
+ timeError = ParseTime( parsedFullTime, *parsedTimeBuffer );
+ }
+ }
+ }
+ else
+ {
+ dateError = ParseDate( aParsedValue, *parsedDateBuffer );
+ }
+
+ // Check if there are any errors during the date parsing before appending
+ // to buffer and setting the timestamp
+ if( !dateError )
+ {
+ parsedDateTime->Des().Append( parsedDateBuffer->Des() );
+ // Check if there are any errors in time parsing before appending
+ if( !timeError )
+ {
+ // Check that the time field exists before appending to buffer
+ if( parsedTimeBuffer->Des() != KNullDesC16 )
+ {
+ parsedDateTime->Des().Append( KDateTimeSeparator );
+ parsedDateTime->Des().Append( parsedTimeBuffer->Des() );
+ // Check if there are no errors inmicroseconds parsing before
+ // appending
+ if( !microsecondsError )
+ {
+ // Check that the microseconds field exists before
+ // appending to the buffer
+ if( parsedMicrosecondsBuffer->Des() != KNullDesC16 )
+ {
+ parsedDateTime->Des().Append( KTimeMicroSecondSeparator );
+ parsedDateTime->Des().Append( parsedMicrosecondsBuffer->Des() );
+ }
+ }
+ }
+ }
+ // convert the parsed date time buffer into a TTime object & set the timestamp
+ // for the parsed landmark
+ TTime timestamp;
+ TInt error = timestamp.Set( parsedDateTime->Des() );
+ // Check that there is no error returned while setting the time
+ if ( !error )
+ {
+ TDateTime dateTime = timestamp.DateTime();
+ // Check that the year & day fields are not zero to avoid
+ // SetTimeStampL from leaving with KErrArgument
+ if( dateTime.Year() && dateTime.Day() )
+ {
+ iParsedLandmark->SetTimeStampL( timestamp );
+ }
+ }
+ }
+ // delete all items on cleanupstack
+ CleanupStack::PopAndDestroy( 4, parsedDateBuffer );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::SetCategoryParamL
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::SetCategoryParamL( const TDesC8& aParsedValue )
+ {
+ TBool categoryPresent = EFalse;
+ // parse the category name
+ HBufC* parsedCategoryValue = ParseTextL( aParsedValue, KPosLmMaxCategoryNameLength );
+ CleanupStack::PushL( parsedCategoryValue );
+
+ // Check that the category name exists before creating a category instance
+ if( *parsedCategoryValue != KNullDesC )
+ {
+ // Check that there are categories present in the parsed category array
+ if ( !iParsedCategories.Count() )
+ {
+ categoryPresent = EFalse;
+ }
+ // Check that the parsed category name is not already present,create
+ // category only with unique names
+ for( TInt i=0;i<iParsedCategories.Count();i++ )
+ {
+ TPtrC existingCategoryName;
+ // Get category name of each of the parsed categories
+ if( !( iParsedCategories[i]->GetCategoryName( existingCategoryName ) ) )
+ {
+ // Compare the existing category name with the newly parsed category
+ // name
+ if( !parsedCategoryValue->Des().CompareC( existingCategoryName ) )
+ {
+ categoryPresent = ETrue;
+ }
+ else
+ {
+ categoryPresent = EFalse;
+ }
+ }
+ }
+ // if the category is not present then create the category instance
+ if( !categoryPresent )
+ {
+ // Create a category instance
+ CPosLandmarkCategory* parsedCategory = CPosLandmarkCategory::NewL();
+ CleanupStack::PushL( parsedCategory );
+ // Check that category id is not equal to any of the reserved global
+ // category ids.If so then increment the id before setting it.
+ if( iParsedCategoryId%3000 == 0 )
+ {
+ iParsedCategoryId++;
+ }
+ // set the category id for the parsed categories
+ PosLmImplExtension::SetCategoryIdL( *parsedCategory, iParsedCategoryId++ );
+
+ // set the category name that has been parsed
+ TPtrC categoryName;
+ categoryName.Set( *parsedCategoryValue );
+ parsedCategory->SetCategoryNameL( categoryName );
+ // Add the category to the parsed landmark
+ iParsedLandmark->AddCategoryL( parsedCategory->CategoryId() );
+ User::LeaveIfError( iParsedCategories.Append( CPosLandmarkCategory::NewL(
+ *parsedCategory ) ) );
+ CleanupStack::PopAndDestroy( parsedCategory );
+ }
+ }
+ CleanupStack::PopAndDestroy( parsedCategoryValue );
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseDate
+// -----------------------------------------------------------------------------
+//
+TInt CPosLmUrlParser::ParseDate( const TDesC8& aParsedDate ,
+ HBufC& aParsedDateBuffer )
+ {
+ TInt error = KErrNone;
+ // parse the date field
+ if( aParsedDate.Length() != KMaxDateFieldLength )
+ {
+ error = KErrGeneral;
+ }
+ else
+ {
+ TLex8 dateString( aParsedDate );
+ while ( !dateString.Eos() )
+ {
+ TChar character = dateString.Get();
+ if( character.IsDigit() )
+ {
+ aParsedDateBuffer.Des().Append( character );
+ }
+ else
+ {
+ error = KErrGeneral;
+ break;
+ }
+ }
+ }
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ParseTime
+// -----------------------------------------------------------------------------
+//
+TInt CPosLmUrlParser::ParseTime( const TDesC8& aParsedTime ,
+ HBufC& aParsedTimeBuffer )
+ {
+ TInt error = KErrNone;
+ // parse the date field
+ if( aParsedTime.Length() != KMaxTimeFieldLength )
+ {
+ error = KErrGeneral;
+ }
+ else
+ {
+ TLex8 timeString( aParsedTime );
+ while ( !timeString.Eos() )
+ {
+ TChar character = timeString.Get();
+ if( character.IsDigit() )
+ {
+ aParsedTimeBuffer.Des().Append( character );
+ }
+ else
+ {
+ error = KErrGeneral;
+ break;
+ }
+ }
+ }
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmUrlParser::ResetUrlParameters
+// -----------------------------------------------------------------------------
+//
+void CPosLmUrlParser::ResetUrlParameters()
+ {
+ // Initialize the coordinate values to NaN
+ PosLmConverterUtils::SetNaN( iParsedLatitudeValue );
+ PosLmConverterUtils::SetNaN( iParsedLongitudeValue );
+ PosLmConverterUtils::SetNaN( iParsedAltitudeValue );
+ PosLmConverterUtils::SetNaN( iParsedPositionAccuracyValue );
+ PosLmConverterUtils::SetNaN( iParsedAltitudeAccuracyValue );
+ // Initialize all the parameters parsed value to be EFalse
+ // during the start of parsing,indicating that the params have
+ // not been parsed yet.
+ iLatitudeParsed = EFalse;
+ iLongitudeParsed = EFalse;
+ iAltitudeParsed = EFalse;
+ iPositionAccuracyParsed = EFalse;
+ iAltitudeAccuracyParsed = EFalse;
+ iSpeedParsed = EFalse;
+ iHeadingParsed = EFalse;
+ iNameParsed = EFalse;
+ iStreetParsed = EFalse;
+ iHouseNumberParsed = EFalse;
+ iPostalCodeParsed = EFalse;
+ iCityParsed = EFalse;
+ iStateParsed = EFalse;
+ iCountryParsed = EFalse;
+ iTelephoneParsed = EFalse;
+ iWebUrlParsed = EFalse;
+ iDescriptionParsed = EFalse;
+ iPlaceIdParsed = EFalse;
+ iTimeStampParsed = EFalse;
+ // initializing the category id
+ iParsedCategoryId = 1;
+ // Reset the parsed categories array
+ iParsedCategories.Reset();
+ iSeek = 0;
+ iFileparsed = EFalse;
+ iParamDelimiterParsed = ETrue;
+ }
+