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