os/persistentdata/persistentstorage/centralrepository/common/inc/operations.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #ifndef OPERATIONS_H
    17 #define OPERATIONS_H
    18 
    19 #include <e32debug.h>
    20 #include <e32std.h>
    21 #include "datatype.h"
    22 
    23 /**
    24 This class encapsulates the operation logic used in both the client-server and the PC side library. The MOperationLogic
    25 defines a set of pure virtual functions to be implemented. Currently the two classes responsible for performing operations
    26 respectively are the CServerRepository and the CPcRepImpl
    27 @internalTechnology
    28 */
    29 class MOperationLogic
    30 	{
    31 	public:
    32 
    33 /** DELETE RANGE
    34 Delete a settings from a source list. Settings are marked as deleted rather than deleted immediately
    35 @param aSourceList the source array of settings's pointer matching the partial key and mask
    36 @param aPartialKey the partialKey of the settings to be delted
    37 @param aErrorKey to hold the error encountered during the Delete operation
    38 */
    39 void DeleteSettingsRangeL(RSettingPointerArray& aSourceList,TUint32 aPartialKey,TUint32& aErrorKey)
    40 	{
    41 	if (aSourceList.Count()==0)	
    42 		{
    43 		aErrorKey=aPartialKey;		
    44 		User::Leave(KErrNotFound);
    45 		}
    46 		
    47 	aErrorKey = KUnspecifiedKey;
    48 	TInt numSettings = aSourceList.Count();
    49 	TInt error=KErrNone;		
    50 	for (TInt i = 0; (i < numSettings) && (error == KErrNone); i++)
    51 		{
    52 		ASSERT(aSourceList[i]);
    53 		TServerSetting& settingToDelete = *(aSourceList[i]);
    54 		TUint32 key = settingToDelete.Key();
    55 		// delete it Ensure there is a delete placeholder at the location
    56 		if (GetWritableSettingList().Find(key) == &settingToDelete)
    57 			{
    58 			// we are deleting a setting that is already in the transaction list: Flag it as deleted
    59 			settingToDelete.Reset();
    60 			settingToDelete.SetDeleted();
    61 			}
    62 		else
    63 			{
    64 			// create a new placeholder and set as deleted
    65 			TServerSetting newSetting(key);
    66 			newSetting.SetMeta(settingToDelete.Meta());
    67 			newSetting.SetDeleted();
    68 			GetWritableSettingList().OrderedInsertL(newSetting);
    69 			}
    70 		}	
    71 	}
    72 
    73 /** DELETE
    74 Mark a setting in the source list as deleted if found
    75 @param aId the setting Id to be deleted
    76 @param aSettingList the list of source setting to look for
    77 */
    78 void DeleteSettingL(TUint32 aId)
    79 	{
    80 	TServerSetting* ts=GetWritableSettingList().Find(aId);
    81 	if (ts)
    82 		{
    83 		if (ts->IsDeleted())
    84 			User::Leave(KErrNotFound);
    85 		else
    86 			{
    87 			ts->Reset();
    88 			ts->SetDeleted();	
    89 			}
    90 		}
    91 	else
    92 		{
    93 		TServerSetting* s=GetSetting(aId);
    94 		if (!s)	
    95 			User::Leave(KErrNotFound);
    96 		else
    97 			{
    98 			TServerSetting newSetting(aId);
    99 			newSetting.SetMeta(s->Meta());
   100 			newSetting.SetDeleted();
   101 			GetWritableSettingList().OrderedInsertL(newSetting);
   102 			}
   103 		}
   104 	}
   105 
   106 /** SET
   107 Set a setting to a new value, create the setting if it does not exist yet
   108 @param aKey the id of the setting
   109 @param aVal the new value of the setting
   110 */
   111 template <class T>
   112 void SetSettingL(TUint32 aKey,const T& aVal)
   113 	{
   114 	TServerSetting* s = GetWritableSettingList().Find(aKey);
   115 	if (s)
   116 		{
   117 		if (s->IsDeleted())
   118 			{
   119 	 		// replace the deleted entry with the new values
   120 			s->CopyValueL(aVal);
   121 			s->SetAccessPolicy(GetFallbackAccessPolicy(aKey)); 			
   122 			}
   123 		else
   124 			{
   125 			User::LeaveIfError(s->AssignValueFrom(aVal));	
   126 			s->SetMeta(s->Meta() & (~KMetaDefaultValue));	
   127 			}		
   128 		}
   129 	else	
   130 		{
   131 		TServerSetting* ns=GetSetting(aKey);
   132 		TServerSetting newSetting(aKey);
   133 		newSetting.CopyValueL(aVal);
   134 		newSetting.SetAccessPolicy(GetFallbackAccessPolicy(aKey));
   135 		TUint32 metadata;		
   136 		if (!ns)
   137 			{
   138 			GetSingleMeta(aKey,metadata);
   139 			}
   140 		else
   141 			{
   142 			if (!ns->IsType(aVal))
   143 				{
   144 				User::Leave(KErrArgument);
   145 				}			
   146 			metadata = ~KMetaDefaultValue & ns->Meta();
   147 			}
   148 		newSetting.SetMeta(metadata);			
   149 		newSetting.PushL(); // only needed for strings
   150 		GetWritableSettingList().OrderedInsertL(newSetting);	
   151 		newSetting.Pop();			
   152 		}
   153 	}
   154 
   155 /** CREATE
   156 Create a setting with a new value with a meta value.If meta value
   157 not specified it will attempt to look for the meta in order of single
   158 ,range, and finally default meta
   159 @param aKey the id of the setting
   160 @param aVal the new value of the setting
   161 @param aMeta the meta value of the setting
   162 @leave KErrAlreadyExists if setting with that id already exist
   163 */
   164 template <class T>
   165 void CreateSettingL(TUint32 aKey, const T& aVal, TUint32* aMeta)
   166 	{
   167 	TServerSetting* s = GetSetting(aKey);
   168 	if (s)
   169 		{
   170 		if (!s->IsDeleted())
   171 			User::Leave(KErrAlreadyExists);
   172 		else
   173 			{
   174 			//previously deleted settings			
   175 			s->CopyValueL(aVal);
   176 			s->SetAccessPolicy(GetFallbackAccessPolicy(aKey));		
   177 			}
   178 		}
   179 	else
   180 		{
   181 		//brand new settings, create this
   182 		TServerSetting newSetting(aKey);
   183 		newSetting.CopyValueL(aVal);
   184 		if (aMeta)		
   185 			{
   186 			newSetting.SetMeta(*aMeta);
   187 			}
   188 		else
   189 			{
   190 			TUint32 singleMeta;
   191 			GetSingleMeta(aKey,singleMeta);
   192 			newSetting.SetMeta(singleMeta);	
   193 			}
   194 		newSetting.SetAccessPolicy(GetFallbackAccessPolicy(aKey));
   195 		newSetting.PushL(); // only needed for strings
   196 		GetWritableSettingList().OrderedInsertL(newSetting);	
   197 		newSetting.Pop();		
   198 		}
   199 	}
   200 
   201 /** GETMETA
   202 Retrieve the meta associated with a setting
   203 @param aId the id of the setting
   204 @param aMeta return value for the setting's meta
   205 @return KErrNotFound if setting does not exist
   206 */
   207 TInt GetMeta(TUint32 aId, TUint32& aMeta)
   208 	{
   209 	const TServerSetting* s = GetSetting(aId);
   210 	//if is deleted or cannot be found
   211 	if (s && s->IsDeleted() || !s)
   212 		{
   213 		return KErrNotFound;
   214 		}
   215 	aMeta = ~KMetaDefaultValue & s->Meta();
   216 	return KErrNone;
   217 	}
   218 
   219 /** GET
   220 Retrieve the value of a setting
   221 @param aId the id of the setting
   222 @param aVal return value for the setting's value
   223 @return KErrNotFound if setting does not exist
   224 		KErrArgument if specified setting type does not match	
   225 */
   226 template <class T>
   227 TInt Get(TUint32 aId, T& aVal)
   228 	{
   229 	const TServerSetting* s = GetSetting(aId);
   230 	//if is deleted or cannot be found
   231 	if (s && s->IsDeleted() || !s)
   232 		{
   233 		return KErrNotFound;
   234 		}
   235 	return s->AssignValueTo(aVal);
   236 	}
   237 
   238 /** FIND COMPARE
   239 Retrieve a list of settings' id that match the value based on either the equal or not equal comparison
   240 @param aInputArray the source array of pointer to the settings
   241 @param aVal the value to be compared for the setting
   242 @param aEqual the comparison rule to be applied
   243 @param aFoundIds the passed in ID array to hold the matching settings
   244 */
   245 template <class T>
   246 void FindCompareL(const RSettingPointerArray& aInputArray,const T& aVal,TComparison aEqual,RArray<TUint32>& aFoundIds) const
   247 	{
   248 	aFoundIds.Reset();
   249 	TInt numSettings=aInputArray.Count();
   250 	for (TInt i=0;i< numSettings;i++)
   251 		{
   252 		ASSERT(aInputArray[i]);
   253 		const TServerSetting& setting = *(aInputArray[i]);
   254 		ASSERT(!setting.IsDeleted());
   255 		TInt error=KErrNone;		
   256 		if(aEqual && setting==aVal || !aEqual && setting!=aVal)
   257 			{
   258 			error = aFoundIds.Append(setting.Key());
   259 			if (error != KErrNone)
   260 				{
   261 				aFoundIds.Reset();
   262 				User::Leave(error);
   263 				}
   264 			}
   265 		}
   266 	if (aFoundIds.Count() == 0)
   267 		{
   268 		User::Leave(KErrNotFound);
   269 		}
   270 	}
   271 		
   272 /** FINDL
   273 Retrieve a list of settings that match the partial id and mask
   274 @param aSourcePartialKey the partial key to match
   275 @param aMask the mask to be used with the partial key for matching
   276 @param aFoundIds, the array to hold the found settings id
   277 @param aFoundIdsMaxLimit, specify the max id to fit in the aFoundIds
   278 @param aExcessIds, the array to hold the remaining settings id
   279 */		
   280 void FindL(TUint32 aSourcePartialKey,TUint32 aMask,RArray<TUint32>& aFoundIds,TUint aFoundIdsMaxLimit,RArray<TUint32>& aExcessIds)
   281 	{
   282 	RSettingPointerArray settings;
   283 	CleanupClosePushL(settings);
   284 	TInt error = FindSettings(aSourcePartialKey,aMask, settings);
   285 	if (error == KErrNone)
   286 		{
   287 		const TUint numSettings = settings.Count();
   288 		if (numSettings==0)
   289 			{
   290 			User::Leave(KErrNotFound);
   291 			}
   292 		aFoundIds.Reset();
   293 		
   294 		const TUint numInitial = numSettings > aFoundIdsMaxLimit ? aFoundIdsMaxLimit : numSettings;
   295 		const TUint numFinal = numSettings > aFoundIdsMaxLimit ? numSettings - aFoundIdsMaxLimit : 0;
   296 		
   297 		//reserve memory for everything that needs to be added to the array
   298 		aFoundIds.ReserveL(numSettings);
   299 		
   300 		//now append up to aFoundIdsMaxLimit settings
   301 		for(TUint i = 0; i < numInitial; i++)
   302 			{
   303 			ASSERT(settings[i]);
   304 			// all settings flagged as deleted should have been removed by now, but just to be safe:
   305 			ASSERT(!settings[i]->IsDeleted());
   306 			aFoundIds.AppendL(settings[i]->Key());
   307 			}
   308 			
   309 		//fill the aExcessIds array with any remaining settings
   310 		if(numFinal)
   311 			{
   312 			aExcessIds.Reset();
   313 			aExcessIds.ReserveL(numFinal);
   314 			for(TUint i = numInitial; i < numSettings; i++)
   315 				{
   316 				ASSERT(settings[i]);
   317 				// all settings flagged as deleted should have been removed by now, but just to be safe:
   318 				ASSERT(!settings[i]->IsDeleted());
   319 				aExcessIds.AppendL(settings[i]->Key());
   320 				}
   321 			}
   322 		}
   323 	CleanupStack::PopAndDestroy();
   324 	User::LeaveIfError(error);
   325 	}
   326 
   327 /** MOVE
   328 Move settings that match a given partial key to another target partial key given the mask
   329 @param aSourcePartialKey, the source partialKey
   330 @param aTargetPartialKey the target partialKey
   331 @param aMask the mask to be used with the partial keys
   332 @param aErrorKey to hold the error encountered during the move operation
   333 @param aSourcePointerArray the array containing the source settings' pointer
   334 */
   335 TInt MoveL(TUint32 aSourcePartialKey,TUint32 aTargetPartialKey,TUint32 aMask, TUint32& aErrorKey,
   336 			const RSettingPointerArray& aSourcePointerArray)
   337 	{
   338 	// all write operations now done in a transaction
   339 	TInt error = KErrNone;
   340 	aErrorKey = KUnspecifiedKey;
   341 	
   342 	TUint32 maskedSourcePartialKey = aSourcePartialKey & aMask;
   343 	TUint32 maskedTargetPartialKey = aTargetPartialKey & aMask;
   344 	TUint32 sourceToTarget = maskedSourcePartialKey ^ maskedTargetPartialKey;
   345 	if(!sourceToTarget)
   346 		{
   347 		// not moving anywhere: must return now as this trivial case fails with later logic
   348 		return KErrNone;
   349 		}
   350 
   351 	//Validation of the SourcePointerArray whether any item exist
   352 	if (aSourcePointerArray.Count() == 0)
   353 		{
   354 		aErrorKey=aSourcePartialKey;
   355 		return KErrNotFound;
   356 		}
   357 
   358 	// create a local copy of settings as the settings pointed to by RSettingPointerArray 
   359 	// could move and cause CServerRepository to point to the wrong key, added as fix for DEF080104
   360 	RSettingsArray settingsCopy;
   361 	CleanupClosePushL(settingsCopy);
   362 	settingsCopy.CopyFromPointerArrayL(aSourcePointerArray);
   363 			
   364 	for (TInt i = 0; (i < settingsCopy.Count()) && (error == KErrNone); i++)
   365 		{
   366 		ASSERT(&settingsCopy[i]);
   367 		TServerSetting& sourceSetting = settingsCopy[i];
   368 		TUint32 sourceKey = sourceSetting.Key();
   369 		TUint32 targetKey = sourceKey ^ sourceToTarget;
   370 		
   371 		TServerSetting* targetSetting = GetSetting(targetKey);		
   372 		if (targetSetting)
   373 			{
   374 			// must be set as deleted only(for PC side this can never be reached, all setting either exist or not and if exist
   375 			// this will return KErrAlreadyExists and this error already captured earlier
   376 			ASSERT(targetSetting->IsDeleted());
   377 			error = targetSetting->Replace(sourceSetting);
   378 			if (error == KErrNone)
   379 				{
   380 				targetSetting->SetKey(targetKey);
   381 				// setting takes the access policy of the target key
   382 				targetSetting->SetAccessPolicy(GetFallbackAccessPolicy(targetKey));
   383 				}
   384 			}
   385 		else
   386 			{
   387 			TServerSetting newSetting;
   388 			error = newSetting.Replace(sourceSetting);
   389 			if (error == KErrNone)
   390 				{
   391 				TUint32 metaFromIni;
   392 				newSetting.SetKey(targetKey);
   393 				GetSingleMeta(targetKey,metaFromIni);
   394 				newSetting.SetMeta(metaFromIni);
   395 			
   396 				// setting takes the access policy of the target key
   397 				newSetting.SetAccessPolicy(GetFallbackAccessPolicy(targetKey));
   398 				newSetting.PushL(); // only needed for strings
   399 				GetWritableSettingList().OrderedInsertL(newSetting);
   400 				newSetting.Pop();	// only needed for strings
   401 				}
   402 			}
   403 			
   404 		// ensure there is a delete placeholder at the old location
   405 		TServerSetting* oldSetting=GetWritableSettingList().Find(sourceKey);
   406 		if (oldSetting)
   407 			{
   408 			oldSetting->Reset();
   409 			oldSetting->SetDeleted();
   410 			}
   411 		else
   412 			{
   413 			//this part cannot happen for PC side as the search is on the persistent directly
   414 			TServerSetting newSetting(sourceKey);
   415 			newSetting.SetDeleted();
   416 			GetWritableSettingList().OrderedInsertL(newSetting);			
   417 			}
   418 		}
   419 	// destroy local copy of settings
   420 	settingsCopy.Reset();
   421 	CleanupStack::PopAndDestroy(&settingsCopy);
   422 	return error;		
   423 	}
   424 
   425 
   426 	//pure virtual functions to be implemented by CServerRepository and CPcRepImpl
   427 	
   428 	/**
   429 	Retrieve the meta for a setting, look for the meta in the order of individual setting meta
   430 	range meta and then default meta.
   431 	*/
   432 	virtual void GetSingleMeta(TUint aKey,TUint32& aMeta)=0;
   433 	
   434 	/**
   435 	Retrieve the fall back policy associated with a setting
   436 	*/
   437 	virtual TSettingsAccessPolicy* GetFallbackAccessPolicy(TUint32 aId) const =0;
   438 	
   439 	/**
   440 	Retrieve a pointer to a setting having the key specified in aKey
   441 	*/
   442 	virtual TServerSetting* GetSetting(TUint aKey)=0;
   443 	
   444 	/**
   445 	Retrieve the settings that match the partial key and mask and add it into the settings pointer array
   446 	*/
   447 	virtual TInt FindSettings(TUint32 aSourcePartialKey,TUint32 aMask,RSettingPointerArray& aOutputArray) const=0;
   448 	
   449 	/**
   450 	Get the list of settings array where modification should be made
   451 	*/
   452 	virtual RSettingsArray& GetWritableSettingList() =0;
   453 };
   454 #endif // OPERATIONS_H
   455