diff -r 000000000000 -r f979ecb2b13e searchfw/coresearchfw/utilities/src/searchtextsearcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/searchfw/coresearchfw/utilities/src/searchtextsearcher.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,593 @@ +/* +* Copyright (c) 2006-2007 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 handling the search of several keywords in a block of +* text. +* +*/ + + + +#include + +#include +#include +#include +#include +#include +#include "searchkeywordstatus.h" +#include "searchalgorithm.h" + +#include + +_LIT(KColon,":"); +const TInt KNumberDataLength( 50 ); +const TInt KTimeDataLength( 50 ); +const TInt KArrayGranularity( 2 ); +const TInt KSingleKeywordInArray( 1 ); + + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::NewL() +// Symbian C++ 2 phase construction +// ----------------------------------------------------------------------------- +// +EXPORT_C CSearchTextSearcher* CSearchTextSearcher::NewL( + MSearchTextSearcherObserver& aObserver ) + { + CSearchTextSearcher* self = CSearchTextSearcher::NewLC( aObserver ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::NewLC() +// Symbian C++ 2 phase construction +// ----------------------------------------------------------------------------- +// +EXPORT_C CSearchTextSearcher* CSearchTextSearcher::NewLC( + MSearchTextSearcherObserver& aObserver ) + { + CSearchTextSearcher* self = new( ELeave ) CSearchTextSearcher( aObserver ); + CleanupStack::PushL( self ); + ( *self ).ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::~CSearchTextSearcher() +// C++ destructor +// ----------------------------------------------------------------------------- +// +CSearchTextSearcher::~CSearchTextSearcher() + { + iKeywordSearchStatusArray.Close(); + + if ( iSearchKeywords8 ) + { + iSearchKeywords8->Reset(); + delete iSearchKeywords8; + iSearchKeywords8 = NULL; + } + + if ( iHaveParameters != TRUE ) + { + iSearchKeywords16->Reset(); + delete iSearchKeywords16; + iSearchKeywords16 = NULL; + } + + if ( iSearchAlgorithm ) + { + delete iSearchAlgorithm; + iSearchAlgorithm = NULL; + } + iClause.Reset(); + iClause.Close(); + FeatureManager::UnInitializeLib(); + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::Cleanup() +// Cleanup Method +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSearchTextSearcher::Cleanup() + { + iKeywordSearchStatusArray.Reset(); + for ( TInt i = 0; i < iKeywordSearchStatusArray.Count() ; i++ ) + { + iKeywordSearchStatusArray[i].iFound = EFalse; + iKeywordSearchStatusArray[i].iFoundAtNthPosition = KErrNotFound; + } + } +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::SetParametersL() +// Sets the search parameters for the search. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSearchTextSearcher::SetParametersL( const MDesCArray& aKeywords, + CSearchTextSearcher::TSearchCriteriaOperator + aOperator, TBool aCaseSensitive ) + { + iSearchKeywords = static_cast( &aKeywords ); + iOperator = aOperator; + iCaseSensitive = aCaseSensitive; + + //convert from 16 - 8 bits for keyword + iSearchKeywords8->Reset(); + iCount = iSearchKeywords->MdcaCount(); + + DoUftTo8BitConversionL( *iSearchKeywords ); + + //initialize keyword status + iKeywordSearchStatusArray.Reset(); + for ( TInt i = 0 ;i < iCount ; i++ ) + { + TKeywordSearchStatus status; + status.iFound = EFalse; + status.iFoundAtNthPosition = KErrNotFound; + iKeywordSearchStatusArray.AppendL( status ); + } + //Set it here to indicate client has called this method + iHaveParameters = ETrue; + if ( iCount == KSingleKeywordInArray) + { + iIsBooleanCondition = EFalse; + } + else + { + iIsBooleanCondition = ETrue; + //SetCriteriaOperator(); not to be called here , dont have clause yet + } + + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::SetParametersL() +// Sets the search parameters based on conditions for the search. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSearchTextSearcher::SetParametersL( const CSearchCondition& + aCondition ) + { + if ( iHaveParameters ) + { + return; + } + else + { + iSearchKeywords16 = new( ELeave ) CDesC16ArrayFlat( KArrayGranularity ); + } + + switch( aCondition.Type() ) + { + case CSearchCondition::EConditionTypeSimple: + { + iOperator = ESearchCriteriaAND; + iIsBooleanCondition = EFalse; + SetSingleConditionDataL( + *(static_cast( &aCondition ) ) ); + } + break; + case CSearchCondition::EConditionTypeBoolean: + { + iOperator = ESearchCriteriaAND; + iIsBooleanCondition = ETrue; + RPointerArray conditions; + (static_cast( &aCondition ) )-> + GetConditions( conditions,iClause ); + + for ( TInt i = 0; i < conditions.Count() ; i++ ) + { + SetSingleConditionDataL( + *(static_cast( conditions[i] ) ) ); + } + iCount = iSearchKeywords16->Count(); + conditions.Reset(); + conditions.Close(); + + SetCriteriaOperator( ); + } + break; + + default: + break; + } + + DoUftTo8BitConversionL( *iSearchKeywords16 ); + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::SearchL() +// Starts the text search with the previous supplied parameters set +// by SetParametersL. 16 bit version. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSearchTextSearcher::SearchL( const TDesC16& aToBeSearchedDes ) + { + iKeywordSearchStatusArray.Reset(); + for ( TInt i = 0 ;i < iCount ; i++ ) + { + TKeywordSearchStatus status; + status.iFound = EFalse; + status.iFoundAtNthPosition = KErrNotFound; + iKeywordSearchStatusArray.AppendL( status ); + } + + if ( iHaveParameters ) + { + DoStringCompareWithKeywordsL( aToBeSearchedDes,*iSearchKeywords, + iKeywordSearchStatusArray,iOperator,iCaseSensitive ); + } + else + { + DoStringCompareWithKeywordsL( aToBeSearchedDes,*iSearchKeywords16, + iKeywordSearchStatusArray,iOperator,iCaseSensitive ); + } + } + + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::SearchL() +// Starts the text search with the previous supplied parameters set by +// SetParametersL. 8 bit version. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSearchTextSearcher::SearchL ( const TDesC8& aToBeSearchedDes ) + { + DoStringCompareWithKeywordsL( aToBeSearchedDes,*iSearchKeywords8, + iKeywordSearchStatusArray,iOperator,iCaseSensitive ); + } + +// ----------------------------------------------------------------------------- +// Set whether searching for the email +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSearchTextSearcher::SearchEmailAddress ( TBool aSearchEmail ) + { + iSearchAlgorithm->SearchEmailAddress ( aSearchEmail ); + } + +// ----------------------------------------------------------------------------- +// Return the search keyword +// ----------------------------------------------------------------------------- +// +EXPORT_C CDesC16ArrayFlat* CSearchTextSearcher::SearchKeyword() + { + return iSearchKeywords16; + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::CSearchTextSearcher() +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CSearchTextSearcher::CSearchTextSearcher( + MSearchTextSearcherObserver& aObserver ) +: iObserver( aObserver ) + { + + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::ConstructL() +// Symbian 2nd phase construction +// ----------------------------------------------------------------------------- +// +void CSearchTextSearcher::ConstructL() + { + iSearchKeywords8 = new(ELeave) CDesC8ArrayFlat( KArrayGranularity ); + iSearchAlgorithm = CSearchAlgorithm::NewL(); + iSearchAlgorithm->SearchEmailAddress( ETrue ); + iHaveParameters = EFalse; + iSameCondition = EFalse; + iIsBooleanCondition = EFalse; + FeatureManager::InitializeLibL(); + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::DoStringCompareWithKeywords() +// Compares the to be searched string with the list of keywords, 16 bit version. +// ----------------------------------------------------------------------------- +// +TBool CSearchTextSearcher::DoStringCompareWithKeywordsL ( + const TDesC& aToBeSearchedDes, + const CDesC16Array& aKeywords, + RArray& aKeywordSearchStatusArray, + CSearchTextSearcher::TSearchCriteriaOperator aOperator, + TBool aCaseSensitive ) + { + iSearchAlgorithm->SearchL( aToBeSearchedDes,aKeywords, + aKeywordSearchStatusArray, + aOperator, + aCaseSensitive ); + if ( aKeywordSearchStatusArray.Count() >= 0 ) + { + if ( iIsBooleanCondition ) + { + CheckForBooleanClausesL( aKeywordSearchStatusArray ); + } + else + { + if ( !aKeywordSearchStatusArray[0].iFound ) + { + iObserver.HitL( KErrNotFound ); + } + else + { + iObserver.HitL( aKeywordSearchStatusArray[0].iFoundAtNthPosition ); + } + } + } + + return TRUE; + } + + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::DoStringCompareWithKeywords() +// Compares the to be searched string with the list of keywords, 8 bit version. +// ----------------------------------------------------------------------------- +// +TBool CSearchTextSearcher::DoStringCompareWithKeywordsL ( + const TDesC8& aToBeSearchedDes, + const CDesC8Array& aKeywords, + RArray& aKeywordSearchStatusArray, + CSearchTextSearcher::TSearchCriteriaOperator aOperator, + TBool aCaseSensitive ) + { + iSearchAlgorithm->SearchL( aToBeSearchedDes,aKeywords, + aKeywordSearchStatusArray,aOperator, aCaseSensitive ); + if ( aKeywordSearchStatusArray.Count() >= 0 ) + { + if ( iIsBooleanCondition ) + { + CheckForBooleanClausesL( aKeywordSearchStatusArray ); + } + else + { + if ( !aKeywordSearchStatusArray[0].iFound ) + { + iObserver.HitL( KErrNotFound ); + } + else + { + iObserver.HitL( aKeywordSearchStatusArray[0].iFoundAtNthPosition ); + } + } + } + return TRUE; + } + + // ----------------------------------------------------------------------------- +// CSearchTextSearcher::SetSingleConditionDataL() +// Sets the singlecondition data for the search. +// ----------------------------------------------------------------------------- +// +void CSearchTextSearcher::SetSingleConditionDataL ( const + CSearchSingleCondition& aSingleCondition ) + { + const CSearchField& field = aSingleCondition.Term(); + switch ( field.DataType() ) + { + case ESearchFieldDataTypeUnknown: + break; + case ESearchFieldDataTypeTInt: + { + TInt intData; + field.GetData( intData ); + HBufC* pbuf = HBufC::NewLC( KNumberDataLength ); + pbuf->Des().AppendNum( intData ); + iSearchKeywords16->AppendL( pbuf->Des() ); + CleanupStack::PopAndDestroy( pbuf ); + } + break; + case ESearchFieldDataTypeTReal: + { + TReal realData; + TRealFormat realFormat( KRealFormatGeneral,KDefaultRealWidth ); + field.GetData( realData ); + HBufC* pbuf = HBufC::NewLC( KNumberDataLength ); + pbuf->Des().AppendNum( realData,realFormat ); + iSearchKeywords16->AppendL( pbuf->Des() ); + CleanupStack::PopAndDestroy( pbuf ); + } + break; + case ESearchFieldDataTypeTTime: + { + TTime timeData; + field.GetData( timeData ); + TDateTime dateTime = timeData.DateTime(); + + HBufC* pbuf = HBufC::NewLC( KTimeDataLength) ; + + //Set Time and inset into array + pbuf->Des().AppendNum( dateTime.Hour() ); + pbuf->Des().Append( KColon ); + pbuf->Des().AppendNum( dateTime.Minute() ); + pbuf->Des().Append( KColon ); + pbuf->Des().AppendNum( dateTime.Second() ); + iSearchKeywords16->AppendL( pbuf->Des() ); + CleanupStack::PopAndDestroy( pbuf ); + } + break; + case ESearchFieldDataTypeTDesC: + { + TPtrC8 ptr; + field.GetData( ptr ); + HBufC* dataDes = HBufC::NewLC( ptr.Length() ); + TPtr pdata = dataDes->Des(); + CnvUtfConverter::ConvertToUnicodeFromUtf8( pdata , ptr ); + + if ( FeatureManager::FeatureSupported( KFeatureIdJapanese ) || + FeatureManager::FeatureSupported( KFeatureIdChinese ) || + FeatureManager::FeatureSupported( KFeatureIdThai ) ) + { + HBufC* tempBuffer = HBufC::NewLC( ptr.Length() + 1); + TPtr pDataTemp = tempBuffer->Des(); + _LIT(KStar, "*"); + pDataTemp.Zero(); + pDataTemp.Append(KStar); + pDataTemp.Append(pdata); + + iSearchKeywords16->AppendL( pDataTemp ); + CleanupStack::PopAndDestroy( tempBuffer ); + } + else + { + iSearchKeywords16->AppendL( pdata ); + } + + CleanupStack::PopAndDestroy( dataDes ); + } + break; + case ESearchFieldDataTypeCustom: + break; + default: + break; + } + } + + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::DoUftTo8BitConvertionL() +// 16 - 8 bit conversion +// ----------------------------------------------------------------------------- +// +void CSearchTextSearcher::DoUftTo8BitConversionL ( const MDesCArray& aKeywords ) + { + for ( TInt i = 0 ;i < aKeywords.MdcaCount() ; i++ ) + { + HBufC8* pBuf = HBufC8::NewLC( aKeywords.MdcaPoint( i ).Length() ); + TPtr8 ptr8 = pBuf->Des(); + CnvUtfConverter::ConvertFromUnicodeToUtf8( ptr8 ,aKeywords.MdcaPoint( i ) ); + iSearchKeywords8->AppendL( ptr8 ); + CleanupStack::PopAndDestroy( pBuf ); + } + } + + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::SetCriteriaOperator() +// ----------------------------------------------------------------------------- +// +void CSearchTextSearcher::SetCriteriaOperator() + { + + RArray& clause = iClause; + + TInt condition = iBooleanClause = clause[0]; // take first clause out + + TInt nextclause= 0; + for ( TInt i = 0 ;i < clause.Count() ; i++ ) + { + if ( i>0 ) + { + nextclause = clause[i]; + condition ^=nextclause; //check if all are + //the same clause category ( ANDs or ORs ) + if ( condition ) + { + iIntermediateClause = clause[i]; + break; + } + } + } + if ( !condition ) // iSameCondition is initially set to FALSE + { + iSameCondition = TRUE; + } + + } + +// ----------------------------------------------------------------------------- +// CSearchTextSearcher::CheckForBooleanClausesL() +// Compares the to be searched string with the list of keywords, 8 bit version. +// ----------------------------------------------------------------------------- +// +void CSearchTextSearcher::CheckForBooleanClausesL( RArray& + aKeywordSearchStatusArray ) + { + + TBool ifNoneFound = ETrue; + TInt recordFirstPos = 0; + + for ( TInt i = 0 ; i < iCount && i < aKeywordSearchStatusArray.Count() ; i++ ) + { + if ( iBooleanClause == CSearchBooleanCondition::EBooleanMust + && iSameCondition ) + { + if ( !aKeywordSearchStatusArray[i].iFound ) + { + ifNoneFound = ETrue; + break; + } + else + { + ifNoneFound = EFalse; + if ( !recordFirstPos ) + { + recordFirstPos = + aKeywordSearchStatusArray[i].iFoundAtNthPosition; + } + //iObserver.HitL( + // aKeywordSearchStatusArray[i].iFoundAtNthPosition ); + } + } + else if ( iBooleanClause == CSearchBooleanCondition::EBooleanShould + && iSameCondition ) + { + if ( !aKeywordSearchStatusArray[i].iFound ) + { + //Do nothing ,just pass on + } + else + { + ifNoneFound = EFalse; + iObserver.HitL( + aKeywordSearchStatusArray[i].iFoundAtNthPosition ); + } + } + else //if( !iSameCondition ) + { + if ( !aKeywordSearchStatusArray[i].iFound ) + { + if ( iBooleanClause == CSearchBooleanCondition::EBooleanMust ) + { + ifNoneFound = ETrue; + //break; + } + else if( iBooleanClause == + CSearchBooleanCondition::EBooleanShould + && iIntermediateClause == + CSearchBooleanCondition::EBooleanMust ) + { + ifNoneFound = ETrue; + //break; + } + } + else + { + ifNoneFound = EFalse; + iObserver.HitL( aKeywordSearchStatusArray[i].iFoundAtNthPosition ); + } + } + } + + if ( !ifNoneFound && iBooleanClause == + CSearchBooleanCondition::EBooleanMust ) + { + iObserver.HitL( recordFirstPos ); + } + }