1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/centralrepository/common/inc/operations.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,455 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#ifndef OPERATIONS_H
1.20 +#define OPERATIONS_H
1.21 +
1.22 +#include <e32debug.h>
1.23 +#include <e32std.h>
1.24 +#include "datatype.h"
1.25 +
1.26 +/**
1.27 +This class encapsulates the operation logic used in both the client-server and the PC side library. The MOperationLogic
1.28 +defines a set of pure virtual functions to be implemented. Currently the two classes responsible for performing operations
1.29 +respectively are the CServerRepository and the CPcRepImpl
1.30 +@internalTechnology
1.31 +*/
1.32 +class MOperationLogic
1.33 + {
1.34 + public:
1.35 +
1.36 +/** DELETE RANGE
1.37 +Delete a settings from a source list. Settings are marked as deleted rather than deleted immediately
1.38 +@param aSourceList the source array of settings's pointer matching the partial key and mask
1.39 +@param aPartialKey the partialKey of the settings to be delted
1.40 +@param aErrorKey to hold the error encountered during the Delete operation
1.41 +*/
1.42 +void DeleteSettingsRangeL(RSettingPointerArray& aSourceList,TUint32 aPartialKey,TUint32& aErrorKey)
1.43 + {
1.44 + if (aSourceList.Count()==0)
1.45 + {
1.46 + aErrorKey=aPartialKey;
1.47 + User::Leave(KErrNotFound);
1.48 + }
1.49 +
1.50 + aErrorKey = KUnspecifiedKey;
1.51 + TInt numSettings = aSourceList.Count();
1.52 + TInt error=KErrNone;
1.53 + for (TInt i = 0; (i < numSettings) && (error == KErrNone); i++)
1.54 + {
1.55 + ASSERT(aSourceList[i]);
1.56 + TServerSetting& settingToDelete = *(aSourceList[i]);
1.57 + TUint32 key = settingToDelete.Key();
1.58 + // delete it Ensure there is a delete placeholder at the location
1.59 + if (GetWritableSettingList().Find(key) == &settingToDelete)
1.60 + {
1.61 + // we are deleting a setting that is already in the transaction list: Flag it as deleted
1.62 + settingToDelete.Reset();
1.63 + settingToDelete.SetDeleted();
1.64 + }
1.65 + else
1.66 + {
1.67 + // create a new placeholder and set as deleted
1.68 + TServerSetting newSetting(key);
1.69 + newSetting.SetMeta(settingToDelete.Meta());
1.70 + newSetting.SetDeleted();
1.71 + GetWritableSettingList().OrderedInsertL(newSetting);
1.72 + }
1.73 + }
1.74 + }
1.75 +
1.76 +/** DELETE
1.77 +Mark a setting in the source list as deleted if found
1.78 +@param aId the setting Id to be deleted
1.79 +@param aSettingList the list of source setting to look for
1.80 +*/
1.81 +void DeleteSettingL(TUint32 aId)
1.82 + {
1.83 + TServerSetting* ts=GetWritableSettingList().Find(aId);
1.84 + if (ts)
1.85 + {
1.86 + if (ts->IsDeleted())
1.87 + User::Leave(KErrNotFound);
1.88 + else
1.89 + {
1.90 + ts->Reset();
1.91 + ts->SetDeleted();
1.92 + }
1.93 + }
1.94 + else
1.95 + {
1.96 + TServerSetting* s=GetSetting(aId);
1.97 + if (!s)
1.98 + User::Leave(KErrNotFound);
1.99 + else
1.100 + {
1.101 + TServerSetting newSetting(aId);
1.102 + newSetting.SetMeta(s->Meta());
1.103 + newSetting.SetDeleted();
1.104 + GetWritableSettingList().OrderedInsertL(newSetting);
1.105 + }
1.106 + }
1.107 + }
1.108 +
1.109 +/** SET
1.110 +Set a setting to a new value, create the setting if it does not exist yet
1.111 +@param aKey the id of the setting
1.112 +@param aVal the new value of the setting
1.113 +*/
1.114 +template <class T>
1.115 +void SetSettingL(TUint32 aKey,const T& aVal)
1.116 + {
1.117 + TServerSetting* s = GetWritableSettingList().Find(aKey);
1.118 + if (s)
1.119 + {
1.120 + if (s->IsDeleted())
1.121 + {
1.122 + // replace the deleted entry with the new values
1.123 + s->CopyValueL(aVal);
1.124 + s->SetAccessPolicy(GetFallbackAccessPolicy(aKey));
1.125 + }
1.126 + else
1.127 + {
1.128 + User::LeaveIfError(s->AssignValueFrom(aVal));
1.129 + s->SetMeta(s->Meta() & (~KMetaDefaultValue));
1.130 + }
1.131 + }
1.132 + else
1.133 + {
1.134 + TServerSetting* ns=GetSetting(aKey);
1.135 + TServerSetting newSetting(aKey);
1.136 + newSetting.CopyValueL(aVal);
1.137 + newSetting.SetAccessPolicy(GetFallbackAccessPolicy(aKey));
1.138 + TUint32 metadata;
1.139 + if (!ns)
1.140 + {
1.141 + GetSingleMeta(aKey,metadata);
1.142 + }
1.143 + else
1.144 + {
1.145 + if (!ns->IsType(aVal))
1.146 + {
1.147 + User::Leave(KErrArgument);
1.148 + }
1.149 + metadata = ~KMetaDefaultValue & ns->Meta();
1.150 + }
1.151 + newSetting.SetMeta(metadata);
1.152 + newSetting.PushL(); // only needed for strings
1.153 + GetWritableSettingList().OrderedInsertL(newSetting);
1.154 + newSetting.Pop();
1.155 + }
1.156 + }
1.157 +
1.158 +/** CREATE
1.159 +Create a setting with a new value with a meta value.If meta value
1.160 +not specified it will attempt to look for the meta in order of single
1.161 +,range, and finally default meta
1.162 +@param aKey the id of the setting
1.163 +@param aVal the new value of the setting
1.164 +@param aMeta the meta value of the setting
1.165 +@leave KErrAlreadyExists if setting with that id already exist
1.166 +*/
1.167 +template <class T>
1.168 +void CreateSettingL(TUint32 aKey, const T& aVal, TUint32* aMeta)
1.169 + {
1.170 + TServerSetting* s = GetSetting(aKey);
1.171 + if (s)
1.172 + {
1.173 + if (!s->IsDeleted())
1.174 + User::Leave(KErrAlreadyExists);
1.175 + else
1.176 + {
1.177 + //previously deleted settings
1.178 + s->CopyValueL(aVal);
1.179 + s->SetAccessPolicy(GetFallbackAccessPolicy(aKey));
1.180 + }
1.181 + }
1.182 + else
1.183 + {
1.184 + //brand new settings, create this
1.185 + TServerSetting newSetting(aKey);
1.186 + newSetting.CopyValueL(aVal);
1.187 + if (aMeta)
1.188 + {
1.189 + newSetting.SetMeta(*aMeta);
1.190 + }
1.191 + else
1.192 + {
1.193 + TUint32 singleMeta;
1.194 + GetSingleMeta(aKey,singleMeta);
1.195 + newSetting.SetMeta(singleMeta);
1.196 + }
1.197 + newSetting.SetAccessPolicy(GetFallbackAccessPolicy(aKey));
1.198 + newSetting.PushL(); // only needed for strings
1.199 + GetWritableSettingList().OrderedInsertL(newSetting);
1.200 + newSetting.Pop();
1.201 + }
1.202 + }
1.203 +
1.204 +/** GETMETA
1.205 +Retrieve the meta associated with a setting
1.206 +@param aId the id of the setting
1.207 +@param aMeta return value for the setting's meta
1.208 +@return KErrNotFound if setting does not exist
1.209 +*/
1.210 +TInt GetMeta(TUint32 aId, TUint32& aMeta)
1.211 + {
1.212 + const TServerSetting* s = GetSetting(aId);
1.213 + //if is deleted or cannot be found
1.214 + if (s && s->IsDeleted() || !s)
1.215 + {
1.216 + return KErrNotFound;
1.217 + }
1.218 + aMeta = ~KMetaDefaultValue & s->Meta();
1.219 + return KErrNone;
1.220 + }
1.221 +
1.222 +/** GET
1.223 +Retrieve the value of a setting
1.224 +@param aId the id of the setting
1.225 +@param aVal return value for the setting's value
1.226 +@return KErrNotFound if setting does not exist
1.227 + KErrArgument if specified setting type does not match
1.228 +*/
1.229 +template <class T>
1.230 +TInt Get(TUint32 aId, T& aVal)
1.231 + {
1.232 + const TServerSetting* s = GetSetting(aId);
1.233 + //if is deleted or cannot be found
1.234 + if (s && s->IsDeleted() || !s)
1.235 + {
1.236 + return KErrNotFound;
1.237 + }
1.238 + return s->AssignValueTo(aVal);
1.239 + }
1.240 +
1.241 +/** FIND COMPARE
1.242 +Retrieve a list of settings' id that match the value based on either the equal or not equal comparison
1.243 +@param aInputArray the source array of pointer to the settings
1.244 +@param aVal the value to be compared for the setting
1.245 +@param aEqual the comparison rule to be applied
1.246 +@param aFoundIds the passed in ID array to hold the matching settings
1.247 +*/
1.248 +template <class T>
1.249 +void FindCompareL(const RSettingPointerArray& aInputArray,const T& aVal,TComparison aEqual,RArray<TUint32>& aFoundIds) const
1.250 + {
1.251 + aFoundIds.Reset();
1.252 + TInt numSettings=aInputArray.Count();
1.253 + for (TInt i=0;i< numSettings;i++)
1.254 + {
1.255 + ASSERT(aInputArray[i]);
1.256 + const TServerSetting& setting = *(aInputArray[i]);
1.257 + ASSERT(!setting.IsDeleted());
1.258 + TInt error=KErrNone;
1.259 + if(aEqual && setting==aVal || !aEqual && setting!=aVal)
1.260 + {
1.261 + error = aFoundIds.Append(setting.Key());
1.262 + if (error != KErrNone)
1.263 + {
1.264 + aFoundIds.Reset();
1.265 + User::Leave(error);
1.266 + }
1.267 + }
1.268 + }
1.269 + if (aFoundIds.Count() == 0)
1.270 + {
1.271 + User::Leave(KErrNotFound);
1.272 + }
1.273 + }
1.274 +
1.275 +/** FINDL
1.276 +Retrieve a list of settings that match the partial id and mask
1.277 +@param aSourcePartialKey the partial key to match
1.278 +@param aMask the mask to be used with the partial key for matching
1.279 +@param aFoundIds, the array to hold the found settings id
1.280 +@param aFoundIdsMaxLimit, specify the max id to fit in the aFoundIds
1.281 +@param aExcessIds, the array to hold the remaining settings id
1.282 +*/
1.283 +void FindL(TUint32 aSourcePartialKey,TUint32 aMask,RArray<TUint32>& aFoundIds,TUint aFoundIdsMaxLimit,RArray<TUint32>& aExcessIds)
1.284 + {
1.285 + RSettingPointerArray settings;
1.286 + CleanupClosePushL(settings);
1.287 + TInt error = FindSettings(aSourcePartialKey,aMask, settings);
1.288 + if (error == KErrNone)
1.289 + {
1.290 + const TUint numSettings = settings.Count();
1.291 + if (numSettings==0)
1.292 + {
1.293 + User::Leave(KErrNotFound);
1.294 + }
1.295 + aFoundIds.Reset();
1.296 +
1.297 + const TUint numInitial = numSettings > aFoundIdsMaxLimit ? aFoundIdsMaxLimit : numSettings;
1.298 + const TUint numFinal = numSettings > aFoundIdsMaxLimit ? numSettings - aFoundIdsMaxLimit : 0;
1.299 +
1.300 + //reserve memory for everything that needs to be added to the array
1.301 + aFoundIds.ReserveL(numSettings);
1.302 +
1.303 + //now append up to aFoundIdsMaxLimit settings
1.304 + for(TUint i = 0; i < numInitial; i++)
1.305 + {
1.306 + ASSERT(settings[i]);
1.307 + // all settings flagged as deleted should have been removed by now, but just to be safe:
1.308 + ASSERT(!settings[i]->IsDeleted());
1.309 + aFoundIds.AppendL(settings[i]->Key());
1.310 + }
1.311 +
1.312 + //fill the aExcessIds array with any remaining settings
1.313 + if(numFinal)
1.314 + {
1.315 + aExcessIds.Reset();
1.316 + aExcessIds.ReserveL(numFinal);
1.317 + for(TUint i = numInitial; i < numSettings; i++)
1.318 + {
1.319 + ASSERT(settings[i]);
1.320 + // all settings flagged as deleted should have been removed by now, but just to be safe:
1.321 + ASSERT(!settings[i]->IsDeleted());
1.322 + aExcessIds.AppendL(settings[i]->Key());
1.323 + }
1.324 + }
1.325 + }
1.326 + CleanupStack::PopAndDestroy();
1.327 + User::LeaveIfError(error);
1.328 + }
1.329 +
1.330 +/** MOVE
1.331 +Move settings that match a given partial key to another target partial key given the mask
1.332 +@param aSourcePartialKey, the source partialKey
1.333 +@param aTargetPartialKey the target partialKey
1.334 +@param aMask the mask to be used with the partial keys
1.335 +@param aErrorKey to hold the error encountered during the move operation
1.336 +@param aSourcePointerArray the array containing the source settings' pointer
1.337 +*/
1.338 +TInt MoveL(TUint32 aSourcePartialKey,TUint32 aTargetPartialKey,TUint32 aMask, TUint32& aErrorKey,
1.339 + const RSettingPointerArray& aSourcePointerArray)
1.340 + {
1.341 + // all write operations now done in a transaction
1.342 + TInt error = KErrNone;
1.343 + aErrorKey = KUnspecifiedKey;
1.344 +
1.345 + TUint32 maskedSourcePartialKey = aSourcePartialKey & aMask;
1.346 + TUint32 maskedTargetPartialKey = aTargetPartialKey & aMask;
1.347 + TUint32 sourceToTarget = maskedSourcePartialKey ^ maskedTargetPartialKey;
1.348 + if(!sourceToTarget)
1.349 + {
1.350 + // not moving anywhere: must return now as this trivial case fails with later logic
1.351 + return KErrNone;
1.352 + }
1.353 +
1.354 + //Validation of the SourcePointerArray whether any item exist
1.355 + if (aSourcePointerArray.Count() == 0)
1.356 + {
1.357 + aErrorKey=aSourcePartialKey;
1.358 + return KErrNotFound;
1.359 + }
1.360 +
1.361 + // create a local copy of settings as the settings pointed to by RSettingPointerArray
1.362 + // could move and cause CServerRepository to point to the wrong key, added as fix for DEF080104
1.363 + RSettingsArray settingsCopy;
1.364 + CleanupClosePushL(settingsCopy);
1.365 + settingsCopy.CopyFromPointerArrayL(aSourcePointerArray);
1.366 +
1.367 + for (TInt i = 0; (i < settingsCopy.Count()) && (error == KErrNone); i++)
1.368 + {
1.369 + ASSERT(&settingsCopy[i]);
1.370 + TServerSetting& sourceSetting = settingsCopy[i];
1.371 + TUint32 sourceKey = sourceSetting.Key();
1.372 + TUint32 targetKey = sourceKey ^ sourceToTarget;
1.373 +
1.374 + TServerSetting* targetSetting = GetSetting(targetKey);
1.375 + if (targetSetting)
1.376 + {
1.377 + // must be set as deleted only(for PC side this can never be reached, all setting either exist or not and if exist
1.378 + // this will return KErrAlreadyExists and this error already captured earlier
1.379 + ASSERT(targetSetting->IsDeleted());
1.380 + error = targetSetting->Replace(sourceSetting);
1.381 + if (error == KErrNone)
1.382 + {
1.383 + targetSetting->SetKey(targetKey);
1.384 + // setting takes the access policy of the target key
1.385 + targetSetting->SetAccessPolicy(GetFallbackAccessPolicy(targetKey));
1.386 + }
1.387 + }
1.388 + else
1.389 + {
1.390 + TServerSetting newSetting;
1.391 + error = newSetting.Replace(sourceSetting);
1.392 + if (error == KErrNone)
1.393 + {
1.394 + TUint32 metaFromIni;
1.395 + newSetting.SetKey(targetKey);
1.396 + GetSingleMeta(targetKey,metaFromIni);
1.397 + newSetting.SetMeta(metaFromIni);
1.398 +
1.399 + // setting takes the access policy of the target key
1.400 + newSetting.SetAccessPolicy(GetFallbackAccessPolicy(targetKey));
1.401 + newSetting.PushL(); // only needed for strings
1.402 + GetWritableSettingList().OrderedInsertL(newSetting);
1.403 + newSetting.Pop(); // only needed for strings
1.404 + }
1.405 + }
1.406 +
1.407 + // ensure there is a delete placeholder at the old location
1.408 + TServerSetting* oldSetting=GetWritableSettingList().Find(sourceKey);
1.409 + if (oldSetting)
1.410 + {
1.411 + oldSetting->Reset();
1.412 + oldSetting->SetDeleted();
1.413 + }
1.414 + else
1.415 + {
1.416 + //this part cannot happen for PC side as the search is on the persistent directly
1.417 + TServerSetting newSetting(sourceKey);
1.418 + newSetting.SetDeleted();
1.419 + GetWritableSettingList().OrderedInsertL(newSetting);
1.420 + }
1.421 + }
1.422 + // destroy local copy of settings
1.423 + settingsCopy.Reset();
1.424 + CleanupStack::PopAndDestroy(&settingsCopy);
1.425 + return error;
1.426 + }
1.427 +
1.428 +
1.429 + //pure virtual functions to be implemented by CServerRepository and CPcRepImpl
1.430 +
1.431 + /**
1.432 + Retrieve the meta for a setting, look for the meta in the order of individual setting meta
1.433 + range meta and then default meta.
1.434 + */
1.435 + virtual void GetSingleMeta(TUint aKey,TUint32& aMeta)=0;
1.436 +
1.437 + /**
1.438 + Retrieve the fall back policy associated with a setting
1.439 + */
1.440 + virtual TSettingsAccessPolicy* GetFallbackAccessPolicy(TUint32 aId) const =0;
1.441 +
1.442 + /**
1.443 + Retrieve a pointer to a setting having the key specified in aKey
1.444 + */
1.445 + virtual TServerSetting* GetSetting(TUint aKey)=0;
1.446 +
1.447 + /**
1.448 + Retrieve the settings that match the partial key and mask and add it into the settings pointer array
1.449 + */
1.450 + virtual TInt FindSettings(TUint32 aSourcePartialKey,TUint32 aMask,RSettingPointerArray& aOutputArray) const=0;
1.451 +
1.452 + /**
1.453 + Get the list of settings array where modification should be made
1.454 + */
1.455 + virtual RSettingsArray& GetWritableSettingList() =0;
1.456 +};
1.457 +#endif // OPERATIONS_H
1.458 +