diff -r 000000000000 -r b16258d2340f applayerpluginsandutils/uripermissionservices/server/src/urilistinterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applayerpluginsandutils/uripermissionservices/server/src/urilistinterface.cpp Tue Feb 02 01:09:52 2010 +0200 @@ -0,0 +1,1291 @@ +// Copyright (c) 2007-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: +// + +#include +#include +#include "urilistinterface.h" +#include "sqldbaccessor.h" +#include "ineturiimpl.h" +#include "urilistwritestream.h" +#include "urilist.h" +#include "urilistinitializer.h" +#include "tldlistinitializer.h" +#include "uriqueryfilter.h" +#include "tldproperties.h" +#include +#include "tldlist.h" +#include +#include +#include +#include + +const TInt KMaxLength = 1024; +const TInt pkgId(0x2000A471); +_LIT(KRomDirectory, "z"); +_LIT(KUriListFile, ":\\private\\20009D70\\ineturilist.xml"); +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS +_LIT(KPolicyFile, ":\\private\\20009D70\\tldpolicy.xml"); +#endif //SYMBIAN_ENABLE_SPLIT_HEADERS + +CUriListInterface::CUriListInterface () + { + + } + +CUriListInterface::~CUriListInterface () + { + if ( iDbAccessor ) + { + iDbAccessor->Release (); + } + iStringPool.Close (); + } + +CUriListInterface* CUriListInterface::NewL () + { + CUriListInterface* self = new ( ELeave ) CUriListInterface (); + CleanupStack::PushL ( self ); + self->ConstructL (); + CleanupStack::Pop ( self ); + + return self; + } + + +void CUriListInterface::ConstructL () + { + iStringPool.OpenL ( URILIST::Table ); + iStringPool.OpenL ( TLDLIST::Table ); + iDbAccessor = CSqlDbAccessor::NewL ( iStringPool ); + InitializeDatabaseL (); + } + +/** +Add a new URI and its associated properties into the storage. + +@param aUriStream A stream to read the CInetUriImpl object. +@param aUriId URI Id value that will be returned to the caller +@param aPropId Property Id value that will be returned to the caller + +*/ +void CUriListInterface::AddUriL ( RReadStream& aUriStream, TInt& aUriId, TInt& aPropId ) + { + CInetUriImpl* inetUri = CInetUriImpl::NewL (); + CleanupStack::PushL ( inetUri ); + inetUri->UnpackL ( aUriStream ); + InsertL ( *inetUri ); + aUriId = inetUri->UriId (); + aPropId = inetUri->Properties().PropId (); + CleanupStack::PopAndDestroy ( inetUri ); + } + +/** +Removes the properties from the URIPropertiesTbl. The function removes the URI from the +URITbl table if it is not having a dependency. See the table structure + +@param aUriId URI Id value +@param aPropId Property Id value +*/ +void CUriListInterface::RemoveUriL ( TInt aUriId, TInt aPropId ) + { + iDbAccessor->BeginTransactionL (); + // This is not to delete the object rather to do a rollback operation incase of a failure + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::RollbackTrans, iDbAccessor ) ); + + // Delete from properties table + DeleteL ( KUriPropsTblName(), URILIST::EPropId, aPropId ); + + // The URI also need to be removed if it is not marked for another service type. + // Check for dependency. + if ( CheckDependencyL( aUriId ) ) + { + // No dependency. The URI also need to be removed + DeleteL ( KUriTblName(), URILIST::EId, aUriId ); + } + + // Delete the same from view + DeleteL ( KViewName(), URILIST::EPropId, aPropId ); + iDbAccessor->CommitTransactionL (); + CleanupStack::Pop (); // iDbAccessor + } + +/** +Updates the listtype and favouritename. Only, these 2 properties can be modified. + +@param aUriPropsId Property ID which uniquely identifies the row in the URIPropertiesTbl +@param aListType New Listtype +@param aFavouriteName New favourite name for the URI +*/ +void CUriListInterface::UpdateUriL ( TInt aUriPropsId, InetUriList::TListType aListType, const TDesC8& aFavouriteName ) + { + iDbAccessor->BeginTransactionL (); + // This is not to delete the object rather to do a rollback operation incase of a failure + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::RollbackTrans, iDbAccessor ) ); + + // Only update List Type & Favourite Name. Other properties are not allowed to update. + if ( UpdateL ( KUriPropsTblName(), aUriPropsId, aListType, aFavouriteName ) == 0 ) + User::Leave ( InetUriList::KErrUriNotFound ); + + User::LeaveIfError ( UpdateL ( KViewName(), aUriPropsId, aListType, aFavouriteName ) ); + + iDbAccessor->CommitTransactionL (); + CleanupStack::Pop (); // iDbAccessor + } + +/** +Inserts the information into URITbl, URIPropertiesTbl & the URI view. Checks whether +the URI is already present in the storage and applies the blacklist/whitelist rule +before insertion. + +@param aInetUri URI information object. On return the new property id and URI id will be set. +*/ +void CUriListInterface::InsertL ( CInetUriImpl& aInetUri ) + { + TInt result = KErrNone; + const TUriC8& uri ( aInetUri.Uri().Uri() ); + MDBTransaction* dbTrans = DoSearchExactUriLC ( uri, aInetUri.Properties().ServiceType() ); + if ( dbTrans->Next() ) + { + // URI already exists for the requested service type. + result = InetUriList::KErrUriAlreadyExists; + } + User::LeaveIfError ( result ); + CleanupStack::PopAndDestroy (); // dbTrans + + // Now the URI can be added. + iDbAccessor->BeginTransactionL (); + // This is not to delete the object rather to do a rollback operation incase of a failure + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::RollbackTrans, iDbAccessor ) ); + + TInt uriId = 0; + if ( InsertIntoUriTblL ( aInetUri.Uri().Uri(), uriId ) == 0 ) + User::Leave ( InetUriList::KErrUriAddFailed ); + + aInetUri.SetUriId ( uriId ); + + // Now add the properties + TInt propId = 0; + if ( InsertIntoUriPropsTblL ( aInetUri.UriId(), aInetUri.Properties(), propId ) == 0 ) + User::Leave ( InetUriList::KErrUriAddFailed ); + aInetUri.Properties().SetPropId( propId ); + User::LeaveIfError ( InsertIntoViewL ( aInetUri ) ); + iDbAccessor->CommitTransactionL (); + CleanupStack::Pop (); // iDbAccessor + } + +/** +Inserts the information into TLDTbl. Checks whether +the URI is already present in the storage and applies the blacklist/whitelist rule +before insertion. + +@param aTldPolicydata Tld information object. +*/ +void CUriListInterface::InsertTldPolicyDataL ( CTldProperties& aTldPolicydata ) + { + //First check whether such row is available + //if yes dont insert. + // Now the TLD Policy data can be added. + iDbAccessor->BeginTransactionL (); + // This is not to delete the object rather to do a rollback operation incase of a failure + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::RollbackTrans, iDbAccessor ) ); + //Inserts unique row + if( !IsDuplicateEntryL( aTldPolicydata ) ) + { + InsertIntoTldTblL ( aTldPolicydata ); + } + + iDbAccessor->CommitTransactionL (); + CleanupStack::Pop (); // iDbAccessor + } + +/** +Inserts the data into the URITbl. + +@param aUri URI object +@param [out] aUriId The URI will be filled upon successful insertion. This ID + uniquelly indentifies the URI. + +@return Returns the number of rows inserted. Normally 1. Otherwise returns with + system-wide error code. +*/ +TInt CUriListInterface::InsertIntoUriTblL ( const TUriC8& aUri, TInt& aUriId ) + { + const TDesC8& id ( iStringPool.String (URILIST::EId,URILIST::Table).DesC() ); + aUriId = GetMaxIdValueL ( KUriTblName(), id ) + 1; + _LIT8 ( KUriTblInsertStmt, "INSERT INTO %S VALUES (:V1, :V2, :V3, :V4, :V5, :V6, :V7, :V8)" ); + + RBuf8 sqlStmt; + sqlStmt.CreateL ( KMaxDbStmtLen ); + CleanupClosePushL ( sqlStmt ); + sqlStmt.Format ( KUriTblInsertStmt(), &(KUriTblName()) ); + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( sqlStmt ); + CleanupStack::PopAndDestroy (); // sqlStmt + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + // We are having 8 parameters for this query. First bind the query with parameter position 0 + // and so on + dbTrans->BindIntL ( URILIST::EId, aUriId ); + dbTrans->BindTextL ( URILIST::EScheme, aUri.IsPresent(EUriScheme) ? aUri.Extract ( EUriScheme ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EUserInfo, aUri.IsPresent(EUriUserinfo) ? aUri.Extract ( EUriUserinfo ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EHost, aUri.IsPresent(EUriHost) ? aUri.Extract ( EUriHost ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EPort, aUri.IsPresent(EUriPort) ? aUri.Extract ( EUriPort ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EPath, aUri.IsPresent(EUriPath) ? aUri.Extract ( EUriPath ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EQuery, aUri.IsPresent(EUriQuery) ? aUri.Extract ( EUriQuery ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EFragments, aUri.IsPresent(EUriFragment) ? aUri.Extract ( EUriFragment ) : KNullDesC8() ); + + TInt result = dbTrans->ExecuteL (); + CleanupStack::PopAndDestroy (); //dbTrans + return result; + } + +/** +Inserts the data into the TLDTbl. + +@return Returns the number of rows inserted. Normally 1. Otherwise returns with + system-wide error code. +*/ +TInt CUriListInterface::InsertIntoTldTblL ( const CTldProperties& aTldProps ) + { + _LIT8 ( KTldTblInsertStmt, "INSERT INTO %S VALUES ( :V1, :V2, :V3 )" ); + RBuf8 sqlStmt; + sqlStmt.CreateL ( KMaxDbStmtLen ); + CleanupClosePushL ( sqlStmt ); + sqlStmt.Format ( KTldTblInsertStmt(), &(KTldTblName()) ); + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( sqlStmt ); + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->BindTextL ( TLDLIST::ETLDName, aTldProps.TldName() ); + TInt lt = static_cast ( aTldProps.ListType() ) ; + dbTrans->BindIntL ( TLDLIST::EListType, lt ); + dbTrans->BindTextL ( TLDLIST::ECharacterSet, aTldProps.CharacterSet() ); + TInt result = dbTrans->ExecuteL (); + CleanupStack::PopAndDestroy (2); // sqlStmt, dbTrans + return result; + } + +/** +Checks whether the duplicate entry in the TLDTbl. + +@return ETrue if already such row exist else retrns EFalse +*/ +TBool CUriListInterface::IsDuplicateEntryL ( const CTldProperties& aTldProps ) + { + _LIT8 ( KTldTblSearchStmt, "SELECT * FROM %S WHERE %S=:V1 and %S=:V2" ); + const TDesC8& KTldName (iStringPool.String (TLDLIST::ETLDName,TLDLIST::Table).DesC()); + const TDesC8& KTldListType (iStringPool.String (TLDLIST::EListType,TLDLIST::Table).DesC()); + RBuf8 sqlStmt; + sqlStmt.CreateL ( KMaxDbStmtLen ); + CleanupClosePushL ( sqlStmt ); + sqlStmt.Format ( KTldTblSearchStmt(), &(KTldTblName()), &KTldName, &KTldListType ); + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( sqlStmt ); + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->BindTextL ( TLDLIST::ETLDName, aTldProps.TldName() ); + TInt lt = static_cast ( aTldProps.ListType() ) ; + dbTrans->BindIntL ( TLDLIST::EListType, lt ); + TBool result( dbTrans->Next () ); + CleanupStack::PopAndDestroy (2); // sqlStmt, dbTrans + return result; + } + +/** +Inserts the data into the URIPropertiesTbl. + +@param aUri URI object +@param [out] aUriId The URI will be filled upon successful insertion. This ID + uniquelly indentifies the URI. + +@return Returns the number of rows inserted. Normally 1. Otherwise returns with + system-wide error code. +*/ +TInt CUriListInterface::InsertIntoUriPropsTblL ( TInt aUriId, const CInetUriProperties& aUriProps, TInt& aPropId ) + { + const TInt KMaxLen = 128; + const TDesC8& propId ( iStringPool.String (URILIST::EPropId,URILIST::Table).DesC() ); + aPropId = GetMaxIdValueL ( KUriPropsTblName(), propId ) + 1; + _LIT8 ( KInsertStmt, "INSERT INTO %S VALUES (%d, %d, %d, %d, %d, :V1)"); + RBuf8 queryBuf; + CleanupClosePushL (queryBuf); + queryBuf.CreateL ( KMaxLen ); + queryBuf.AppendFormat ( KInsertStmt, &(KUriPropsTblName()), aUriId, aPropId, aUriProps.ServiceType(), aUriProps.ListType(), aUriProps.Permission() ); + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->BindTextL ( 0, aUriProps.FavouriteName () ); // Bind with parameter index 0 + TInt result = dbTrans->ExecuteL (); + CleanupStack::PopAndDestroy (2); // queryBuf, dbTrans + + return result; + } + +/** +Insert the data into the view. The view insertion will happen via a trigger. +The SQLite views are read-only and cannot do any INSERT/DELETE/UPDATE operation directly. + +@param aInetUri The URI information + +@return KErrNone for success else return any of the system wide error code. + +Note: The view insertion execution will not give the number of rows actualy +inserted. It returns KErrNone +*/ +TInt CUriListInterface::InsertIntoViewL ( const CInetUriImpl& aInetUri ) + { + _LIT8 ( KUriViewInsertStmt, "INSERT INTO %S \ + VALUES (:V1, :V2, :V3, :V4, :V5, :V6, :V7, :V8, \ + :V9, :V10, :V11, :V12, :V13)" ); + + RBuf8 sqlStmt; + sqlStmt.CreateL ( KMaxDbStmtLen ); + CleanupClosePushL ( sqlStmt ); + sqlStmt.Format ( KUriViewInsertStmt(), &(KViewName())); + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( sqlStmt ); + CleanupStack::PopAndDestroy (); //sqlStmt + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + // We are having 8 parameters for this query. First bind the query with parameter position 0 + // and so on + dbTrans->BindIntL ( URILIST::EId, aInetUri.UriId() ); + TUriC8 uri ( aInetUri.Uri().Uri() ); + dbTrans->BindTextL ( URILIST::EScheme, uri.IsPresent(EUriScheme) ? uri.Extract ( EUriScheme ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EUserInfo, uri.IsPresent(EUriUserinfo) ? uri.Extract ( EUriUserinfo ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EHost, uri.IsPresent(EUriHost) ? uri.Extract ( EUriHost ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EPort, uri.IsPresent(EUriPort) ? uri.Extract ( EUriPort ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EPath, uri.IsPresent(EUriPath) ? uri.Extract ( EUriPath ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EQuery, uri.IsPresent(EUriQuery) ? uri.Extract ( EUriQuery ) : KNullDesC8() ); + dbTrans->BindTextL ( URILIST::EFragments, uri.IsPresent(EUriFragment) ? uri.Extract ( EUriFragment ) : KNullDesC8() ); + + CInetUriProperties& properties = aInetUri.Properties (); + dbTrans->BindIntL ( URILIST::EPropId - 1, properties.PropId() ); + dbTrans->BindIntL ( URILIST::EServiceType - 1, properties.ServiceType() ); + dbTrans->BindIntL ( URILIST::EListType - 1, properties.ListType() ); + dbTrans->BindIntL ( URILIST::EPermission - 1, properties.Permission() ); + dbTrans->BindTextL ( URILIST::EFavouriteName-1, properties.FavouriteName() ); + + TInt result = dbTrans->ExecuteL (); + CleanupStack::PopAndDestroy (); //dbTrans + return result; + } + + +/** +Updates the URI properties + +@param aSchemaName Schema name - Could be table or view name +@param aPropId Property ID +@param aListType new List type +@param aFavouritename new favourite name. +*/ +TInt CUriListInterface::UpdateL ( const TDesC8& aSchemaName, TInt aPropId, InetUriList::TListType aListType, const TDesC8& aFavouriteName ) + { + const TDesC8& propId ( iStringPool.String (URILIST::EPropId,URILIST::Table).DesC() ); + const TDesC8& listType (iStringPool.String (URILIST::EListType,URILIST::Table).DesC()); + const TDesC8& favouriteName (iStringPool.String (URILIST::EFavouriteName,URILIST::Table).DesC()); + + // Only update List Type & Favourite Name. Other properties are not allowed to update. + _LIT8 ( KUpdateStmt, "UPDATE %S SET %S=%d, %S=:V1 where %S=%d" ); + const TInt KMaxLen = 128; + RBuf8 queryBuf; + CleanupClosePushL ( queryBuf ); + queryBuf.CreateL ( KMaxLen ); + queryBuf.AppendFormat ( KUpdateStmt(), &aSchemaName, &listType, aListType, &favouriteName, &propId, aPropId ); + + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->BindTextL ( 0, aFavouriteName ); + TInt result = dbTrans->ExecuteL (); + CleanupStack::PopAndDestroy (2); // dbTrans, queryBuf + return result; + } + +/** +Counts the number of URIs present in the storage for a given service type & list type +*/ +TInt CUriListInterface::CountUriL ( InetUriList::TServiceType aServiceType, InetUriList::TListType aListType ) + { + + TQueryArgs args ( aServiceType, aListType ); + CUriQueryFilter* queryFilter = QueryL ( args ); + CleanupStack::PushL ( queryFilter ); + TInt count = queryFilter->MatchRecordCountL(); + CleanupStack::PopAndDestroy (); // queryFilter + return count; + } + +/** +Returns the List type associated with the URI and a servicetype +*/ +InetUriList::TListType CUriListInterface::GetListTypeL ( const TDesC8& aUri, InetUriList::TServiceType aSt ) + { + TUriParser8 uriParser; + User::LeaveIfError ( uriParser.Parse ( aUri ) ); + + MDBTransaction* dbTrans = DoSearchExactUriLC ( uriParser, aSt ); + + if ( !dbTrans->Next() ) + { + User::LeaveIfError ( InetUriList::KErrUriNotFound ); + } + InetUriList::TListType lt = static_cast < InetUriList::TListType > ( dbTrans->ColumnIntL ( URILIST::EListType - 1 ) ); + CleanupStack::PopAndDestroy (); // dbTrans + return lt; + } + +/** +Delete the information from the given schema + +@param aSchemaName Table or view name +@param aFieldPos The actual string index in the string table +@param aid ID + +@return +*/ +void CUriListInterface::DeleteL ( const TDesC8& aSchemaName, TInt aFieldPos, TInt aId ) + { + const TInt KMaxLen = 64; + _LIT8 ( KDeleteStmt, "DELETE FROM %S where %S=%d" ); + + const TDesC8& fieldName ( iStringPool.String (aFieldPos,URILIST::Table).DesC() ); + + RBuf8 queryBuf; + CleanupClosePushL ( queryBuf ); + queryBuf.CreateL ( KMaxLen ); + queryBuf.AppendFormat ( KDeleteStmt(), &aSchemaName, &fieldName, aId ); + + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->ExecuteL (); + CleanupStack::PopAndDestroy ( 2 ); // queryBuf, dbTrans + } + +/** +The URI can be added for different servicetypes. Check if it is exist in the table. + +*/ +TBool CUriListInterface::CheckDependencyL ( TInt aId ) + { + const TDesC8& id ( iStringPool.String (URILIST::EId,URILIST::Table).DesC() ); + const TInt KMaxLen = 64; + _LIT8 ( KQueryStmt, "SELECT * FROM %S where %S=%d" ); + RBuf8 queryBuf; + CleanupClosePushL ( queryBuf ); + queryBuf.CreateL ( KMaxLen ); + queryBuf.AppendFormat ( KQueryStmt(), &(KUriTblName()), &id, aId ); + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + TBool result = dbTrans->Next(); + CleanupStack::PopAndDestroy (2); // queryBuf, dbTrans + return result; + } + + +/** +Get the Maximum Id value from the table. + +*/ +TInt CUriListInterface::GetMaxIdValueL ( const TDesC8& aTblName, const TDesC8& aFieldName ) + { + const TInt KMaxLen = 64; + _LIT8 ( KMaxValueQuery, "SELECT MAX(%S) from %S" ); + RBuf8 queryBuf; + CleanupClosePushL ( queryBuf ); + queryBuf.CreateL ( KMaxLen ); + queryBuf.AppendFormat ( KMaxValueQuery, &aFieldName, &aTblName ); + TInt result = iDbAccessor->ExecuteScalarQueryL ( queryBuf ); + CleanupStack::PopAndDestroy (); //queryBuf + return result; + } + +/** +Destroys the transaction object +*/ +void CUriListInterface::DestroyTransObj ( TAny* aPtr ) + { + MDBTransaction* trans = (MDBTransaction*)aPtr; + trans->Release(); + } +/** +Rollback the transaction when a leave happens in insert/delete/update operation +*/ +void CUriListInterface::RollbackTrans ( TAny* aPtr ) + { + MDBAccessor* accessor = (MDBAccessor*)aPtr; + accessor->RollbackTransaction(); + } + +/** +Query for the URI based on service type and listtype. The servicetype and listtype +will be extracted from aQueryArgs +*/ +CUriQueryFilter* CUriListInterface::QueryL ( const TQueryArgs& aQueryArgs ) + { + const TDesC8& serviceType (iStringPool.String (URILIST::EServiceType,URILIST::Table).DesC()); + const TDesC8& listType (iStringPool.String (URILIST::EListType,URILIST::Table).DesC()); + + RBuf8 queryBuf; + InitViewQueryLC (queryBuf); + + TInt st = aQueryArgs.Get ( TQueryArgs::EServiceType ); + TInt lt = aQueryArgs.Get ( TQueryArgs::EListType ); + + if ( lt == KErrNotFound ) + { + _LIT8 (KFmtStr, "%S=%d" ); + queryBuf.AppendFormat ( KFmtStr, &serviceType, st ); + + } + else + { + _LIT8 (KFmtStr, "%S=%d and %S=%d" ); + queryBuf.AppendFormat ( KFmtStr, &serviceType, st, &listType, lt ); + } + + + // Execute the query + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PopAndDestroy (); //queryBuf + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + CUriQueryFilter* queryFilter = CUriQueryFilter::NewL ( dbTrans ); + CleanupStack::Pop (); // dbTrans + + return queryFilter; // return the queryFilter + } + +/** +Fetches the length of the policy data if exists. +*/ +TInt CUriListInterface::PolicyDataLengthL ( const TDesC8& aUri, const TPolicyQueryArgs& aQueryArgs ) + { + CUriQueryFilter* queryFilter = QueryWithTldL ( aUri, aQueryArgs ); + CleanupStack::PushL(queryFilter); + MDBTransaction& dbTrans = queryFilter->DBTransaction(); + TInt resultsLength(0); + if ( dbTrans.Next() && queryFilter->MatchRecordL() ) + { + resultsLength = dbTrans.ColumnTextL ( TLDLIST::ECharacterSet ).Length(); + } + else + { + //Requested Policydata Not available for this TLD + CleanupStack::PopAndDestroy(queryFilter); + User::Leave(InetUriList::KErrInvalidTLD); + } + CleanupStack::PopAndDestroy(queryFilter); + return resultsLength; + } + +/** +Fetches the host type of given uri. +*/ +InetUriList::TListType CUriListInterface::GetHostTypeL (const TDesC8& aUri ) + { + TBool blackListed( EFalse ); + TInt err(KErrNone); + TRAP(err, blackListed = IsBlackListedUriL(aUri) ); + if( err == InetUriList::KErrInvalidTLD ) + { + //No Blacklisted policy data avaialble + TBool whiteListed( EFalse ); + whiteListed = IsWhiteListedUriL(aUri); + blackListed = whiteListed? EFalse : ETrue; + } + //Bundle output Args with "blackListed" flag + return blackListed ? InetUriList::EBlackList : InetUriList::EWhiteList ; + } + +HBufC8* CUriListInterface::QueryTldInfoL(const TDesC8& aUri, const TPolicyQueryArgs& aQueryArgs ) + { + HBufC8* charSet(NULL); + CUriQueryFilter* queryFilter = QueryWithTldL ( aUri, aQueryArgs ); + CleanupStack::PushL(queryFilter); + MDBTransaction& dbTrans = queryFilter->DBTransaction(); + if ( dbTrans.Next() && queryFilter->MatchRecordL() ) + { + charSet = dbTrans.ColumnTextL ( TLDLIST::ECharacterSet ).AllocL(); + } + else + { + //Requested Policydata Not available for this TLD + CleanupStack::PopAndDestroy(queryFilter); + User::Leave(InetUriList::KErrInvalidTLD); + } + CleanupStack::PopAndDestroy(queryFilter); + return charSet; + } + +/** +Query for the Tld based on listtype. The listtype will be extracted from aQueryArgs +*/ +CUriQueryFilter* CUriListInterface::QueryWithTldL (const TDesC8& aUri, const TPolicyQueryArgs& aQueryArgs ) + { + //Etract Tld + HBufC8* tld = ExtractTldL(aUri); + CleanupStack::PushL(tld); + //execute Query Tld + CUriQueryFilter* queryFilter = DoQueryWithTldL ( tld->Des(), aQueryArgs ); + CleanupStack::PopAndDestroy(); //tld + return queryFilter; + } + +/** +Query for the Tld based on listtype. The listtype will be extracted from aQueryArgs +*/ +CUriQueryFilter* CUriListInterface::DoQueryWithTldL ( const TDesC8& aUri, const TPolicyQueryArgs& aQueryArgs ) + { + InetUriList::TTLDQueryType matchType(InetUriList::EPolicyListType); + #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS + if ( aQueryArgs.Get ( TPolicyQueryArgs::ETldQueryType ) != KErrNotFound) + { + matchType = static_cast < InetUriList::TTLDQueryType > ( aQueryArgs.Get ( TPolicyQueryArgs::ETldQueryType ) ); + } + #else + if ( aQueryArgs.IsSet ( TPolicyQueryArgs::ETldQueryType ) ) + { + matchType = static_cast < InetUriList::TTLDQueryType > ( aQueryArgs.Get ( TPolicyQueryArgs::ETldQueryType ) ); + } + #endif //SYMBIAN_ENABLE_SPLIT_HEADERS + __ASSERT_ALWAYS( ( matchType == InetUriList::EPolicyListType || matchType == InetUriList::EPolicyCharSet ), User::Invariant() ); + + const TDesC8& tldName (iStringPool.String (TLDLIST::ETLDName,TLDLIST::Table).DesC()); + const TDesC8& listType (iStringPool.String (TLDLIST::EListType,TLDLIST::Table).DesC()); + + RBuf8 queryBuf; + InitTldQueryLC (queryBuf); + //Do not change the order of this query. Index is created on tldname and list type + _LIT8(KSql, "( %S=:V1 and %S=:V2 ) or ( %S=:V3 and %S=:V2 )" ); + queryBuf.AppendFormat( KSql, &tldName, &listType, &tldName, &listType ); + + //Prepare the query + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PopAndDestroy (); //queryBuf + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + TInt lt = aQueryArgs.Get ( TPolicyQueryArgs::ETldListType ); + RBuf8 upperCaseUri; + upperCaseUri.Create(aUri); + upperCaseUri.UpperCase(); + dbTrans->BindTextL(0, aUri); + dbTrans->BindIntL(1, lt); + dbTrans->BindTextL(2, upperCaseUri ); + + // Execute the query + CUriQueryFilter* queryFilter = CTldPolicyDataFilter::NewL ( dbTrans ); + upperCaseUri.Close(); + CleanupStack::Pop (); // dbTrans + return queryFilter; // return the queryFilter + } + +/** +Query the list with the URI and other specified parameters in the aQueryArgs +*/ +CUriQueryFilter* CUriListInterface::QueryWithUriL ( const TDesC8& aUri, const TQueryArgs& aQueryArgs ) + { + TUriParser8 uriParser; + User::LeaveIfError ( uriParser.Parse ( aUri ) ); + + MDBTransaction* dbTrans = NULL; + CUriQueryFilter* queryFilter = NULL; + + TInt serviceType = aQueryArgs.Get ( TQueryArgs::EServiceType ); + TInt listType = aQueryArgs.Get ( TQueryArgs::EListType ); + InetUriList::TURIMatch matchType = InetUriList::EExact; + #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS + if ( aQueryArgs.Get ( TQueryArgs::EURIMatch ) != KErrNotFound) + matchType = static_cast < InetUriList::TURIMatch > ( aQueryArgs.Get ( TQueryArgs::EURIMatch ) ); + #else + if ( aQueryArgs.IsSet ( TQueryArgs::EURIMatch ) ) + matchType = static_cast < InetUriList::TURIMatch > ( aQueryArgs.Get ( TQueryArgs::EURIMatch ) ); + #endif //SYMBIAN_ENABLE_SPLIT_HEADERS + switch ( matchType ) + { + case InetUriList::EExact: + dbTrans = DoSearchExactUriLC ( uriParser, serviceType, listType ); + queryFilter = CUriQueryFilter::NewL ( dbTrans ); + break; + + case InetUriList::EDomain: + dbTrans = DoSearchUriDomainLC ( uriParser, serviceType, listType ); + queryFilter = CUriDomainFilter::NewL ( dbTrans, uriParser.Extract( EUriHost ) ); + break; + + case InetUriList::EExactPath: + dbTrans = DoSearchUriPathLC (uriParser, matchType, serviceType, listType ); + queryFilter = CUriQueryFilter::NewL ( dbTrans ); + break; + + case InetUriList::EPartialPrefixPath: + case InetUriList::EPartialSuffixPath: + dbTrans = DoSearchUriPathLC (uriParser, matchType, serviceType, listType ); + queryFilter = CUriPathFilter::NewL ( dbTrans, matchType, uriParser.Extract ( EUriPath ) ); + break; + default: + User::Invariant (); + } + CleanupStack::Pop (); // dbTrans + return queryFilter; + } + +/** +Do a exact match in the list for the given uri and servicetype. All URI components +will be matched +*/ +MDBTransaction* CUriListInterface::DoSearchExactUriLC ( const TUriC8& aUri, TInt aServiceType, TInt aListType /* = KErrNotFound */ ) + { + const TDesC8& serviceType (iStringPool.String (URILIST::EServiceType,URILIST::Table).DesC()); + const TDesC8& listType (iStringPool.String (URILIST::EListType,URILIST::Table).DesC()); + + RBuf8 queryBuf; + InitViewQueryLC(queryBuf); + + AppendFieldName ( queryBuf, URILIST::EScheme, aUri, EUriScheme ); + AppendFieldName ( queryBuf, URILIST::EUserInfo, aUri, EUriUserinfo ); + AppendFieldName ( queryBuf, URILIST::EHost, aUri, EUriHost ); + AppendFieldName ( queryBuf, URILIST::EPort, aUri, EUriPort ); + AppendFieldName ( queryBuf, URILIST::EPath, aUri, EUriPath ); + AppendFieldName ( queryBuf, URILIST::EQuery, aUri, EUriQuery ); + AppendFieldName ( queryBuf, URILIST::EFragments, aUri, EUriFragment ); + if ( aListType == KErrNotFound ) + { + _LIT8 ( KStr, "%S=%d" ); + queryBuf.AppendFormat( KStr(), &serviceType, aServiceType ); + } + else + { + _LIT8 ( KStrWithListType, "%S=%d and %S=%d" ); + queryBuf.AppendFormat( KStrWithListType(), &serviceType, aServiceType, &listType, aListType ); + } + TInt bindPos = 0; + + // Prepare the transaction. + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PopAndDestroy (); // queryBuf + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + + if ( aUri.IsPresent(EUriScheme) && aUri.Extract(EUriScheme).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriScheme) ); + if ( aUri.IsPresent(EUriUserinfo) && aUri.Extract(EUriUserinfo).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriUserinfo) ); + if ( aUri.IsPresent(EUriHost) && aUri.Extract(EUriHost).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriHost) ); + if ( aUri.IsPresent(EUriPort) && aUri.Extract(EUriPort).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriPort) ); + if ( aUri.IsPresent(EUriPath) && aUri.Extract(EUriPath).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriPath) ); + if ( aUri.IsPresent(EUriQuery) && aUri.Extract(EUriQuery).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriQuery) ); + if ( aUri.IsPresent(EUriFragment) && aUri.Extract(EUriFragment).Length() ) + dbTrans->BindTextL ( bindPos++, aUri.Extract(EUriFragment) ); + + return dbTrans; + } + +/** +Do a path match. Path match can be EExactPath, EPartialSuffixPath or EPartialPrefixPath. +Only path and scheme components of the URI is considered for this query + +Actual filtering of the query results will be done CUriPathFilter class while sending the results. +*/ +MDBTransaction* CUriListInterface::DoSearchUriPathLC ( const TUriC8& aUri, InetUriList::TURIMatch aMatchType, TInt aServiceType, TInt aListType /* = KErrNotFound */ ) + { + const TDesC8& serviceType (iStringPool.String (URILIST::EServiceType,URILIST::Table).DesC()); + const TDesC8& listType (iStringPool.String (URILIST::EListType,URILIST::Table).DesC()); + const TDesC8& path ( iStringPool.String (URILIST::EPath,URILIST::Table).DesC() ); + const TDesC8& scheme ( iStringPool.String (URILIST::EScheme,URILIST::Table).DesC() ); + + RBuf8 queryBuf; + InitViewQueryLC(queryBuf); + + if ( aMatchType == InetUriList::EExactPath && aListType == KErrNotFound ) + { + // exact path without listtype + _LIT8 ( KFmtStr, "%S=? and %S=%d and %S=?" ); + queryBuf.AppendFormat ( KFmtStr(), &scheme, &serviceType, aServiceType, &path ); + } + else if ( aMatchType == InetUriList::EExactPath ) + { + // exact path with listtype + _LIT8 ( KFmtStr, "%S=? and %S=%d and %S=%d and %S=?" ); + queryBuf.AppendFormat ( KFmtStr(), &scheme, &serviceType, aServiceType, &listType, aListType, &path ); + } + else if ( aListType == KErrNotFound ) + { + // partial path withoutlisttype + _LIT8 ( KFmtStr, "%S=? and %S=%d" ); + queryBuf.AppendFormat ( KFmtStr(), &scheme, &serviceType, aServiceType ); + } + else + { + // partial path with listtype + _LIT8 ( KFmtStr, "%S=? and %S=%d and %S=%d" ); + queryBuf.AppendFormat ( KFmtStr(), &scheme, &serviceType, aServiceType, &listType, aListType ); + } + + // Prepare the transaction. + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PopAndDestroy (); // queryBuf + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->BindTextL ( 0, aUri.Extract ( EUriScheme ) ); // Bind the scheme + if ( aMatchType == InetUriList::EExactPath ) + dbTrans->BindTextL ( 1, aUri.Extract ( EUriPath ) ); // Bind the path + return dbTrans; + } + +/** +Do a domain search. Actual domain query ersults will be done in the CUriDomainFilter class +*/ +MDBTransaction* CUriListInterface::DoSearchUriDomainLC ( const TUriC8& aUri, TInt aServiceType, TInt aListType /* = KErrNotFound */ ) + { + const TDesC8& serviceType (iStringPool.String (URILIST::EServiceType,URILIST::Table).DesC()); + const TDesC8& listType (iStringPool.String (URILIST::EListType,URILIST::Table).DesC()); + const TDesC8& scheme ( iStringPool.String (URILIST::EScheme,URILIST::Table).DesC() ); + RBuf8 queryBuf; + InitViewQueryLC(queryBuf); + + if ( aListType == KErrNotFound ) + { + _LIT8 ( KStr, "%S=? and %S=%d" ); + queryBuf.AppendFormat( KStr(), &scheme, &serviceType, aServiceType ); + } + else + { + _LIT8 ( KStrWithListType, "%S=? and %S=%d and %S=%d" ); + queryBuf.AppendFormat( KStrWithListType(), &scheme, &serviceType, aServiceType, &listType, aListType ); + } + // Prepare the transaction. + MDBTransaction* dbTrans = iDbAccessor->PrepareTransactionL ( queryBuf ); + CleanupStack::PopAndDestroy (); // queryBuf + CleanupStack::PushL ( TCleanupItem ( CUriListInterface::DestroyTransObj, dbTrans ) ); + dbTrans->BindTextL ( 0, aUri.Extract ( EUriScheme ) ); // Bind the scheme + + return dbTrans; + } + + +void CUriListInterface::InitViewQueryLC ( RBuf8& aBuf ) + { + _LIT8 ( KSelectStmt, "SELECT * FROM %S where "); + CleanupClosePushL ( aBuf ); + aBuf.CreateL ( KMaxDbStmtLen ); + aBuf.AppendFormat ( KSelectStmt(), &(KViewName()) ); + } + +void CUriListInterface::InitTldQueryLC ( RBuf8& aBuf ) + { + _LIT8 ( KSelectStmt, "SELECT * FROM %S where "); + CleanupClosePushL ( aBuf ); + aBuf.CreateL ( KMaxDbStmtLen ); + aBuf.AppendFormat ( KSelectStmt(), &(KTldTblName()) ); + } + +void CUriListInterface::AppendFieldName ( RBuf8& aBuf, TInt aTableIndex, const TUriC8& aUri, TUriComponent aComponent ) + { + _LIT8 ( KNormalStr, "%S=? and " ); + _LIT8 ( KIsNullStr, "%S ISNULL and " ); + + const TPtrC8 value ( aUri.IsPresent ( aComponent ) ? aUri.Extract ( aComponent ) : KNullDesC8() ); + if ( value.Length() > 0 ) + { + aBuf.AppendFormat ( KNormalStr(), &(GetFieldName(aTableIndex)) ); + } + else + { + aBuf.AppendFormat ( KIsNullStr(), &(GetFieldName(aTableIndex)) ); + } + } + +const TDesC8& CUriListInterface::GetFieldName ( TInt aTableIndex ) + { + return iStringPool.String ( aTableIndex,URILIST::Table ).DesC(); + } + +void CUriListInterface::BindTextL ( MDBTransaction& aDbTrans, TInt aBindPos, const TUriC8& aUri, TUriComponent aComponent ) + { + TPtrC8 valuePtr ( KNullDesC8() ); + if ( aUri.IsPresent (aComponent) ) + valuePtr.Set( aUri.Extract ( aComponent ) ); + + aDbTrans.BindTextL ( aBindPos, (valuePtr.Length() == 0) ? KNullDesC8() : valuePtr ); + } + +/** +Initializes the database(if it is empty) from the pre-configured XML file. + +*/ +void CUriListInterface::InitializeDatabaseL () + { + const TDesC8& id ( iStringPool.String (URILIST::EId,URILIST::Table).DesC() ); + if ( GetMaxIdValueL ( KViewName(), id ) != 0 ) + { + // Database already created and thre are some values already added. + //Update with Policyfile installed, after rebooting the server. + UpgradePolicyDatabaseL(); + return; + } + // Otherwise go and read the XML file, if exists and populate the data fields + TBuf uriListFilePath; + uriListFilePath.FillZ(); + //if uriListFilePath is Null then SIS file is not installed + GetInstalledDirectoryL( TUid::Uid(pkgId), KUriListFile(), uriListFilePath ); + CUriListInitializer* listInitializer = CUriListInitializer::NewL ( *this ); + CleanupStack::PushL ( listInitializer ); + TInt err( KErrNone ); + if(uriListFilePath.CompareF(KNullDesC) != 0) + { + //File ineturilist.xml exist in external path. + TRAP ( err, listInitializer->ParseDocumentL ( uriListFilePath ) ); + } + CleanupStack::PopAndDestroy (); // listInitializer + if ( err != KErrNotFound && err != KErrPathNotFound ) + { + // File found and some other error. leave + User::LeaveIfError ( err ); + } + //initialise Policy data + InitializePolicyDatabaseL(); + } + + +/** +Initializes the database to default policy data if it is available in ROM. +If a valid upgraded policy file exist then, database will be updated to later version. +*/ +void CUriListInterface::InitializePolicyDatabaseL () + { + //Install the file with ROM Policy data if ROM file exists + _LIT( KDefaultFilePath, "z:\\private\\20009d70\\tldpolicy.xml"); + if( FileExist( KDefaultFilePath() ) ) + { + CTldListInitializer* tldlistInitializer = CTldListInitializer::NewL ( *this ); + CleanupStack::PushL ( tldlistInitializer ); + TRAPD ( policyfileerr, tldlistInitializer->ParseDocumentL ( KDefaultFilePath() ) ); + CleanupStack::PopAndDestroy (); //tldlistInitializer + if ( policyfileerr != KErrNotFound && policyfileerr != KErrPathNotFound ) // File found and some other error. leave + { + User::LeaveIfError ( policyfileerr ); + } + } + + UpgradePolicyDatabaseL(); + } + +/** +Database will be updated with the Policy file installed. +*/ +void CUriListInterface::UpgradePolicyDatabaseL() + { + //Upgrade DB if Policy file is installed + //Get the Installed file path + _LIT(KTldPolicyFile, "c:\\private\\20009d70\\tldpolicy.xml"); + if(!FileExist( KTldPolicyFile() )) + { + return; + } + //Upgrade DB + CTldListInitializer* tldListUpgrader = CTldListInitializer::NewL ( *this ); + CleanupStack::PushL ( tldListUpgrader ); + TRAPD ( fileerr, tldListUpgrader->ParseDocumentL ( KTldPolicyFile() ) ); + CleanupStack::PopAndDestroy ();//tldListUpgrader + if ( fileerr != KErrNotFound && fileerr != KErrPathNotFound ) // File found and some other error. leave + { + User::LeaveIfError ( fileerr ); + } + } + +/** +Get the external file path installed out of ROM. +out parameter -- aFilePath +*/ +void CUriListInterface::GetInstalledDirectoryL(const TUid aUid, const TDesC& aFile, TDes& aFilePath ) + { + __ASSERT_DEBUG( aFile.CompareF( KNullDesC ) !=0, User::Invariant( ) ); + Swi::RSisRegistrySession session; + if(session.Connect( ) != KErrNone) + { + //Sis Not Installed + session.Close(); + return; + } + CleanupClosePushL( session ); + TBool installed = session.IsInstalledL( aUid ); + Swi::RSisRegistryEntry registryEntry; + TInt error = registryEntry.Open( session, aUid ); + CleanupClosePushL( registryEntry ); + TBool available = EFalse; + if ( error == KErrNone ) + { + RPointerArray files; + // get list of files + TRAPD( err, registryEntry.FilesL( files ) ); + if (err != KErrNone) + { + files.ResetAndDestroy(); + CleanupStack::PopAndDestroy(2); // ®istryEntry, &session + User::Leave(err); + } + TInt filesCount = files.Count(); + for (TInt index = 0; index < filesCount; index++) + { + TBuf fileNameBuf(KNullDesC); + fileNameBuf.Copy(files[index]->Des()); + TInt pos = fileNameBuf.FindF(aFile); + if( pos >= 0 && !available && fileNameBuf.Left(pos).CompareF(KRomDirectory)!=0 ) + { + aFilePath.Copy(fileNameBuf); + available = ETrue; + break; + } + } + files.ResetAndDestroy(); + } + CleanupStack::PopAndDestroy(2); // ®istryEntry, &session + } + +/** +Checks if the specified file exists. + +@param aFileName File to check +@return ETrue if the file exists, otherwise EFalse +*/ +TBool CUriListInterface::FileExist(const TDesC& aFilePath) + { + RFs iFs; + TBool result( EFalse ); + TInt error = iFs.Connect(); + if( !error ) + { + result = BaflUtils::FileExists( iFs, aFilePath ); + } + iFs.Close(); + return result; + } + +/** +return ETrue if Uri is BlackListed, else return EFalse +Leaves with KErrNotSupported if No Policydata is available +*/ +TBool CUriListInterface::IsBlackListedUriL( const TDesC8& aUri ) + { + TBool blackListed(EFalse); + TPolicyQueryArgs blackListArgs ( InetUriList::EBlackList, InetUriList::EPolicyCharSet ); + CUriQueryFilter* queryFilter = QueryWithTldL ( aUri, blackListArgs ); + CleanupStack::PushL(queryFilter); + MDBTransaction& dbTrans = queryFilter->DBTransaction(); + if ( dbTrans.Next() && queryFilter->MatchRecordL() ) + { + const TDesC8& charSet = dbTrans.ColumnTextL ( TLDLIST::ECharacterSet ); + //Policy file contains empty body for Requested white/Black listed data + __ASSERT_ALWAYS( charSet.Length() > 0, User::Invariant() ); + RArray policyCharList; + CleanupClosePushL(policyCharList); + //Tokenize the results + TokenizeStringL( charSet, policyCharList); + //Get the host and check whether any of these char is in PolicyCharList + HBufC8* host = ExtractHostL(aUri); + CleanupStack::PushL(host); + blackListed = IsBlackListedHost( host->Des(), policyCharList ); + CleanupStack::PopAndDestroy(2); //host, PolicyCharList + } + else + { + //Requested Policydata Not available for this TLD + CleanupStack::PopAndDestroy(queryFilter); + User::Leave(InetUriList::KErrInvalidTLD); + } + CleanupStack::PopAndDestroy(queryFilter); + return blackListed; + } + +/** +return ETrue if Uri is WhiteListed, else return EFalse +Leaves with KErrNotSupported if No Policydata is available +*/ +TBool CUriListInterface::IsWhiteListedUriL( const TDesC8& aUri ) + { + TBool whiteListed (EFalse); + TPolicyQueryArgs whiteListArgs ( InetUriList::EWhiteList, InetUriList::EPolicyCharSet ); + CUriQueryFilter* queryFilter = QueryWithTldL ( aUri, whiteListArgs ); + CleanupStack::PushL(queryFilter); + MDBTransaction& dbTrans = queryFilter->DBTransaction(); + if ( dbTrans.Next() && queryFilter->MatchRecordL() ) + { + const TDesC8& charSet = dbTrans.ColumnTextL ( TLDLIST::ECharacterSet ); + //Policy file contains empty body for Requested white/Black listed data + __ASSERT_ALWAYS( charSet.Length() > 0, User::Invariant() ); + RArray policyCharList; + CleanupClosePushL(policyCharList); + //Tokenize the results + TokenizeStringL(charSet, policyCharList); + //Get the host and check whether any of these char is in PolicyCharList + HBufC8* host = ExtractHostL(aUri); + CleanupStack::PushL(host); + whiteListed = IsWhiteListedHostL( host->Des(), policyCharList ); + CleanupStack::PopAndDestroy(2); // PolicyCharList,host + } + else + { + //Requested Policydata Not available for this TLD + CleanupStack::PopAndDestroy(queryFilter); + User::Leave(InetUriList::KErrInvalidTLD); + } + CleanupStack::PopAndDestroy(queryFilter); + return whiteListed; + } + +/** +returns ETrue if aHost is white listed else returns EFalse +*/ +TBool CUriListInterface::IsWhiteListedHostL( const TDesC8& aHost, RArray& aPolicyList ) + { + //Every character in the host must be in the list + RArray hostCharList; + CleanupClosePushL(hostCharList); + StringToCharListL(aHost, hostCharList); + TBool whiteList(ETrue); + for(TInt index(0); index < hostCharList.Count(); index++ ) + { + if(!IsNextCharInList(hostCharList[index], aPolicyList)) + { + whiteList = EFalse; + break; + } + } + CleanupStack::PopAndDestroy();//hostCharList + return whiteList; + } + +/** +Returns ETrue if aChar is in aPolicyList else returns EFalse +*/ +TBool CUriListInterface::IsNextCharInList(TChar aChar, RArray& aPolicyList) + { + TBool found(EFalse); + for (TInt index(0); index < aPolicyList.Count(); index++) + { + if( aPolicyList[index] == aChar ) + { + found = ETrue; + break; + } + } + return found; + } + +/** +Tokenizes the policydata into characters list +*/ +void CUriListInterface::TokenizeStringL(const TDesC8& aString, RArray& aList, TChar aSeparator) + { + TLex8 lexer(aString); + while(!lexer.Eos()) + { + TChar charcter = lexer.Get(); + if ( charcter != aSeparator && charcter != '\n' && charcter != '\t' ) + { + aList.AppendL(charcter); + } + } + } + +/** +Tokenizes the Host into characters list +*/ +void CUriListInterface::StringToCharListL(const TDesC8& aString, RArray& aList, TChar aSeparator) + { + //Here sepearator is '.' + TokenizeStringL( aString, aList, aSeparator ); + } + +/** +returns ETrue if aHost is Black listed else returns EFalse +*/ +TBool CUriListInterface::IsBlackListedHost( const TDesC8& aHost, RArray& aList ) + { + TBool result( EFalse ); + for(TInt index(0); index < aList.Count(); index++ ) + { + if ( aHost.Locate(aList[index]) >= 0 ) + { + result = ETrue; + break; + } + } + return result; + } + +/** +Extracts the TLD from the given uri. +*/ +HBufC8* CUriListInterface::ExtractTldL( const TDesC8& aUri ) + { + HBufC8* tld = ExtractHostL( aUri ); + CleanupStack::PushL( tld ); + TChar dot('.'); + TInt pos = tld->LocateReverse( dot ); + __ASSERT_DEBUG( ( pos >= 0 ) , User::Invariant() ); + HBufC8* tldPtr = tld->Mid( pos + 1 ).AllocL(); //Excluding dot '.' + CleanupStack::PopAndDestroy( tld ); + return tldPtr; + } + +/** +Extracts the Host from the given uri. +*/ +HBufC8* CUriListInterface::ExtractHostL( const TDesC8& aUri ) + { + TUriParser8 tldUri1; + RBuf8 tld; + RBuf8 customisedUri; + HBufC8* tldPtr; + User::LeaveIfError ( tldUri1.Parse ( aUri ) ); + TBool isSchemePresent = tldUri1.IsPresent( EUriScheme ); + if (!isSchemePresent) + { + _LIT8(KHttp, "http://"); + RBuf8 urirbuf; + urirbuf.CleanupClosePushL(); + urirbuf.CreateL(KHttp,aUri.Length()+7); + urirbuf.Append(aUri); + customisedUri.Create( DoNormalisationLC ( urirbuf ) ); + TUriParser8 tldUri2; + User::LeaveIfError ( tldUri2.Parse ( customisedUri ) ); + __ASSERT_ALWAYS(tldUri2.IsPresent( EUriHost ), User::Invariant()); + tld.Create( tldUri2.Extract(EUriHost) ); + tldPtr = tld.AllocL(); + CleanupStack::PopAndDestroy(2); //calls aRBuf.Close()and DoNormalisationLC pop + + } + else + { + customisedUri.Create( DoNormalisationLC ( aUri ) ); + User::LeaveIfError ( tldUri1.Parse ( customisedUri ) ); + __ASSERT_ALWAYS(tldUri1.IsPresent( EUriHost ), User::Invariant()); + tld.Create( tldUri1.Extract(EUriHost) ); + tldPtr = tld.AllocL(); + CleanupStack::PopAndDestroy ();//objects added in DoNormalisationLC + } + tld.Close(); + customisedUri.Close(); + return tldPtr; + } + +/** +Does the syntax based normalisation. If the MUriCustomiser is set then it customises the URI, +that is, do the protocol/scheme-based normalisation on the URI. The customisation algorithm needs +to be implemented by the application. +*/ +const TDesC8& CUriListInterface::DoNormalisationLC ( const TDesC8& aUri ) + { + // Do a syntax based normalisation + TUriParser8 uriParser; + User::LeaveIfError ( uriParser.Parse ( aUri ) ); + CUri8* normalisedUri = UriUtils::NormaliseUriL ( uriParser ); + CleanupStack::PushL ( normalisedUri ); + return normalisedUri->Uri().UriDes(); + } +