diff -r 81f8547efd4f -r e8e3147d53eb predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsAlgorithm1.cpp --- a/predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsAlgorithm1.cpp Fri Mar 12 15:41:25 2010 +0200 +++ b/predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsAlgorithm1.cpp Mon Mar 15 12:39:26 2010 +0200 @@ -30,7 +30,7 @@ #include "CPsDataPluginInterface.h" #include "CPcsDefs.h" -const TInt KSpace = 32; +const TText KSpace = ' '; // UID used for Publish and Subscribe mechanism // This should be same as the one defined in CPsPropertyHandler.cpp @@ -95,15 +95,16 @@ } // Initialize key map and pti engine - //keyMap = CPcsKeyMap::NewL(); + //iKeyMap = CPcsKeyMap::NewL(); TInt keyMapErr = KErrNone; TRAP( keyMapErr, iKeyMap = CPcsKeyMap::NewL()); if ( keyMapErr != KErrNone ) { - PRINT ( _L("**********************************************.")); - PRINT1 ( _L("CPcsAlgorithm1::ConstructL() KeyMap construction error. The keymap crashed with error code %d."),keyMapErr ); - PRINT ( _L("Please check the keypad/language for which keymap got crashed.") ); - PRINT ( _L("**********************************************.")); + PRINT ( _L("**********************************************.")); + PRINT1( _L("CPcsAlgorithm1::ConstructL() KeyMap construction error. The keymap crashed with error code %d."),keyMapErr ); + PRINT ( _L("Please check the keypad/language for which keymap got crashed.") ); + PRINT ( _L("**********************************************.")); + User::Leave( keyMapErr ); // we can't go on without a key map; constructing cache needs it } // Initialize helpers @@ -185,7 +186,8 @@ // ---------------------------------------------------------------------------- // CPcsAlgorithm1::ReplaceZeroWithSpaceL -// Replace all '0's in a search query with " "s +// Replace all "0"s in a search query with " "s if those characters are on +// the same key. // ---------------------------------------------------------------------------- TBool CPcsAlgorithm1::ReplaceZeroWithSpaceL(CPsQuery& aQuery) { @@ -195,43 +197,33 @@ TBool queryModified = EFalse; - if (iKeyMap->GetSpaceAndZeroOnSameKey()) - { - /* In phones like E52 and E55, where the "0" and the " " characters are on - * the same key, then the "0"s EItut have to be considered as possible - * separators. - */ + /* In phones like E52 and E55, where the "0" and the " " characters are on + * the same key, the "0"s have to be considered as possible separators. + * + * In phones like N97 and E72, where the "0" and the " " characters are on + * different keys, the "0"s must not be considered as possible separators. + */ - // Skip initial "0"s, they are not replaced into spaces - TInt skipIndex = 0; - while ( (skipIndex < aQuery.Count()) && - (aQuery.GetItemAtL(skipIndex).Character().GetNumericValue() == 0) ) - { - skipIndex++; - } - - // Replace remaining EItut "0"s into spaces - TChar space(KSpace); - for ( TInt index = skipIndex; index < aQuery.Count(); index++ ) + // Skip initial "0"s, they are not replaced into spaces + TInt skipIndex = 0; + while ( (skipIndex < aQuery.Count()) && + (aQuery.GetItemAtL(skipIndex).Character().GetNumericValue() == 0) ) + { + skipIndex++; + } + + // Replace remaining "0"s into spaces in case they are entered with a keyboard + // that has "0" and " " on the same key. + for ( TInt index = skipIndex; index < aQuery.Count(); index++ ) + { + CPsQueryItem& item = aQuery.GetItemAtL(index); + + if ( iKeyMap->GetSpaceAndZeroOnSameKey( item.Mode() ) && + item.Character().GetNumericValue() == 0 ) { - CPsQueryItem& item = aQuery.GetItemAtL(index); - - if ( item.Character().GetNumericValue() == 0 && - item.Mode() == EItut ) - { - item.SetCharacter(space); - queryModified = ETrue; - } - } - } - else - { - /* In phones like N97 and E72, where the "0" and the " " characters are on - * a different key, then the "0" EItut does not have to be considered as a - * possible separator. - */ - - PRINT ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL: \"0\" and \" \" are on different keys, not attepting to replace") ); + item.SetCharacter(KSpace); + queryModified = ETrue; + } } //PRINTQUERY ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL (AFTER): "), aQuery ); @@ -256,12 +248,13 @@ __LATENCY_MARK ( _L("CPcsAlgorithm1::PerformSearchL") ); - RPointerArray query; - // Local arrays to hold the search results RPointerArray tempSearchResults; + CleanupClosePushL( tempSearchResults ); RPointerArray tempSearchResultsIni; + CleanupClosePushL( tempSearchResultsIni ); RPointerArray tempSearchResultsMod; + CleanupClosePushL( tempSearchResultsMod ); // ----------------------- Perform the basic search ----------------------- /* Even before replacing zeroes with spaces the query can have multiple words @@ -345,7 +338,7 @@ else { // Copy all the contents from tempSearchResults to the results stream - for(int i = 0; i < resultSet; i++) + for(TInt i = 0; i < resultSet; i++) { aSearchResults.Append(WriteClientDataL(*(tempSearchResults[i]))); } @@ -353,9 +346,9 @@ // ------------------------------------------------------------------------ // Cleanup local results array - tempSearchResults.Reset(); // Don't destroy - tempSearchResultsIni.Reset(); // Don't destroy - tempSearchResultsMod.Reset(); // Don't destroy + CleanupStack::PopAndDestroy( &tempSearchResultsMod ); // Close, don't destroy + CleanupStack::PopAndDestroy( &tempSearchResultsIni ); // Close, don't destroy + CleanupStack::PopAndDestroy( &tempSearchResults ); // Close, don't destroy __LATENCY_MARKEND ( _L("CPcsAlgorithm1::PerformSearchL") ); @@ -545,8 +538,8 @@ // ---------------------------------------------------------------------------- void CPcsAlgorithm1::DoSearchL(const CPsSettings& aSettings, CPsQuery& aQuery, - RPointerArray& searchResults, - RPointerArray& searchSeqs ) + RPointerArray& aSearchResults, + RPointerArray& aSearchSeqs ) { PRINT ( _L("Enter CPcsAlgorithm1::DoSearchL") ); @@ -554,10 +547,13 @@ // -(0)----------------- Check if group search is required --------------- RArray contactsInGroup; + CleanupClosePushL( contactsInGroup ); RArray groupIdArray; + CleanupClosePushL( groupIdArray ); // Create a new settings instance CPsSettings *tempSettings = aSettings.CloneL(); + CleanupStack::PushL( tempSettings ); TBool isGroupSearch = IsGroupSearchL(*tempSettings, groupIdArray); @@ -570,33 +566,32 @@ GetContactsInGroupL ( groupIdArray[0], contactsInGroup ); } - groupIdArray.Close(); - // ----------------------------------------------------------------------- // Extract query list. RPointerArray queryList = iMultiSearchHelper->MultiQueryL(aQuery); + CleanupResetAndDestroyPushL( queryList ); PRINTQUERYLIST ( _L("CPcsAlgorithm1::DoSearchL: "), queryList ); - // (1)-------------------- No query return all contacts ------------------- + // (1)-------------------- No query return all contacts ------------------- if ( queryList.Count() == 0 ) { - GetAllContentsL(*tempSettings, searchResults); + GetAllContentsL(*tempSettings, aSearchResults); if ( isGroupSearch ) { - FilterSearchResultsForGroupsL ( contactsInGroup, searchResults ); + FilterSearchResultsForGroupsL( contactsInGroup, aSearchResults ); } } // ------------------------------------------------------------------------ // (2)-------------------- Perform a single query search ------------------ - else if ( queryList.Count() == 1 ) // single qwery + else if ( queryList.Count() == 1 ) // single query { PRINT ( _L("CPcsAlgorithm1::DoSearchL: Query received is Single. Performing a SingleSearch") ); iHelper->SearchSingleL(*tempSettings, *queryList[0], isGroupSearch, - contactsInGroup, searchResults, searchSeqs); + contactsInGroup, aSearchResults, aSearchSeqs); } // ------------------------------------------------------------------------ @@ -607,17 +602,16 @@ // Search results iMultiSearchHelper->SearchMultiL(*tempSettings, queryList, isGroupSearch, - contactsInGroup, searchResults, searchSeqs); + contactsInGroup, aSearchResults, aSearchSeqs); } // ------------------------------------------------------------------------- // Cleanup - delete tempSettings; - tempSettings = NULL; - groupIdArray.Close(); - contactsInGroup.Close(); - queryList.ResetAndDestroy(); + CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy + CleanupStack::PopAndDestroy( tempSettings ); + CleanupStack::PopAndDestroy( &groupIdArray ); // Close + CleanupStack::PopAndDestroy( &contactsInGroup ); // Close __LATENCY_MARKEND ( _L("CPcsAlgorithm1::DoSearchL") ); @@ -629,7 +623,7 @@ // Search function helper // ---------------------------------------------------------------------------- void CPcsAlgorithm1::DoSearchInputL(CPsQuery& aQuery, - TDesC& aData, + const TDesC& aData, RPointerArray& aMatchSet, RArray& aMatchLocation ) { @@ -736,19 +730,14 @@ CPcsCache* cache = iPcsCache[dataStoreIndex]; - TRAPD(err, cache->RemoveAllFromCacheL()); - - if ( err != KErrNone ) - { - SetCachingError(aDataStore, err); - } + cache->RemoveAllFromCache(); } // ---------------------------------------------------------------------------- // CPcsAlgorithm1::GetCacheIndex // Return the cache index for a data store // ---------------------------------------------------------------------------- -TInt CPcsAlgorithm1::GetCacheIndex(TDesC& aDataStore) +TInt CPcsAlgorithm1::GetCacheIndex(const TDesC& aDataStore) { for ( int i = 0; i < iPcsCache.Count(); i++ ) { @@ -781,13 +770,13 @@ { SetCachingError(aDataStore, err); return; - } + } // Increment the cachecount iCacheCount++; - RArray dataFields; - TRAP(err, iPsDataPluginInterface->GetSupportedDataFieldsL(cache->GetURI(), dataFields)); + RArray dataFields; + TRAP(err, iPsDataPluginInterface->GetSupportedDataFieldsL(cache->GetURI(), dataFields)); if ( err != KErrNone ) { SetCachingError(aDataStore, err); @@ -860,7 +849,7 @@ // CPcsAlgorithm1::GetUriForIdL // Get the URI string for this internal id // ---------------------------------------------------------------------------- -TDesC& CPcsAlgorithm1::GetUriForIdL(TUint8 aUriId) +const TDesC& CPcsAlgorithm1::GetUriForIdL(TUint8 aUriId) { TBool found = EFalse; TInt i = 0; @@ -886,7 +875,7 @@ // CPcsAlgorithm1::FindStoreUri // Checks if this store exists // ---------------------------------------------------------------------------- -TInt CPcsAlgorithm1::FindStoreUri ( TDesC& aDataStore ) +TInt CPcsAlgorithm1::FindStoreUri ( const TDesC& aDataStore ) { for ( int i = 0; i < iPcsCache.Count(); i++ ) { @@ -961,14 +950,12 @@ // CPcsAlgorithm1::SetCachingError // Updates cachinge error // ---------------------------------------------------------------------------- -void CPcsAlgorithm1::SetCachingError(TDesC& aDataStore, TInt aError) +void CPcsAlgorithm1::SetCachingError(const TDesC& aDataStore, TInt aError) { - TBuf store; - store.Copy(aDataStore); - PRINT2 ( _L("SetCachingError::URI %S ERROR %d"), &store, aError ); + PRINT2 ( _L("SetCachingError::URI %S ERROR %d"), &aDataStore, aError ); iCacheError = aError; - RProperty::Set(KCStatus,1,iCacheError ); + RProperty::Set( KCStatus,1,iCacheError ); } // ---------------------------------------------------------------------------- @@ -982,46 +969,50 @@ PRINT ( _L("Enter CPcsAlgorithm1::GetAllContentsL") ); - // Get the data stores - RPointerArray aDataStores; - aSettings.SearchUrisL(aDataStores); - // To hold array of results from different data stores typedef RPointerArray CPSDATA_R_PTR_ARRAY; - RPointerArray iSearchResultsArr; + RPointerArray searchResultsArr; + CleanupResetAndDestroyPushL( searchResultsArr ); + // TODO: Here's still a potential memory leak if a leave happens. The child + // arrays of searchResultsArr are not Reset in that case. The CPsData objects + // may leak as well. Handling this safely is somewhat complicated because some of + // the CPsData objects may already be transferred to ownership of aResults array + // at the time the leave happens, and those items must not be deleted. + // Get the data stores + RPointerArray dataStores; + CleanupResetAndDestroyPushL( dataStores ); + aSettings.SearchUrisL(dataStores); + // Get all contacts for each data store - for ( int dsIndex = 0; - dsIndex < aDataStores.Count(); + for ( TInt dsIndex = 0; + dsIndex < dataStores.Count(); dsIndex++ ) { RPointerArray *temp = new (ELeave) RPointerArray(); - iSearchResultsArr.Append(temp); + searchResultsArr.Append(temp); - TInt arrayIndex = GetCacheIndex(*(aDataStores[dsIndex])); + TInt arrayIndex = GetCacheIndex(*(dataStores[dsIndex])); if ( arrayIndex < 0 ) continue; CPcsCache* cache = GetCache(arrayIndex); - cache->GetAllContentsL(*(iSearchResultsArr[dsIndex])); - } - - aDataStores.ResetAndDestroy(); + cache->GetAllContentsL(*(searchResultsArr[dsIndex])); + } + + CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy // Merge the results from different data stores - CPcsAlgorithm1Utils::FormCompleteSearchResultsL(iSearchResultsArr, + CPcsAlgorithm1Utils::FormCompleteSearchResultsL(searchResultsArr, aResults); // Cleanup the local arrays - for(TInt i = 0; i < iSearchResultsArr.Count(); i++) + for(TInt i = 0; i < searchResultsArr.Count(); i++) { - iSearchResultsArr[i]->Reset(); - delete iSearchResultsArr[i]; - iSearchResultsArr[i] = NULL; - } - - iSearchResultsArr.Reset(); + searchResultsArr[i]->Reset(); + } + CleanupStack::PopAndDestroy( &searchResultsArr ); // ResetAndDestroy PRINT1 ( _L("Number of results = %d"), aResults.Count() ); @@ -1044,18 +1035,18 @@ // Get the current URIs defined in settings RPointerArray searchUris; + CleanupResetAndDestroyPushL( searchUris ); aSettings.SearchUrisL(searchUris); if ( aGroupIdArray.Count() && (searchUris.Count() > aGroupIdArray.Count() ) ) { // There is an error, either there are more than one groups // or the settings contain a combination of group/non-group Uris - searchUris.ResetAndDestroy(); aGroupIdArray.Close(); User::Leave(KErrArgument); } - searchUris.ResetAndDestroy(); + CleanupStack::PopAndDestroy( &searchUris ); // ResetAndDestroy PRINT ( _L("End CPcsAlgorithm1::IsGroupSearchL") ); @@ -1069,18 +1060,19 @@ // CPcsAlgorithm1::ReplaceGroupsUriL // Replace groups uri to contacts uri // ---------------------------------------------------------------------------- -void CPcsAlgorithm1::ReplaceGroupsUriL ( CPsSettings& aSettings ) +void CPcsAlgorithm1::ReplaceGroupsUriL( CPsSettings& aSettings ) { - RPointerArray uri; + RPointerArray uri; + CleanupResetAndDestroyPushL( uri ); // Set contacts db uri - HBufC* cntdb = HBufC::NewL(KBufferMaxLen); - cntdb->Des().Copy(KVPbkDefaultCntDbURI); - uri.Append(cntdb); + HBufC* cntdb = KVPbkDefaultCntDbURI().AllocLC(); + uri.AppendL(cntdb); + CleanupStack::Pop( cntdb ); // ownership transferred aSettings.SetSearchUrisL(uri); // Cleanup - uri.ResetAndDestroy(); + CleanupStack::PopAndDestroy( &uri ); // ResetAndDestroy } // ---------------------------------------------------------------------------- @@ -1119,27 +1111,20 @@ // CPcsAlgorithm1::GetContactsInGroupL // Recover contacts that belong to a group // ---------------------------------------------------------------------------- -void CPcsAlgorithm1::GetContactsInGroupL ( TInt aGroupId, - RArray& aGroupContactIds ) +void CPcsAlgorithm1::GetContactsInGroupL( TInt aGroupId, + RArray& aGroupContactIds ) { // Clear results array aGroupContactIds.Reset(); - // Groups URI - HBufC* groupURI = HBufC::NewL(50); - groupURI->Des().Copy(KVPbkDefaultGrpDbURI); - - // Cache Index - TInt cacheIndex = GetCacheIndex(*groupURI); - - // Cleanup - delete groupURI; - groupURI = NULL; + // Cache Index for group database + TInt cacheIndex = GetCacheIndex(KVPbkDefaultGrpDbURI); // Get the groups contact ids if ( cacheIndex != -1 ) { RPointerArray groups; + CleanupClosePushL( groups ); // Get all groups iPcsCache[cacheIndex]->GetAllContentsL(groups); @@ -1154,7 +1139,7 @@ } } - groups.Reset(); + CleanupStack::PopAndDestroy( &groups ); // Close } } @@ -1263,7 +1248,7 @@ if ( aSortOrder.Count() == mySortOrder.Count() ) { TBool same = ETrue; - for ( int i = 0; i < mySortOrder.Count(); i++ ) + for ( TInt i = 0; i < mySortOrder.Count(); i++ ) { if ( mySortOrder[i] != aSortOrder[i] ) { @@ -1308,7 +1293,7 @@ // Read the persisted sort order from the central repository // Persisted sort order is of form URI Field1 Field2 Field3 .. FieldN (space delimited) // --------------------------------------------------------------------------------- -void CPcsAlgorithm1::ReadSortOrderFromCenRepL(TDesC& aURI, +void CPcsAlgorithm1::ReadSortOrderFromCenRepL(const TDesC& aURI, RArray& aSortOrder) { PRINT ( _L("Enter CPcsAlgorithm1::ReadSortOrderFromCenRepL.") ); @@ -1343,7 +1328,7 @@ // Extract the sort order token.Set(lex.NextToken()); - while ( token.Length() != 0 ) + while ( token.Length() != 0 ) { TLex lex1(token); @@ -1353,16 +1338,16 @@ if ( KErrNone == err ) { aSortOrder.Append(intVal); - } + } // Next token - token.Set(lex.NextToken()); + token.Set(lex.NextToken()); } break; - } + } } - + } delete repository; @@ -1374,12 +1359,12 @@ // Write the sort order into the central repository // Persisted sort order is of form URI Field1 Field2 Field3 .. FieldN (space delimited) // --------------------------------------------------------------------------------- -void CPcsAlgorithm1::WriteSortOrderToCenRepL(TDesC& aURI, +void CPcsAlgorithm1::WriteSortOrderToCenRepL(const TDesC& aURI, RArray& aSortOrder) { PRINT ( _L("Enter CPcsAlgorithm1::WriteSortOrderToCenRepL.") ); - CRepository *repository = CRepository::NewL( KCRUidPSSortOrder ); + CRepository *repository = CRepository::NewLC( KCRUidPSSortOrder ); // Check if there an entry for this URI in cenrep TBuf str; @@ -1444,7 +1429,7 @@ } // Persist the sort order - HBufC* str1 = HBufC::NewL(KCRMaxLen); + HBufC* str1 = HBufC::NewLC(KCRMaxLen); TPtr ptr(str1->Des()); // Append the URI @@ -1452,7 +1437,7 @@ ptr.Append(KSpace); // Append the sort order fields - for ( int j = 0; j < aSortOrder.Count(); j++ ) + for ( TInt j = 0; j < aSortOrder.Count(); j++ ) { ptr.AppendNum(aSortOrder[j]); ptr.Append(KSpace); @@ -1463,9 +1448,9 @@ User::LeaveIfError(err); - delete str1; + CleanupStack::PopAndDestroy( str1 ); - delete repository; + CleanupStack::PopAndDestroy( repository ); PRINT ( _L("End CPcsAlgorithm1::WriteSortOrderToCenRepL.") ); } @@ -1530,15 +1515,17 @@ User::LeaveIfError( Dll::SetTls(&iPcsCache) ); // Initialize cache - RPointerArray dataStores; + RPointerArray dataStores; + CleanupClosePushL( dataStores ); iPsDataPluginInterface->GetAllSupportedDataStoresL(dataStores); - for ( int dIndex = 0; dIndex < dataStores.Count(); dIndex++ ) - { - AddDataStore(*(dataStores[dIndex])); - } - dataStores.Reset(); + for ( TInt dIndex = 0; dIndex < dataStores.Count(); dIndex++ ) + { + AddDataStore(*(dataStores[dIndex])); + } + + CleanupStack::PopAndDestroy( &dataStores ); // Close } // End of file