diff -r a3a1ae9acec6 -r da5135c61bad meetingrequest/mrurlparserplugin/src/cesmrurlparserpluginimpl.cpp --- a/meetingrequest/mrurlparserplugin/src/cesmrurlparserpluginimpl.cpp Mon Mar 15 12:39:10 2010 +0200 +++ b/meetingrequest/mrurlparserplugin/src/cesmrurlparserpluginimpl.cpp Wed Mar 31 21:08:33 2010 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2008-2008 Nokia Corporation and/or its subsidiary(-ies). +* 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" @@ -17,64 +17,44 @@ -#include "emailtrace.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "cesmrurlparserpluginimpl.h" +#include "cmrurlparserextension.h" -#include "cesmrurlparserpluginimpl.h" -#include "esmrinternaluid.h" - +#include +#include +#include +#include +#include +#include +#include +#include -_LIT( KResourceName, "esmrurlparserplugindata.rsc" ); -_LIT( KResourceFileLocFormat, "r%02d" ); -_LIT( KResourceFormat, "rsc" ); +#include "emailtrace.h" -const TInt KCoordinateMaxLength = 10; -const TInt KNumberOfDecimals = 4; -const TUint KDecimalSeparator = '.'; - - +namespace +{ +_LIT8( KLandmarkUrlMimeType, "maps.ovi.com" ); +} // ======== MEMBER FUNCTIONS ======== - - // --------------------------------------------------------------------------- -// Non-leaving constructor +// CESMRUrlParserPluginImpl::CESMRUrlParserPluginImpl // --------------------------------------------------------------------------- // CESMRUrlParserPluginImpl::CESMRUrlParserPluginImpl() -: iIsInitialized(EFalse) { FUNC_LOG; - } - // --------------------------------------------------------------------------- -// ConstructL for leaving construction -// --------------------------------------------------------------------------- -// -void CESMRUrlParserPluginImpl::ConstructL()// codescanner::LFunctionCantLeave - { - FUNC_LOG; - - } - - -// --------------------------------------------------------------------------- -// Symbian style NewL constructor +// CESMRUrlParserPluginImpl::NewL // --------------------------------------------------------------------------- // CESMRUrlParserPluginImpl* CESMRUrlParserPluginImpl::NewL() { FUNC_LOG; + CESMRUrlParserPluginImpl* self = CESMRUrlParserPluginImpl::NewLC(); CleanupStack::Pop( self ); return self; @@ -82,41 +62,48 @@ // --------------------------------------------------------------------------- -// Symbian style NewLC constructor +// CESMRUrlParserPluginImpl::NewLC // --------------------------------------------------------------------------- // CESMRUrlParserPluginImpl* CESMRUrlParserPluginImpl::NewLC() { FUNC_LOG; + CESMRUrlParserPluginImpl* self = new( ELeave ) CESMRUrlParserPluginImpl; CleanupStack::PushL( self ); - self->ConstructL(); return self; } // --------------------------------------------------------------------------- -// Destructor +// CESMRUrlParserPluginImpl::~CESMRUrlParserPluginImpl // --------------------------------------------------------------------------- // CESMRUrlParserPluginImpl::~CESMRUrlParserPluginImpl() { FUNC_LOG; - iFile.Close(); - iFs.Close(); + + delete iParser; + delete iEncoder; + delete iExtension; + + ReleaseLandmarkResources(); } // --------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::FindLocationUrl // Finds location URL from given text input // --------------------------------------------------------------------------- // -TInt CESMRUrlParserPluginImpl::FindLocationUrl( const TDesC& aText, - TPtrC& aUrl ) +TInt CESMRUrlParserPluginImpl::FindLocationUrl( + const TDesC& aText, + TPtrC& aUrl ) { FUNC_LOG; + TInt pos(0); - TRAPD( error, pos = DoFindLocationUrlL( aText, aUrl ) ); + TRAPD( error, DoFindLocationUrlL( aText, pos, aUrl ) ); if ( error != KErrNone ) { return error; @@ -128,379 +115,216 @@ } // --------------------------------------------------------------------------- -// 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; - } - - -// --------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::CreateUrlFromLandmarkL // Creates location URL from landmark object // --------------------------------------------------------------------------- // -HBufC* CESMRUrlParserPluginImpl::CreateUrlFromLandmarkL( - const CPosLandmark& aLandmark ) +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); + + CPosLandmarkEncoder& encoder = InitializeEncoderL(); + CBufBase* buffer = encoder.SetUseOutputBufferL(); + CleanupStack::PushL( buffer ); + encoder.AddLandmarkL( aLandmark ); + CPosLmOperation* operation = encoder.FinalizeEncodingL(); + ExecuteAndDeleteLD( operation ); - //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 ); - + // Convert URL to Unicode and escape encode non-ASCII characters + HBufC* unicode = EscapeUtils::ConvertToUnicodeFromUtf8L( buffer->Ptr( 0 ) ); + CleanupStack::PushL( unicode ); + HBufC* url = EscapeUtils::EscapeEncodeL( *unicode, EscapeUtils::EEscapeNormal ); + + CleanupStack::PopAndDestroy( 2, buffer ); // unicode + //Transfer ownership of url return url; } // --------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::CreateLandmarkFromUrlL // Creates landmark object from location URL // --------------------------------------------------------------------------- // -CPosLandmark* CESMRUrlParserPluginImpl::CreateLandmarkFromUrlL( - const TDesC& aUrl ) +CPosLandmark* CESMRUrlParserPluginImpl::CreateLandmarkFromUrlL( + const TDesC& aUrl ) { FUNC_LOG; - //If this parserplugin instance is not yet initialized - //init it now - if( !iIsInitialized ) + + CPosLandmark* landmark = NULL; + + // Try to create landmark using landmark parser + TRAPD( error, landmark = CreateLandmarkFromUrlInternalL( aUrl ) ); + + if ( error ) { - 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 ); + // Try extension + landmark = ExtensionL().CreateLandmarkFromUrlL( aUrl ); } - //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 +// CESMRUrlParserPluginImpl::CreateGeoValueLC +// Converts URL to Calendar GEO property // ---------------------------------------------------------------------------- -// -TInt CESMRUrlParserPluginImpl::LocateResourceFile( - const TDesC& aResource, - const TDesC& aPath, - TFileName &aResourceFile, - RFs* aFs ) +// +CCalGeoValue* CESMRUrlParserPluginImpl::CreateGeoValueLC( const TDesC& aUrl ) { 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() ); - } - } - } - + + // Convert URL to landmark + CPosLandmark* landmark = CreateLandmarkFromUrlL( aUrl ); + CleanupStack::PushL( landmark ); - return err; + // Get position data from landmark + TLocality position; + User::LeaveIfError( landmark->GetPosition( position ) ); + CleanupStack::PopAndDestroy( landmark ); + + // Convert position data to GEO value + CCalGeoValue* geoVal = CCalGeoValue::NewL(); + CleanupStack::PushL( geoVal ); + geoVal->SetLatLongL( position.Latitude(), position.Longitude() ); + + return geoVal; } // ---------------------------------------------------------------------------- -// CESMRUrlParserPluginImpl::InitializeL +// CESMRUrlParserPluginImpl::InitializeParserL +// ---------------------------------------------------------------------------- // -// Initializes resources -// ---------------------------------------------------------------------------- -// -void CESMRUrlParserPluginImpl::InitializeL() +CPosLandmarkParser& CESMRUrlParserPluginImpl::InitializeParserL() { FUNC_LOG; - if( iIsInitialized ) + + if ( !iParser ) { - return; + iParser = CPosLandmarkParser::NewL( KLandmarkUrlMimeType ); } - //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; + + return *iParser; } // ---------------------------------------------------------------------------- -// CESMRUrlParserPluginImpl::ReadResourceStringLC -// Reads resource string from specified id +// CESMRUrlParserPluginImpl::InitializeEncoderL // ---------------------------------------------------------------------------- -// -HBufC* CESMRUrlParserPluginImpl::ReadResourceStringLC( TInt aResourceId ) +// +CPosLandmarkEncoder& CESMRUrlParserPluginImpl::InitializeEncoderL() { 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; + + delete iEncoder; + iEncoder = NULL; + iEncoder = CPosLandmarkEncoder::NewL( KLandmarkUrlMimeType ); + return *iEncoder; } -// ---------------------------------------------------------------------------- -// CESMRUrlParserPluginImpl::CheckCoordinateParam +// --------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::DoFindLocationUrlL +// Finds location URL from given text input +// --------------------------------------------------------------------------- // -// 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 ) + +void CESMRUrlParserPluginImpl::DoFindLocationUrlL( + const TDesC& aText, + TInt& aPos, + TPtrC& aUrl ) { FUNC_LOG; - if( aParam.Length() == 0 ) + + aPos = KErrNotFound; + aUrl.Set( KNullDesC ); + + // Search URL from given text + CFindItemEngine* itemEngine = CFindItemEngine::NewL( + aText, + CFindItemEngine::EFindItemSearchURLBin ); + CleanupStack::PushL (itemEngine ); + + // For each found item + CFindItemEngine::SFoundItem item; + itemEngine->Item( item ); + + TInt itemCount = itemEngine->ItemCount(); + for ( TInt i = 0; i < itemCount; ++i ) { - 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) + TPtrC url = aText.Mid( item.iStartPos, item.iLength ); + + CPosLandmark* landmark = NULL; + TRAPD( error, landmark = CreateLandmarkFromUrlL( url ); ) + delete landmark; + + if ( !error ) // Location url found { - continue; + aPos = item.iStartPos; + aUrl.Set( url ); + // Stop iteration + break; } - //check that only one decimalseparator exists - if( (TUint)character == KDecimalSeparator ) + else { - if( decimalSeparatorFound ) - { - User::Leave( KErrArgument ); - } - else - { - decimalSeparatorFound = ETrue; - } + itemEngine->NextItem( item ); } - //check that character is either digit or decimalseparator - if( !( character.IsDigit() ) && (TUint)character != KDecimalSeparator ) - { - User::Leave( KErrArgument ); - } + } + + CleanupStack::PopAndDestroy( itemEngine ); + + if ( aPos < 0 ) + { + ExtensionL().FindLocationUrlL( aText, aUrl, aPos ); } } -// ---------------------------------------------------------------------------- -// CESMRUrlParserPluginImpl::GetCoordinateParamValuesL -// Returns longitude and latitude if found correctly -// ---------------------------------------------------------------------------- -// -void CESMRUrlParserPluginImpl::GetCoordinateParamValuesL( const TDesC& aUrl, - TPtrC& aLatitude, - TPtrC& aLongitude ) +// --------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::ExtensionL +// --------------------------------------------------------------------------- +// +CMRUrlParserExtension& CESMRUrlParserPluginImpl::ExtensionL() { 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 ) + + if ( !iExtension ) { - User::Leave( KErrNotFound ); + iExtension = CMRUrlParserExtension::NewL(); } - - //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() ) ); + + return *iExtension; + } + +// --------------------------------------------------------------------------- +// CESMRUrlParserPluginImpl::CreateLandmarkFromUrlInternalL +// Creates landmark object from location URL +// --------------------------------------------------------------------------- +// +CPosLandmark* CESMRUrlParserPluginImpl::CreateLandmarkFromUrlInternalL( + const TDesC& aUrl ) + { + FUNC_LOG; - CleanupStack::PopAndDestroy( separator ); - CleanupStack::PopAndDestroy( lon ); - CleanupStack::PopAndDestroy( lat ); + // Decode URL and convert it to UTF-8 format + HBufC* decodedUrl = EscapeUtils::EscapeDecodeL( aUrl ); + CleanupStack::PushL( decodedUrl ); + HBufC8* url = EscapeUtils::ConvertFromUnicodeToUtf8L( *decodedUrl ); + CleanupStack::PopAndDestroy( decodedUrl ); + CleanupStack::PushL( url ); + + // Create landmark using correct parser + CPosLandmarkParser& parser = InitializeParserL(); + parser.SetInputBuffer( *url ); + CPosLmOperation* operation = parser.ParseContentL(); + ExecuteAndDeleteLD( operation ); + CPosLandmark* landmark = parser.LandmarkLC(); + CleanupStack::Pop( landmark ); + CleanupStack::PopAndDestroy( url ); + + //transfer ownership + return landmark; } + //EOF