sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #ifndef OPERATIONS_H sl@0: #define OPERATIONS_H sl@0: sl@0: #include sl@0: #include sl@0: #include "datatype.h" sl@0: sl@0: /** sl@0: This class encapsulates the operation logic used in both the client-server and the PC side library. The MOperationLogic sl@0: defines a set of pure virtual functions to be implemented. Currently the two classes responsible for performing operations sl@0: respectively are the CServerRepository and the CPcRepImpl sl@0: @internalTechnology sl@0: */ sl@0: class MOperationLogic sl@0: { sl@0: public: sl@0: sl@0: /** DELETE RANGE sl@0: Delete a settings from a source list. Settings are marked as deleted rather than deleted immediately sl@0: @param aSourceList the source array of settings's pointer matching the partial key and mask sl@0: @param aPartialKey the partialKey of the settings to be delted sl@0: @param aErrorKey to hold the error encountered during the Delete operation sl@0: */ sl@0: void DeleteSettingsRangeL(RSettingPointerArray& aSourceList,TUint32 aPartialKey,TUint32& aErrorKey) sl@0: { sl@0: if (aSourceList.Count()==0) sl@0: { sl@0: aErrorKey=aPartialKey; sl@0: User::Leave(KErrNotFound); sl@0: } sl@0: sl@0: aErrorKey = KUnspecifiedKey; sl@0: TInt numSettings = aSourceList.Count(); sl@0: TInt error=KErrNone; sl@0: for (TInt i = 0; (i < numSettings) && (error == KErrNone); i++) sl@0: { sl@0: ASSERT(aSourceList[i]); sl@0: TServerSetting& settingToDelete = *(aSourceList[i]); sl@0: TUint32 key = settingToDelete.Key(); sl@0: // delete it Ensure there is a delete placeholder at the location sl@0: if (GetWritableSettingList().Find(key) == &settingToDelete) sl@0: { sl@0: // we are deleting a setting that is already in the transaction list: Flag it as deleted sl@0: settingToDelete.Reset(); sl@0: settingToDelete.SetDeleted(); sl@0: } sl@0: else sl@0: { sl@0: // create a new placeholder and set as deleted sl@0: TServerSetting newSetting(key); sl@0: newSetting.SetMeta(settingToDelete.Meta()); sl@0: newSetting.SetDeleted(); sl@0: GetWritableSettingList().OrderedInsertL(newSetting); sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** DELETE sl@0: Mark a setting in the source list as deleted if found sl@0: @param aId the setting Id to be deleted sl@0: @param aSettingList the list of source setting to look for sl@0: */ sl@0: void DeleteSettingL(TUint32 aId) sl@0: { sl@0: TServerSetting* ts=GetWritableSettingList().Find(aId); sl@0: if (ts) sl@0: { sl@0: if (ts->IsDeleted()) sl@0: User::Leave(KErrNotFound); sl@0: else sl@0: { sl@0: ts->Reset(); sl@0: ts->SetDeleted(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TServerSetting* s=GetSetting(aId); sl@0: if (!s) sl@0: User::Leave(KErrNotFound); sl@0: else sl@0: { sl@0: TServerSetting newSetting(aId); sl@0: newSetting.SetMeta(s->Meta()); sl@0: newSetting.SetDeleted(); sl@0: GetWritableSettingList().OrderedInsertL(newSetting); sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** SET sl@0: Set a setting to a new value, create the setting if it does not exist yet sl@0: @param aKey the id of the setting sl@0: @param aVal the new value of the setting sl@0: */ sl@0: template sl@0: void SetSettingL(TUint32 aKey,const T& aVal) sl@0: { sl@0: TServerSetting* s = GetWritableSettingList().Find(aKey); sl@0: if (s) sl@0: { sl@0: if (s->IsDeleted()) sl@0: { sl@0: // replace the deleted entry with the new values sl@0: s->CopyValueL(aVal); sl@0: s->SetAccessPolicy(GetFallbackAccessPolicy(aKey)); sl@0: } sl@0: else sl@0: { sl@0: User::LeaveIfError(s->AssignValueFrom(aVal)); sl@0: s->SetMeta(s->Meta() & (~KMetaDefaultValue)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TServerSetting* ns=GetSetting(aKey); sl@0: TServerSetting newSetting(aKey); sl@0: newSetting.CopyValueL(aVal); sl@0: newSetting.SetAccessPolicy(GetFallbackAccessPolicy(aKey)); sl@0: TUint32 metadata; sl@0: if (!ns) sl@0: { sl@0: GetSingleMeta(aKey,metadata); sl@0: } sl@0: else sl@0: { sl@0: if (!ns->IsType(aVal)) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: metadata = ~KMetaDefaultValue & ns->Meta(); sl@0: } sl@0: newSetting.SetMeta(metadata); sl@0: newSetting.PushL(); // only needed for strings sl@0: GetWritableSettingList().OrderedInsertL(newSetting); sl@0: newSetting.Pop(); sl@0: } sl@0: } sl@0: sl@0: /** CREATE sl@0: Create a setting with a new value with a meta value.If meta value sl@0: not specified it will attempt to look for the meta in order of single sl@0: ,range, and finally default meta sl@0: @param aKey the id of the setting sl@0: @param aVal the new value of the setting sl@0: @param aMeta the meta value of the setting sl@0: @leave KErrAlreadyExists if setting with that id already exist sl@0: */ sl@0: template sl@0: void CreateSettingL(TUint32 aKey, const T& aVal, TUint32* aMeta) sl@0: { sl@0: TServerSetting* s = GetSetting(aKey); sl@0: if (s) sl@0: { sl@0: if (!s->IsDeleted()) sl@0: User::Leave(KErrAlreadyExists); sl@0: else sl@0: { sl@0: //previously deleted settings sl@0: s->CopyValueL(aVal); sl@0: s->SetAccessPolicy(GetFallbackAccessPolicy(aKey)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: //brand new settings, create this sl@0: TServerSetting newSetting(aKey); sl@0: newSetting.CopyValueL(aVal); sl@0: if (aMeta) sl@0: { sl@0: newSetting.SetMeta(*aMeta); sl@0: } sl@0: else sl@0: { sl@0: TUint32 singleMeta; sl@0: GetSingleMeta(aKey,singleMeta); sl@0: newSetting.SetMeta(singleMeta); sl@0: } sl@0: newSetting.SetAccessPolicy(GetFallbackAccessPolicy(aKey)); sl@0: newSetting.PushL(); // only needed for strings sl@0: GetWritableSettingList().OrderedInsertL(newSetting); sl@0: newSetting.Pop(); sl@0: } sl@0: } sl@0: sl@0: /** GETMETA sl@0: Retrieve the meta associated with a setting sl@0: @param aId the id of the setting sl@0: @param aMeta return value for the setting's meta sl@0: @return KErrNotFound if setting does not exist sl@0: */ sl@0: TInt GetMeta(TUint32 aId, TUint32& aMeta) sl@0: { sl@0: const TServerSetting* s = GetSetting(aId); sl@0: //if is deleted or cannot be found sl@0: if (s && s->IsDeleted() || !s) sl@0: { sl@0: return KErrNotFound; sl@0: } sl@0: aMeta = ~KMetaDefaultValue & s->Meta(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** GET sl@0: Retrieve the value of a setting sl@0: @param aId the id of the setting sl@0: @param aVal return value for the setting's value sl@0: @return KErrNotFound if setting does not exist sl@0: KErrArgument if specified setting type does not match sl@0: */ sl@0: template sl@0: TInt Get(TUint32 aId, T& aVal) sl@0: { sl@0: const TServerSetting* s = GetSetting(aId); sl@0: //if is deleted or cannot be found sl@0: if (s && s->IsDeleted() || !s) sl@0: { sl@0: return KErrNotFound; sl@0: } sl@0: return s->AssignValueTo(aVal); sl@0: } sl@0: sl@0: /** FIND COMPARE sl@0: Retrieve a list of settings' id that match the value based on either the equal or not equal comparison sl@0: @param aInputArray the source array of pointer to the settings sl@0: @param aVal the value to be compared for the setting sl@0: @param aEqual the comparison rule to be applied sl@0: @param aFoundIds the passed in ID array to hold the matching settings sl@0: */ sl@0: template sl@0: void FindCompareL(const RSettingPointerArray& aInputArray,const T& aVal,TComparison aEqual,RArray& aFoundIds) const sl@0: { sl@0: aFoundIds.Reset(); sl@0: TInt numSettings=aInputArray.Count(); sl@0: for (TInt i=0;i< numSettings;i++) sl@0: { sl@0: ASSERT(aInputArray[i]); sl@0: const TServerSetting& setting = *(aInputArray[i]); sl@0: ASSERT(!setting.IsDeleted()); sl@0: TInt error=KErrNone; sl@0: if(aEqual && setting==aVal || !aEqual && setting!=aVal) sl@0: { sl@0: error = aFoundIds.Append(setting.Key()); sl@0: if (error != KErrNone) sl@0: { sl@0: aFoundIds.Reset(); sl@0: User::Leave(error); sl@0: } sl@0: } sl@0: } sl@0: if (aFoundIds.Count() == 0) sl@0: { sl@0: User::Leave(KErrNotFound); sl@0: } sl@0: } sl@0: sl@0: /** FINDL sl@0: Retrieve a list of settings that match the partial id and mask sl@0: @param aSourcePartialKey the partial key to match sl@0: @param aMask the mask to be used with the partial key for matching sl@0: @param aFoundIds, the array to hold the found settings id sl@0: @param aFoundIdsMaxLimit, specify the max id to fit in the aFoundIds sl@0: @param aExcessIds, the array to hold the remaining settings id sl@0: */ sl@0: void FindL(TUint32 aSourcePartialKey,TUint32 aMask,RArray& aFoundIds,TUint aFoundIdsMaxLimit,RArray& aExcessIds) sl@0: { sl@0: RSettingPointerArray settings; sl@0: CleanupClosePushL(settings); sl@0: TInt error = FindSettings(aSourcePartialKey,aMask, settings); sl@0: if (error == KErrNone) sl@0: { sl@0: const TUint numSettings = settings.Count(); sl@0: if (numSettings==0) sl@0: { sl@0: User::Leave(KErrNotFound); sl@0: } sl@0: aFoundIds.Reset(); sl@0: sl@0: const TUint numInitial = numSettings > aFoundIdsMaxLimit ? aFoundIdsMaxLimit : numSettings; sl@0: const TUint numFinal = numSettings > aFoundIdsMaxLimit ? numSettings - aFoundIdsMaxLimit : 0; sl@0: sl@0: //reserve memory for everything that needs to be added to the array sl@0: aFoundIds.ReserveL(numSettings); sl@0: sl@0: //now append up to aFoundIdsMaxLimit settings sl@0: for(TUint i = 0; i < numInitial; i++) sl@0: { sl@0: ASSERT(settings[i]); sl@0: // all settings flagged as deleted should have been removed by now, but just to be safe: sl@0: ASSERT(!settings[i]->IsDeleted()); sl@0: aFoundIds.AppendL(settings[i]->Key()); sl@0: } sl@0: sl@0: //fill the aExcessIds array with any remaining settings sl@0: if(numFinal) sl@0: { sl@0: aExcessIds.Reset(); sl@0: aExcessIds.ReserveL(numFinal); sl@0: for(TUint i = numInitial; i < numSettings; i++) sl@0: { sl@0: ASSERT(settings[i]); sl@0: // all settings flagged as deleted should have been removed by now, but just to be safe: sl@0: ASSERT(!settings[i]->IsDeleted()); sl@0: aExcessIds.AppendL(settings[i]->Key()); sl@0: } sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(); sl@0: User::LeaveIfError(error); sl@0: } sl@0: sl@0: /** MOVE sl@0: Move settings that match a given partial key to another target partial key given the mask sl@0: @param aSourcePartialKey, the source partialKey sl@0: @param aTargetPartialKey the target partialKey sl@0: @param aMask the mask to be used with the partial keys sl@0: @param aErrorKey to hold the error encountered during the move operation sl@0: @param aSourcePointerArray the array containing the source settings' pointer sl@0: */ sl@0: TInt MoveL(TUint32 aSourcePartialKey,TUint32 aTargetPartialKey,TUint32 aMask, TUint32& aErrorKey, sl@0: const RSettingPointerArray& aSourcePointerArray) sl@0: { sl@0: // all write operations now done in a transaction sl@0: TInt error = KErrNone; sl@0: aErrorKey = KUnspecifiedKey; sl@0: sl@0: TUint32 maskedSourcePartialKey = aSourcePartialKey & aMask; sl@0: TUint32 maskedTargetPartialKey = aTargetPartialKey & aMask; sl@0: TUint32 sourceToTarget = maskedSourcePartialKey ^ maskedTargetPartialKey; sl@0: if(!sourceToTarget) sl@0: { sl@0: // not moving anywhere: must return now as this trivial case fails with later logic sl@0: return KErrNone; sl@0: } sl@0: sl@0: //Validation of the SourcePointerArray whether any item exist sl@0: if (aSourcePointerArray.Count() == 0) sl@0: { sl@0: aErrorKey=aSourcePartialKey; sl@0: return KErrNotFound; sl@0: } sl@0: sl@0: // create a local copy of settings as the settings pointed to by RSettingPointerArray sl@0: // could move and cause CServerRepository to point to the wrong key, added as fix for DEF080104 sl@0: RSettingsArray settingsCopy; sl@0: CleanupClosePushL(settingsCopy); sl@0: settingsCopy.CopyFromPointerArrayL(aSourcePointerArray); sl@0: sl@0: for (TInt i = 0; (i < settingsCopy.Count()) && (error == KErrNone); i++) sl@0: { sl@0: ASSERT(&settingsCopy[i]); sl@0: TServerSetting& sourceSetting = settingsCopy[i]; sl@0: TUint32 sourceKey = sourceSetting.Key(); sl@0: TUint32 targetKey = sourceKey ^ sourceToTarget; sl@0: sl@0: TServerSetting* targetSetting = GetSetting(targetKey); sl@0: if (targetSetting) sl@0: { sl@0: // must be set as deleted only(for PC side this can never be reached, all setting either exist or not and if exist sl@0: // this will return KErrAlreadyExists and this error already captured earlier sl@0: ASSERT(targetSetting->IsDeleted()); sl@0: error = targetSetting->Replace(sourceSetting); sl@0: if (error == KErrNone) sl@0: { sl@0: targetSetting->SetKey(targetKey); sl@0: // setting takes the access policy of the target key sl@0: targetSetting->SetAccessPolicy(GetFallbackAccessPolicy(targetKey)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TServerSetting newSetting; sl@0: error = newSetting.Replace(sourceSetting); sl@0: if (error == KErrNone) sl@0: { sl@0: TUint32 metaFromIni; sl@0: newSetting.SetKey(targetKey); sl@0: GetSingleMeta(targetKey,metaFromIni); sl@0: newSetting.SetMeta(metaFromIni); sl@0: sl@0: // setting takes the access policy of the target key sl@0: newSetting.SetAccessPolicy(GetFallbackAccessPolicy(targetKey)); sl@0: newSetting.PushL(); // only needed for strings sl@0: GetWritableSettingList().OrderedInsertL(newSetting); sl@0: newSetting.Pop(); // only needed for strings sl@0: } sl@0: } sl@0: sl@0: // ensure there is a delete placeholder at the old location sl@0: TServerSetting* oldSetting=GetWritableSettingList().Find(sourceKey); sl@0: if (oldSetting) sl@0: { sl@0: oldSetting->Reset(); sl@0: oldSetting->SetDeleted(); sl@0: } sl@0: else sl@0: { sl@0: //this part cannot happen for PC side as the search is on the persistent directly sl@0: TServerSetting newSetting(sourceKey); sl@0: newSetting.SetDeleted(); sl@0: GetWritableSettingList().OrderedInsertL(newSetting); sl@0: } sl@0: } sl@0: // destroy local copy of settings sl@0: settingsCopy.Reset(); sl@0: CleanupStack::PopAndDestroy(&settingsCopy); sl@0: return error; sl@0: } sl@0: sl@0: sl@0: //pure virtual functions to be implemented by CServerRepository and CPcRepImpl sl@0: sl@0: /** sl@0: Retrieve the meta for a setting, look for the meta in the order of individual setting meta sl@0: range meta and then default meta. sl@0: */ sl@0: virtual void GetSingleMeta(TUint aKey,TUint32& aMeta)=0; sl@0: sl@0: /** sl@0: Retrieve the fall back policy associated with a setting sl@0: */ sl@0: virtual TSettingsAccessPolicy* GetFallbackAccessPolicy(TUint32 aId) const =0; sl@0: sl@0: /** sl@0: Retrieve a pointer to a setting having the key specified in aKey sl@0: */ sl@0: virtual TServerSetting* GetSetting(TUint aKey)=0; sl@0: sl@0: /** sl@0: Retrieve the settings that match the partial key and mask and add it into the settings pointer array sl@0: */ sl@0: virtual TInt FindSettings(TUint32 aSourcePartialKey,TUint32 aMask,RSettingPointerArray& aOutputArray) const=0; sl@0: sl@0: /** sl@0: Get the list of settings array where modification should be made sl@0: */ sl@0: virtual RSettingsArray& GetWritableSettingList() =0; sl@0: }; sl@0: #endif // OPERATIONS_H sl@0: