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