diff -r 000000000000 -r 8466d47a6819 meetingrequest/mrurlparserplugin/src/cesmrurlparserpluginimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mrurlparserplugin/src/cesmrurlparserpluginimpl.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,506 @@ +/* +* Copyright (c) 2008-2008 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: Parser class for parsing landmarks to url and vice versa +* +*/ + + + +#include "emailtrace.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cesmrurlparserpluginimpl.h" +#include "esmrinternaluid.h" + + +_LIT( KResourceName, "esmrurlparserplugindata.rsc" ); +_LIT( KResourceFileLocFormat, "r%02d" ); +_LIT( KResourceFormat, "rsc" ); + +const TInt KCoordinateMaxLength = 10; +const TInt KNumberOfDecimals = 4; +const TUint KDecimalSeparator = '.'; + + + +// ======== MEMBER FUNCTIONS ======== + + + +// --------------------------------------------------------------------------- +// Non-leaving constructor +// --------------------------------------------------------------------------- +// +CESMRUrlParserPluginImpl::CESMRUrlParserPluginImpl() +: iIsInitialized(EFalse) + { + FUNC_LOG; + + } + + +// --------------------------------------------------------------------------- +// ConstructL for leaving construction +// --------------------------------------------------------------------------- +// +void CESMRUrlParserPluginImpl::ConstructL()// codescanner::LFunctionCantLeave + { + FUNC_LOG; + + } + + +// --------------------------------------------------------------------------- +// Symbian style NewL constructor +// --------------------------------------------------------------------------- +// +CESMRUrlParserPluginImpl* CESMRUrlParserPluginImpl::NewL() + { + FUNC_LOG; + CESMRUrlParserPluginImpl* self = CESMRUrlParserPluginImpl::NewLC(); + CleanupStack::Pop( self ); + return self; + } + + +// --------------------------------------------------------------------------- +// Symbian style NewLC constructor +// --------------------------------------------------------------------------- +// +CESMRUrlParserPluginImpl* CESMRUrlParserPluginImpl::NewLC() + { + FUNC_LOG; + CESMRUrlParserPluginImpl* self = new( ELeave ) CESMRUrlParserPluginImpl; + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CESMRUrlParserPluginImpl::~CESMRUrlParserPluginImpl() + { + FUNC_LOG; + iFile.Close(); + iFs.Close(); + } + +// --------------------------------------------------------------------------- +// Finds location URL from given text input +// --------------------------------------------------------------------------- +// +TInt CESMRUrlParserPluginImpl::FindLocationUrl( const TDesC& aText, + TPtrC& aUrl ) + + { + FUNC_LOG; + TInt pos(0); + TRAPD( error, pos = DoFindLocationUrlL( aText, aUrl ) ); + if ( error != KErrNone ) + { + return error; + } + else + { + return pos; + } + } + +// --------------------------------------------------------------------------- +// Finds location URL from given text input +// --------------------------------------------------------------------------- +// +TInt CESMRUrlParserPluginImpl::DoFindLocationUrlL( // codescanner::intleaves + const TDesC& aText, + TPtrC& aUrl ) + { + FUNC_LOG; + //If this parserplugin instance is not yet initialized + //init it now + if( !iIsInitialized ) + { + InitializeL(); + } + + //Read basestring from resource file + HBufC* baseString = ReadResourceStringLC(R_QTN_LOCATION_URL); + + //Seach if base string is found from aText + TInt urlLocation = aText.Find(*baseString); + CleanupStack::PopAndDestroy(baseString); + if( urlLocation < KErrNone ) + { + User::Leave(KErrNotFound); + } + + //Take out unnecessary part before URL and search if endmark (whitespace) + //is found. If endmark is not found, + //then all the rest of descriptor is part of URL + HBufC* urlAndAfterBuf = aText.Mid( urlLocation ).AllocLC(); + TInt urlAndAfterBufLength = urlAndAfterBuf->Length(); + TInt urlEndmarkLocation = KErrNotFound; + + for( TInt i = 0; i < urlAndAfterBufLength; i++) + { + if( TChar( (*urlAndAfterBuf)[i] ).IsSpace() ) + { + urlEndmarkLocation = i; + break; + } + } + + if( urlEndmarkLocation == KErrNotFound ) + { + urlEndmarkLocation = urlAndAfterBufLength; + } + + //Take out part from beginning of URL to endmark + HBufC* urlToEndMark = urlAndAfterBuf->Left( urlEndmarkLocation ).AllocLC(); + + //Now we should have only URL left, check with "sieve" that it is about in + //right format + HBufC* sieve = ReadResourceStringLC(R_QTN_LOCATION_SIEVE_URL); + TInt sievedStartPoint = urlToEndMark->Match( *sieve ); + + CleanupStack::PopAndDestroy(sieve); + CleanupStack::PopAndDestroy(urlToEndMark); + CleanupStack::PopAndDestroy(urlAndAfterBuf); + + if( sievedStartPoint == KErrNotFound ) + { + User::Leave(KErrNotFound); + } + + //Check that parameters are in right format + TPtrC latValue; + TPtrC lonValue; + + GetCoordinateParamValuesL( aText.Mid(urlLocation,urlEndmarkLocation), + latValue, lonValue ); + CheckCoordinateParamL( latValue ); + CheckCoordinateParamL( lonValue ); + + //Set aURL to correspond URL part of aText and return with url position + aUrl.Set( aText.Mid(urlLocation,urlEndmarkLocation)); + return urlLocation; + } + + +// --------------------------------------------------------------------------- +// Creates location URL from landmark object +// --------------------------------------------------------------------------- +// +HBufC* CESMRUrlParserPluginImpl::CreateUrlFromLandmarkL( + const CPosLandmark& aLandmark ) + { + FUNC_LOG; + //If this parserplugin instance is not yet initialized + //init it now + if( !iIsInitialized ) + { + InitializeL(); + } + + //Take longitude and latitude out of landmark + TLocality position; + User::LeaveIfError( aLandmark.GetPosition( position ) ); + TReal64 latitude = position.Latitude(); + TReal64 longitude = position.Longitude(); + + //Define TReal format type + TRealFormat format( KCoordinateMaxLength ); + format.iType = KRealFormatFixed; + format.iPlaces = KNumberOfDecimals; + format.iPoint = TChar(KDecimalSeparator); + + //Read strings from resourcefile + HBufC* baseUrl = ReadResourceStringLC( R_QTN_LOCATION_URL ); + HBufC* lat = ReadResourceStringLC( R_QTN_LOCATION_URL_LATITUDE ); + HBufC* separator = ReadResourceStringLC( R_QTN_LOCATION_URL_PARAM_SEPARATOR ); + HBufC* lon = ReadResourceStringLC( R_QTN_LOCATION_URL_LONGITUDE ); + + //Concatenate all strings and coordinates + HBufC* url = HBufC::NewL( baseUrl->Length() + lat->Length() + separator->Length() + + lon->Length() + format.iWidth + format.iWidth ); + TPtr pointer = url->Des(); + pointer.Append( *baseUrl ); + pointer.Append( *lat ); + pointer.AppendNum( latitude, format ); + pointer.Append( *separator ); + pointer.Append( *lon ); + pointer.AppendNum( longitude, format ); + + CleanupStack::PopAndDestroy( lon ); + CleanupStack::PopAndDestroy( separator ); + CleanupStack::PopAndDestroy( lat ); + CleanupStack::PopAndDestroy( baseUrl ); + + //Transfer ownership of url + return url; + } + + +// --------------------------------------------------------------------------- +// Creates landmark object from location URL +// --------------------------------------------------------------------------- +// +CPosLandmark* CESMRUrlParserPluginImpl::CreateLandmarkFromUrlL( + const TDesC& aUrl ) + { + FUNC_LOG; + //If this parserplugin instance is not yet initialized + //init it now + if( !iIsInitialized ) + { + InitializeL(); + } + + //Read sieve from resourcefile and check if URL matches the sieveformat + HBufC* sieve = ReadResourceStringLC( R_QTN_LOCATION_SIEVE_URL ); + TInt matchPos = User::LeaveIfError( aUrl.Match( *sieve ) ); + CleanupStack::PopAndDestroy( sieve ); + if( matchPos != 0 ) + { + //URL was found but is not int the beginning of desc + User::Leave( KErrArgument ); + } + + //Parse actual coordinate values out of url + TPtrC latValue; + TPtrC lonValue; + GetCoordinateParamValuesL( aUrl, latValue, lonValue ); + + //Check that parameters are in right format + CheckCoordinateParamL( latValue ); + CheckCoordinateParamL( lonValue ); + + //Convert parameters to TReal values + TLex lexConverter( latValue ); + TReal64 realLatitude; + lexConverter.Val( realLatitude ); + + lexConverter.Assign( lonValue ); + TReal64 realLongitude; + lexConverter.Val( realLongitude ); + + //Create landmark with coordinatevalues + CPosLandmark* landmark = CPosLandmark::NewLC(); + TLocality position; + position.SetCoordinate( realLatitude, realLongitude ); + landmark->SetPositionL( position ); + CleanupStack::Pop( landmark ); + //transfer ownership + return landmark; + } + +// ---------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::LocateResourceFile +// +// For locating resource file +// ---------------------------------------------------------------------------- +// +TInt CESMRUrlParserPluginImpl::LocateResourceFile( + const TDesC& aResource, + const TDesC& aPath, + TFileName &aResourceFile, + RFs* aFs ) + { + FUNC_LOG; + TFindFile resourceFile( *aFs ); + TInt err = resourceFile.FindByDir( + aResource, + aPath ); + + if ( KErrNone == err ) + { + aResourceFile.Copy( resourceFile.File() ); + } + else + { + const TChar KFileFormatDelim( '.' ); + TFileName locResourceFile; + + TInt pos = aResource.LocateReverse( KFileFormatDelim ); + if ( pos != KErrNotFound ) + { + locResourceFile.Copy( aResource.Mid(0, pos + 1) ); + + TInt language( User::Language() ); + locResourceFile.AppendFormat( KResourceFileLocFormat, language ); + + TFindFile resourceFile( *aFs ); + err = resourceFile.FindByDir( + locResourceFile, + aPath ); + + if ( KErrNone == err ) + { + aResourceFile.Copy( resourceFile.File() ); + aResourceFile.Replace( + aResourceFile.Length() - KResourceFormat().Length(), + KResourceFormat().Length(), + KResourceFormat() ); + } + } + } + + + return err; + } + +// ---------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::InitializeL +// +// Initializes resources +// ---------------------------------------------------------------------------- +// +void CESMRUrlParserPluginImpl::InitializeL() + { + FUNC_LOG; + if( iIsInitialized ) + { + return; + } + //Connect to RFs session + User::LeaveIfError( iFs.Connect( KFileServerDefaultMessageSlots ) ); + + //Find and open resource file containing URL strings + TFileName fileName; + User::LeaveIfError( LocateResourceFile( KResourceName, + KDC_RESOURCE_FILES_DIR, + fileName, + &iFs ) ); + iFile.OpenL( iFs, fileName ); + iFile.ConfirmSignatureL(); + iIsInitialized = ETrue; + } + +// ---------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::ReadResourceStringLC +// Reads resource string from specified id +// ---------------------------------------------------------------------------- +// +HBufC* CESMRUrlParserPluginImpl::ReadResourceStringLC( TInt aResourceId ) + { + FUNC_LOG; + HBufC8* string = iFile.AllocReadLC(aResourceId); + iReader.SetBuffer(string); + HBufC* stringBuffer = iReader.ReadTPtrC().AllocL(); + CleanupStack::PopAndDestroy( string ); + CleanupStack::PushL( stringBuffer ); + //stringBuffer ownership is transfered + return stringBuffer; + } + +// ---------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::CheckCoordinateParam +// +// Checks if coordinate parameter (lon or lat) is in correct format +// Leaves if not +// Correct form is: +// -minus sign allowed only in first position +// -only one decimalseparator sign allowed +// -only digits allowed +// -aParam length not allowed to be zero +// ---------------------------------------------------------------------------- +// +void CESMRUrlParserPluginImpl::CheckCoordinateParamL( const TDesC& aParam ) + { + FUNC_LOG; + if( aParam.Length() == 0 ) + { + User::Leave( KErrArgument ); + } + + //check that aParam contains only digits and only one decimalseparator + //and minus sign is first, if it exists + TChar character; + TBool decimalSeparatorFound = EFalse; + TLex lex; + lex.Assign( aParam ); + const TUint KMinusSign = '-'; + + for( TInt i = 0; i < aParam.Length(); i++) + { + character = lex.Get(); + //checks if first character is minus sign and continues if it is + if( i == 0 && (TUint)character == KMinusSign) + { + continue; + } + //check that only one decimalseparator exists + if( (TUint)character == KDecimalSeparator ) + { + if( decimalSeparatorFound ) + { + User::Leave( KErrArgument ); + } + else + { + decimalSeparatorFound = ETrue; + } + } + //check that character is either digit or decimalseparator + if( !( character.IsDigit() ) && (TUint)character != KDecimalSeparator ) + { + User::Leave( KErrArgument ); + } + } + } + +// ---------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::GetCoordinateParamValuesL +// Returns longitude and latitude if found correctly +// ---------------------------------------------------------------------------- +// +void CESMRUrlParserPluginImpl::GetCoordinateParamValuesL( const TDesC& aUrl, + TPtrC& aLatitude, + TPtrC& aLongitude ) + { + FUNC_LOG; + //Read latitude and longitude strings from resourcefile + HBufC* lat = ReadResourceStringLC( R_QTN_LOCATION_URL_LATITUDE ); + HBufC* lon = ReadResourceStringLC( R_QTN_LOCATION_URL_LONGITUDE ); + HBufC* separator = ReadResourceStringLC( R_QTN_LOCATION_URL_PARAM_SEPARATOR ); + + //Find out if lat and lon params and separator exists in aUrl + TInt latPos = aUrl.Find( *lat ); + TInt lonPos = aUrl.Find( *lon ); + TInt separatorPos = aUrl.Find( *separator ); + if( latPos == KErrNotFound || lonPos == KErrNotFound + || separatorPos == KErrNotFound ) + { + User::Leave( KErrNotFound ); + } + + //takes from aUrl parts with actual coordinate data + aLatitude.Set( aUrl.Mid( latPos + lat->Length(), separatorPos - latPos - lat->Length() ) ); + aLongitude.Set( aUrl.Right( aUrl.Length() - separatorPos - 1 - lon->Length() ) ); + + CleanupStack::PopAndDestroy( separator ); + CleanupStack::PopAndDestroy( lon ); + CleanupStack::PopAndDestroy( lat ); + } +//EOF +