|
1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implementation of class CPEngStorageManager |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <e32base.h> |
|
21 #include <s32mem.h> |
|
22 #include "CPEngStorageManager.h" |
|
23 #include "CPEngStoreEntry.h" |
|
24 #include "PEngHashTool.h" |
|
25 #include "PEngStorageGlobals.h" |
|
26 #include "PEngStorageServerCommon.h" |
|
27 #include "MPEngStorageManagerWatcher.h" |
|
28 #include "CPEngSessionSlotId.h" |
|
29 |
|
30 #include "PEngMessagePacker.h" |
|
31 |
|
32 // Debug prints |
|
33 #include "PresenceDebugPrint.h" |
|
34 |
|
35 // ============================ MEMBER FUNCTIONS =============================== |
|
36 |
|
37 // ----------------------------------------------------------------------------- |
|
38 // CPEngStorageManager::CPEngStoreEntry |
|
39 // C++ default constructor can NOT contain any code, that might leave. |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 CPEngStorageManager::CPEngStorageManager( |
|
43 MPEngStorageManagerWatcher& aWatcher ) |
|
44 : iAccessCount( 1 ), // init count to 1 |
|
45 iStorageManagerWatcher( aWatcher ), |
|
46 iSessionSlot( aWatcher.SessionSlotId() ) |
|
47 { |
|
48 // Increase handler count |
|
49 iStorageManagerWatcher.Open(); // CSI: 65 # |
|
50 } |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CPEngStorageManager::BaseConstructL |
|
54 // Symbian 2nd phase Base constructor can leave. |
|
55 // ----------------------------------------------------------------------------- |
|
56 // |
|
57 void CPEngStorageManager::ConstructL( |
|
58 RPEngStorageClient& aStorageMainClient ) |
|
59 { |
|
60 // connect to the Server with the Sub Session |
|
61 HBufC8* sessionName = iSessionSlot.PackLC(); |
|
62 User::LeaveIfError( iSubFolderClient.Connect( aStorageMainClient, *sessionName ) ); |
|
63 CleanupStack::PopAndDestroy(); // sessionName |
|
64 } |
|
65 |
|
66 // ----------------------------------------------------------------------------- |
|
67 // CPEngStorageManager::NewL |
|
68 // Two-phased constructor. |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 CPEngStorageManager* CPEngStorageManager::NewL( |
|
72 MPEngStorageManagerWatcher& aWatcher, |
|
73 RPEngStorageClient& aStorageMainClient ) |
|
74 { |
|
75 CPEngStorageManager* self = CPEngStorageManager::NewLC( aWatcher, aStorageMainClient ); |
|
76 |
|
77 CleanupStack::Pop( ); // self |
|
78 return self; |
|
79 } |
|
80 |
|
81 // ----------------------------------------------------------------------------- |
|
82 // CPEngStorageManager::NewL |
|
83 // Two-phased constructor. |
|
84 // ----------------------------------------------------------------------------- |
|
85 // |
|
86 CPEngStorageManager* CPEngStorageManager::NewLC( |
|
87 MPEngStorageManagerWatcher& aWatcher, |
|
88 RPEngStorageClient& aStorageMainClient ) |
|
89 { |
|
90 CPEngStorageManager* self = |
|
91 new ( ELeave ) CPEngStorageManager( aWatcher ); |
|
92 |
|
93 CleanupClosePushL( *self ); |
|
94 self->ConstructL( aStorageMainClient ); |
|
95 |
|
96 return self; |
|
97 } |
|
98 |
|
99 // Destructor |
|
100 CPEngStorageManager::~CPEngStorageManager() |
|
101 { |
|
102 // Use same Panic as CObject is using for Reference counted objects |
|
103 __ASSERT_ALWAYS( iAccessCount == 0, |
|
104 User::Panic( KPEngSMEuserCBasePanic, |
|
105 KPEngSMEuserCBasePanicReason ) ); |
|
106 |
|
107 iSubFolderClient.Close(); |
|
108 // close handle to watcher |
|
109 iStorageManagerWatcher.Close(); |
|
110 } |
|
111 |
|
112 |
|
113 // ----------------------------------------------------------------------------- |
|
114 // ==== Functions from the MPEngStorageManager base classes ==================== |
|
115 // ----------------------------------------------------------------------------- |
|
116 |
|
117 // ----------------------------------------------------------------------------- |
|
118 // CPEngStorageManager::Open() |
|
119 // ----------------------------------------------------------------------------- |
|
120 // |
|
121 void CPEngStorageManager::Open() |
|
122 { |
|
123 iAccessCount++; |
|
124 } |
|
125 |
|
126 |
|
127 // ----------------------------------------------------------------------------- |
|
128 // CPEngStorageManager::Close() |
|
129 // ----------------------------------------------------------------------------- |
|
130 // |
|
131 void CPEngStorageManager::Close() |
|
132 { |
|
133 iAccessCount--; |
|
134 if ( iAccessCount == 0 ) |
|
135 { |
|
136 delete this; |
|
137 } |
|
138 } |
|
139 |
|
140 |
|
141 // ----------------------------------------------------------------------------- |
|
142 // CPEngStorageManager::StoreL() |
|
143 // ----------------------------------------------------------------------------- |
|
144 // |
|
145 void CPEngStorageManager::StoreL( const CPEngStoreEntry& aStoreEntry ) |
|
146 { |
|
147 PENG_DP( D_PENG_LIT( "CPEngStorageManager::StoreL() [%S][%d]" ), |
|
148 &aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
149 |
|
150 // Etrue to obey lock of the store entry |
|
151 StoreEntryL( aStoreEntry, ETrue ); |
|
152 } |
|
153 |
|
154 |
|
155 // ----------------------------------------------------------------------------- |
|
156 // CPEngStorageManager::StoreExclusiveL() |
|
157 // ----------------------------------------------------------------------------- |
|
158 // |
|
159 void CPEngStorageManager::StoreExclusiveL( const CPEngStoreEntry& aStoreEntry ) |
|
160 { |
|
161 PENG_DP( D_PENG_LIT( "CPEngStorageManager::StoreExclusiveL() [%S][%d]" ), |
|
162 &aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
163 |
|
164 |
|
165 // EFalse to obey lock of the store entry |
|
166 StoreEntryL( aStoreEntry, EFalse ); |
|
167 } |
|
168 |
|
169 |
|
170 // ----------------------------------------------------------------------------- |
|
171 // CPEngStorageManager::RetrieveL() |
|
172 // ----------------------------------------------------------------------------- |
|
173 // |
|
174 TInt CPEngStorageManager::RetrieveL( CPEngStoreEntry& aStoreEntry, |
|
175 TBool aObeyVersion /* ETrue */ ) |
|
176 { |
|
177 PENG_DP( D_PENG_LIT( "CPEngStorageManager::RetrieveL() [%S][%d]" ), |
|
178 &aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
179 |
|
180 // Get Entry size for all parts |
|
181 TPEngStorageType entryType ( aStoreEntry.StorageType() ); |
|
182 // Initialize size with some room for version numbers |
|
183 TUint32 entrySize( KStoreVersionSize + aStoreEntry.EntrySize() ); |
|
184 if ( entrySize <= 0 ) |
|
185 { |
|
186 entrySize = KStoreEntryDefaultSize; |
|
187 } |
|
188 // do not believe and correct entry size |
|
189 entrySize += entrySize / KStoreEntryRetrieveOverlap; |
|
190 |
|
191 // create buffer with estimated size |
|
192 HBufC8* buffer = HBufC8::NewLC( entrySize ); |
|
193 TPtr8 ptr = buffer->Des(); |
|
194 |
|
195 // get Buffer from Server, positive response is size of needed buffer, it it's too small |
|
196 TInt err( 1 ); // to make at least one round in following loop |
|
197 while ( err > KErrNone ) |
|
198 { |
|
199 err = iSubFolderClient.Retrieve( aStoreEntry.StorageId(), |
|
200 aStoreEntry.StorageType(), |
|
201 ptr ); |
|
202 |
|
203 // check if we need to realloc buffer |
|
204 if ( err > KErrNone ) |
|
205 { |
|
206 // realloc buffer and once more, be careful with Clean up stack |
|
207 CleanupStack::PopAndDestroy(); // buffer |
|
208 buffer = HBufC8::NewLC( err ); |
|
209 ptr.Set( buffer->Des() ); |
|
210 } |
|
211 } |
|
212 |
|
213 if ( err == KErrNotFound ) |
|
214 { |
|
215 CleanupStack::PopAndDestroy( ); // buffer |
|
216 // set store Version back to the Zero,so following store wont fail |
|
217 aStoreEntry.iEntryVersion = KErrNone; |
|
218 return KErrNotFound; |
|
219 } |
|
220 |
|
221 User::LeaveIfError( err ); |
|
222 |
|
223 RDesReadStream drs( buffer->Des() ); |
|
224 CleanupClosePushL( drs ); |
|
225 |
|
226 // store version of the entry |
|
227 TInt32 retrievedVersion = drs.ReadInt32L(); |
|
228 |
|
229 // check if internalizing is even necessary |
|
230 if ( aObeyVersion && ( retrievedVersion == aStoreEntry.iEntryVersion ) ) |
|
231 { |
|
232 CleanupStack::PopAndDestroy( 2 );//buffer, drs |
|
233 return KErrNone; |
|
234 } |
|
235 |
|
236 entrySize = ptr.Size(); |
|
237 |
|
238 // Internalize all parts of the store entry |
|
239 TPEngStorageType currentType( EPEngStorageBasicFirst ); |
|
240 while ( !( currentType & EPEngStorageBasicLast ) ) |
|
241 { |
|
242 if ( entryType & currentType ) |
|
243 { |
|
244 TInt strmPartType = drs.ReadInt32L(); |
|
245 TInt strmPartLength = drs.ReadInt32L(); |
|
246 |
|
247 if ( currentType != strmPartType ) |
|
248 { |
|
249 PENG_DP( D_PENG_LIT( "CPEngStorageManager::RetrieveL() [%S][%d] - type order mismatch: strmPartType %d currentType %d" ), |
|
250 &aStoreEntry.StorageId(), aStoreEntry.StorageType(), strmPartType, currentType ); |
|
251 User::Panic( KPEngSMPanic, EPEngSM_TypeOrderMismatch ); |
|
252 } |
|
253 |
|
254 if ( strmPartLength != KErrNotFound ) |
|
255 { |
|
256 MStreamBuf* rawStream = drs.Source(); |
|
257 TStreamPos readStartPos = rawStream->TellL( MStreamBuf::ERead ); |
|
258 |
|
259 aStoreEntry.InternalizeL( drs, currentType ); |
|
260 |
|
261 TStreamPos readEndPos = rawStream->TellL( MStreamBuf::ERead ); |
|
262 TInt readLength = readEndPos - readStartPos; |
|
263 |
|
264 // panic client if did not internalize properly |
|
265 if ( readLength != strmPartLength ) |
|
266 { |
|
267 PENG_DP( D_PENG_LIT( "CPEngStorageManager::RetrieveL() [%S][%d] - internalize length mismatch: readLength %d strmPartLength %d" ), |
|
268 &aStoreEntry.StorageId(), aStoreEntry.StorageType(), strmPartType, currentType ); |
|
269 |
|
270 User::Panic( KPEngSMPanic, EPEngSM_InternalizeLengthMismatch ); |
|
271 } |
|
272 } |
|
273 } |
|
274 |
|
275 currentType = static_cast<TPEngStorageType>( currentType << 1 ); // rotate once to left |
|
276 } |
|
277 |
|
278 // update version after successful internalize |
|
279 aStoreEntry.iEntryVersion = retrievedVersion; |
|
280 aStoreEntry.iSize = entrySize; |
|
281 CleanupStack::PopAndDestroy( 2 );//buffer, drs |
|
282 return KErrNone; |
|
283 } |
|
284 |
|
285 |
|
286 // ----------------------------------------------------------------------------- |
|
287 // CPEngStorageManager::Delete() |
|
288 // ----------------------------------------------------------------------------- |
|
289 // |
|
290 TInt CPEngStorageManager::Delete( |
|
291 const CPEngStoreEntry& aStoreEntry ) |
|
292 { |
|
293 PENG_DP( D_PENG_LIT( "CPEngStorageManager::Delete() [%S][%d] - By entry " ), |
|
294 &aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
295 |
|
296 return iSubFolderClient.Delete( aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
297 } |
|
298 |
|
299 |
|
300 // ----------------------------------------------------------------------------- |
|
301 // CPEngStorageManager::Delete() |
|
302 // ----------------------------------------------------------------------------- |
|
303 // |
|
304 TInt CPEngStorageManager::Delete( const TDesC& aStoreEntryId ) |
|
305 { |
|
306 PENG_DP( D_PENG_LIT( "CPEngStorageManager::Delete() [%S] - By entry id" ), &aStoreEntryId ); |
|
307 // set as type everything |
|
308 return iSubFolderClient.Delete( aStoreEntryId , EPEngMixedPermanentCached ); |
|
309 } |
|
310 |
|
311 |
|
312 // ----------------------------------------------------------------------------- |
|
313 // CPEngStorageManager::LockedL() |
|
314 // ----------------------------------------------------------------------------- |
|
315 // |
|
316 TBool CPEngStorageManager::LockedL( |
|
317 const CPEngStoreEntry& aStoreEntry, |
|
318 TPengStorageLockPriority aPriority /*EStorageLockLevelBasic*/ ) const |
|
319 { |
|
320 PENG_DP( D_PENG_LIT( "CPEngStorageManager::LockedL() [%S][%d] - Priority %d" ), |
|
321 &aStoreEntry.StorageId(), aStoreEntry.StorageType(), aPriority ); |
|
322 |
|
323 TInt ret( iSubFolderClient.StoreEntryLocked( aStoreEntry.StorageId(), |
|
324 aStoreEntry.StorageType(), |
|
325 aPriority ) ); |
|
326 User::LeaveIfError( ret ); |
|
327 return ( ret == 0 ? EFalse : ETrue ); |
|
328 } |
|
329 |
|
330 |
|
331 // ----------------------------------------------------------------------------- |
|
332 // CPEngStorageManager::LockedL() |
|
333 // ----------------------------------------------------------------------------- |
|
334 // |
|
335 TBool CPEngStorageManager::Locked( |
|
336 const CPEngStoreEntry& aStoreEntry, |
|
337 TPengStorageLockPriority aPriority /*EStorageLockLevelBasic*/ ) const |
|
338 { |
|
339 PENG_DP( D_PENG_LIT( "CPEngStorageManager::Locked() [%S][%d] - Priority %d" ), |
|
340 &aStoreEntry.StorageId(), aStoreEntry.StorageType(), aPriority ); |
|
341 |
|
342 TInt ret( iSubFolderClient.StoreEntryLocked( aStoreEntry.StorageId(), |
|
343 aStoreEntry.StorageType(), |
|
344 aPriority ) ); |
|
345 return ( ret <= 0 ? EFalse : ETrue ); |
|
346 } |
|
347 |
|
348 |
|
349 // ----------------------------------------------------------------------------- |
|
350 // CPEngStorageManager::Lock() |
|
351 // ----------------------------------------------------------------------------- |
|
352 // |
|
353 TInt CPEngStorageManager::Lock( |
|
354 const CPEngStoreEntry& aStoreEntry, |
|
355 TPengStorageLockPriority aPriority /*EStorageLockLevelBasic*/, |
|
356 TBool aCreateEntry /* = ETrue */ ) const |
|
357 { |
|
358 PENG_DP( D_PENG_LIT( "CPEngStorageManager::Locked() [%S][%d] - Priority %d" ), |
|
359 &aStoreEntry.StorageId(), aStoreEntry.StorageType(), aPriority ); |
|
360 |
|
361 return iSubFolderClient.LockStoreEntry( aStoreEntry.StorageId(), |
|
362 aStoreEntry.StorageType(), |
|
363 aPriority, |
|
364 aCreateEntry ); |
|
365 } |
|
366 |
|
367 // ----------------------------------------------------------------------------- |
|
368 // CPEngStorageManager::Unlock() |
|
369 // ----------------------------------------------------------------------------- |
|
370 // |
|
371 TInt CPEngStorageManager::Unlock( const CPEngStoreEntry& aStoreEntry ) const |
|
372 { |
|
373 PENG_DP( D_PENG_LIT( "CPEngStorageManager::Unlock() store id: %S, StoreTypeL %d " ), |
|
374 &aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
375 return iSubFolderClient.UnlockStoreEntry( aStoreEntry.StorageId(), aStoreEntry.StorageType() ); |
|
376 } |
|
377 |
|
378 |
|
379 // ----------------------------------------------------------------------------- |
|
380 // CPEngStorageManager::NotifyChangedSId() |
|
381 // ----------------------------------------------------------------------------- |
|
382 // |
|
383 TInt CPEngStorageManager::NotifyChangedSId( const TDesC& aChangedSId, |
|
384 TPEngStorageType aSidStorageType ) |
|
385 { |
|
386 return iSubFolderClient.NotifyChangedSIdBlind( aChangedSId, aSidStorageType ); |
|
387 } |
|
388 |
|
389 |
|
390 // ----------------------------------------------------------------------------- |
|
391 // CPEngStorageManager::BufferServerSideNotifications() |
|
392 // ----------------------------------------------------------------------------- |
|
393 // |
|
394 TInt CPEngStorageManager::BufferServerSideNotifications( TInt aCount ) |
|
395 { |
|
396 PENG_DP( D_PENG_LIT( "CPEngStorageManager::BufferServerSideNotifications() - Count %d" ), |
|
397 aCount ); |
|
398 return iSubFolderClient.BufferServerSideNotifications( aCount ); |
|
399 } |
|
400 |
|
401 |
|
402 // ----------------------------------------------------------------------------- |
|
403 // CPEngStorageManager::ReleaseServerSideBuffering() |
|
404 // ----------------------------------------------------------------------------- |
|
405 // |
|
406 TInt CPEngStorageManager::ReleaseServerSideBuffering( TInt aCount ) |
|
407 { |
|
408 PENG_DP( D_PENG_LIT( "CPEngStorageManager::ReleaseServerSideBuffering() - count %d" ), |
|
409 aCount ); |
|
410 return iSubFolderClient.ReleaseServerSideBuffering( aCount ); |
|
411 } |
|
412 |
|
413 |
|
414 // ----------------------------------------------------------------------------- |
|
415 // CPEngStorageManager::StorageManagerWatcher() |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 MPEngStorageManagerWatcher& CPEngStorageManager::StorageManagerWatcher() |
|
419 { |
|
420 return iStorageManagerWatcher; |
|
421 } |
|
422 |
|
423 |
|
424 // ----------------------------------------------------------------------------- |
|
425 // CPEngStorageManager::SessionSlotId() |
|
426 // ----------------------------------------------------------------------------- |
|
427 // |
|
428 const CPEngSessionSlotId& CPEngStorageManager::SessionSlotId() const |
|
429 { |
|
430 return iSessionSlot; |
|
431 } |
|
432 |
|
433 |
|
434 // ============================================================================= |
|
435 // =============== New private Functions of the class ========================== |
|
436 // ============================================================================= |
|
437 |
|
438 // ----------------------------------------------------------------------------- |
|
439 // CPEngStorageManager::BaseStoragePath |
|
440 // Stores Store Entry given as an argument. |
|
441 // Based on the passed parameter is obeyed lock or not. |
|
442 // (other items were commented in a header). |
|
443 // ----------------------------------------------------------------------------- |
|
444 // |
|
445 void CPEngStorageManager::StoreEntryL( const CPEngStoreEntry& aStoreEntry, |
|
446 TBool aObeyLock ) |
|
447 { |
|
448 // count how much space wee need for storing |
|
449 TUint32 entrySize( KStoreVersionSize + aStoreEntry.EntrySize() ); |
|
450 // do not believe and correct entry size |
|
451 entrySize += entrySize / KStoreEntrySizeTolerance; |
|
452 |
|
453 // get buffer for transfer |
|
454 CBufFlat* buf = CBufFlat::NewL( entrySize ); |
|
455 CleanupStack::PushL( buf ); |
|
456 RBufWriteStream ws; |
|
457 CleanupClosePushL( ws ); |
|
458 ws.Open( *buf ); // CSI: 65 # |
|
459 |
|
460 // get all parts of the store entry, and Externalize them |
|
461 TPEngStorageType entryType ( aStoreEntry.StorageType() ); |
|
462 TPEngStorageType currentType( EPEngStorageBasicFirst ); |
|
463 |
|
464 // Write current version of the entry, increased by one, for server info |
|
465 ws.WriteInt32L( aStoreEntry.iEntryVersion + 1 ); |
|
466 |
|
467 // Write actual data |
|
468 while ( !( currentType & EPEngStorageBasicLast ) ) |
|
469 { |
|
470 if ( entryType & currentType ) |
|
471 { |
|
472 |
|
473 //Write first type and type length "holder" |
|
474 ws.WriteInt32L( currentType ); |
|
475 ws.WriteInt32L( KErrNotFound ); |
|
476 |
|
477 MStreamBuf* rawStream = ws.Sink(); |
|
478 |
|
479 //Do the write and cache locally the write start and points |
|
480 TStreamPos typeStartPos = rawStream->TellL( MStreamBuf::EWrite ); |
|
481 aStoreEntry.ExternalizeL( ws, currentType ); |
|
482 TStreamPos typeEndPos = rawStream->TellL( MStreamBuf::EWrite ); |
|
483 |
|
484 //Caculate write length |
|
485 TInt typeLength = typeEndPos - typeStartPos; |
|
486 |
|
487 //Patch the length holder |
|
488 //-4 below: Length holder is TInt32 (4 bytes) just before the actual data |
|
489 typeStartPos -= 4; |
|
490 rawStream->SeekL( MStreamBuf::EWrite, typeStartPos ); |
|
491 ws.WriteInt32L( typeLength ); |
|
492 rawStream->SeekL( MStreamBuf::EWrite, typeEndPos ); |
|
493 } |
|
494 |
|
495 // rotate once to left |
|
496 currentType = static_cast<TPEngStorageType>( currentType << 1 ); |
|
497 } |
|
498 |
|
499 buf->Compress(); |
|
500 entrySize = buf->Size(); |
|
501 // update store type, depends if lock shall be obeyed |
|
502 entryType = static_cast<TPEngStorageType> |
|
503 ( aObeyLock ? entryType : ( entryType | EPEngStorageLockIgnored ) ); |
|
504 |
|
505 // store data to the server |
|
506 User::LeaveIfError( iSubFolderClient.Store( aStoreEntry.StorageId(), |
|
507 entryType , buf->Ptr( 0 ) ) ); |
|
508 |
|
509 // update version after successful update by 1 |
|
510 ( const_cast<CPEngStoreEntry&> ( aStoreEntry ) ).iEntryVersion = |
|
511 aStoreEntry.iEntryVersion % KMaxTInt + 1; |
|
512 |
|
513 ( const_cast<CPEngStoreEntry&> ( aStoreEntry ) ).iSize = entrySize; |
|
514 |
|
515 CleanupStack::PopAndDestroy( 2 );// ws & buffer |
|
516 } |
|
517 |
|
518 // End of File |
|
519 |