searchfw/coresearchfw/utilities/src/searchtextsearcher.cpp
changeset 0 f979ecb2b13e
--- /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 <utf.h>
+
+#include <searchtextsearcherobserver.h>
+#include <searchsinglecondition.h>
+#include <searchcondition.h>
+#include <searchfield.h>
+#include <searchtextsearcher.h>
+#include "searchkeywordstatus.h"
+#include "searchalgorithm.h"
+
+#include <featmgr.h>
+
+_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<const CDesC16Array*>( &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<const CSearchSingleCondition*>( &aCondition ) ) );
+            }
+            break;
+        case CSearchCondition::EConditionTypeBoolean:
+            {
+            iOperator = ESearchCriteriaAND; 
+            iIsBooleanCondition = ETrue;
+            RPointerArray<CSearchCondition> conditions;
+            (static_cast<const CSearchBooleanCondition*>( &aCondition ) )->
+            GetConditions( conditions,iClause );
+            
+            for ( TInt i = 0; i < conditions.Count() ; i++ )
+                {
+                SetSingleConditionDataL( 
+                *(static_cast<const CSearchSingleCondition*>( 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<TKeywordSearchStatus>& 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<TKeywordSearchStatus>& 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<CSearchBooleanCondition::TBooleanClause>& 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<TKeywordSearchStatus>& 
+                                                            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 ); 
+        }
+    }