|
1 /* |
|
2 * Copyright (c) 2006 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <bamdesca.h> |
|
20 |
|
21 #include "ncdstorageclientimpl.h" |
|
22 |
|
23 #include <f32file.h> |
|
24 #include <bautils.h> |
|
25 #include <badesca.h> |
|
26 #include <s32file.h> |
|
27 |
|
28 #include "ncdstorageimpl.h" |
|
29 #include "ncdstoragemanagerimpl.h" |
|
30 #include "catalogsconstants.h" |
|
31 #include "catalogsutils.h" |
|
32 |
|
33 #include "catalogsdebug.h" |
|
34 |
|
35 |
|
36 _LIT( KNamespaceFile, "namespaces" ); |
|
37 |
|
38 // ======== MEMBER FUNCTIONS ======== |
|
39 |
|
40 |
|
41 // --------------------------------------------------------------------------- |
|
42 // ConstructL |
|
43 // --------------------------------------------------------------------------- |
|
44 // |
|
45 void CNcdStorageClient::ConstructL( const TDesC& aUid ) |
|
46 { |
|
47 DLTRACEIN( ("") ); |
|
48 // Copy the uid |
|
49 iUid.CreateL( aUid ); |
|
50 |
|
51 RBuf path; |
|
52 CleanupClosePushL( path ); |
|
53 path.CreateL( KMaxPath ); |
|
54 |
|
55 // Create the path string for the storage |
|
56 AppendRoot( path ); |
|
57 |
|
58 // Create the directory |
|
59 BaflUtils::EnsurePathExistsL( iOwner.FileSession(), path ); |
|
60 |
|
61 // Create storages for each found directory |
|
62 //CreateStoragesFromFileSystemL( path ); |
|
63 CleanupStack::PopAndDestroy( &path ); |
|
64 |
|
65 // Read namespaces and create storages |
|
66 TRAPD( err, ReadNamespacesL() ); |
|
67 if ( err != KErrNone && err != KErrNotFound ) |
|
68 { |
|
69 User::Leave( err ); |
|
70 } |
|
71 DLTRACEOUT( ("") ); |
|
72 } |
|
73 |
|
74 |
|
75 // --------------------------------------------------------------------------- |
|
76 // NewL |
|
77 // --------------------------------------------------------------------------- |
|
78 // |
|
79 CNcdStorageClient* CNcdStorageClient::NewL( MNcdStorageOwner& aOwner, |
|
80 const TDesC& aUid ) |
|
81 { |
|
82 CNcdStorageClient* self = CNcdStorageClient::NewLC( aOwner, aUid ); |
|
83 CleanupStack::Pop( self ); |
|
84 return self; |
|
85 } |
|
86 |
|
87 |
|
88 // --------------------------------------------------------------------------- |
|
89 // NewLC |
|
90 // --------------------------------------------------------------------------- |
|
91 // |
|
92 CNcdStorageClient* CNcdStorageClient::NewLC( MNcdStorageOwner& aOwner, |
|
93 const TDesC& aUid ) |
|
94 { |
|
95 CNcdStorageClient* self = new( ELeave ) CNcdStorageClient( aOwner ); |
|
96 CleanupStack::PushL( self ); |
|
97 self->ConstructL( aUid ); |
|
98 return self; |
|
99 } |
|
100 |
|
101 |
|
102 // --------------------------------------------------------------------------- |
|
103 // Destructor |
|
104 // --------------------------------------------------------------------------- |
|
105 // |
|
106 CNcdStorageClient::~CNcdStorageClient() |
|
107 { |
|
108 iUid.Close(); |
|
109 iStorages.ResetAndDestroy(); |
|
110 } |
|
111 |
|
112 |
|
113 // --------------------------------------------------------------------------- |
|
114 // Storage creator |
|
115 // --------------------------------------------------------------------------- |
|
116 // |
|
117 MNcdStorage& CNcdStorageClient::CreateStorageL( const TDesC& aNamespace ) |
|
118 { |
|
119 DLTRACEIN( ("") ); |
|
120 |
|
121 TInt index = FindStorageByNamespace( aNamespace ); |
|
122 |
|
123 if ( index != KErrNotFound ) |
|
124 { |
|
125 return *( iStorages[ index ] ); |
|
126 } |
|
127 |
|
128 CNcdStorage* storage = CNcdStorage::NewLC( *this, aNamespace ); |
|
129 iStorages.AppendL( storage ); |
|
130 CleanupStack::Pop( storage ); |
|
131 |
|
132 // Save namespaces |
|
133 SaveNamespacesL(); |
|
134 return *static_cast<MNcdStorage*>( storage ); |
|
135 } |
|
136 |
|
137 |
|
138 // --------------------------------------------------------------------------- |
|
139 // Storage getter |
|
140 // --------------------------------------------------------------------------- |
|
141 // |
|
142 MNcdStorage& CNcdStorageClient::StorageL( const TDesC& aNamespace ) |
|
143 { |
|
144 DLTRACEIN(( _L("NS: %S"), &aNamespace )); |
|
145 TInt index = FindStorageByNamespace( aNamespace ); |
|
146 User::LeaveIfError( index ); |
|
147 DLTRACEOUT(("index: %d", index)); |
|
148 return *(iStorages[index]); |
|
149 } |
|
150 |
|
151 |
|
152 // --------------------------------------------------------------------------- |
|
153 // Storage remover |
|
154 // --------------------------------------------------------------------------- |
|
155 // |
|
156 void CNcdStorageClient::RemoveStorageL( const TDesC& aNamespace ) |
|
157 { |
|
158 DLTRACEIN(("")); |
|
159 if ( !aNamespace.Length() ) |
|
160 { |
|
161 User::Leave( KErrArgument ); |
|
162 } |
|
163 |
|
164 TInt index = FindStorageByNamespace( aNamespace ); |
|
165 |
|
166 if ( index == KErrNotFound ) |
|
167 { |
|
168 DLTRACEOUT(("Namespace not found")); |
|
169 return; |
|
170 } |
|
171 |
|
172 // Generate path before deleting the storage in case aNamespace is a |
|
173 // reference to storage's member variable |
|
174 RBuf path; |
|
175 CleanupClosePushL( path ); |
|
176 path.CreateL( KMaxPath ); |
|
177 |
|
178 // Generate path to the storage directory |
|
179 |
|
180 AppendRoot( path ); |
|
181 path.Append( iStorages[ index ]->Directory() ); |
|
182 path.Append( KDirectorySeparator ); |
|
183 |
|
184 |
|
185 delete iStorages[ index ]; |
|
186 iStorages.Remove( index ); |
|
187 |
|
188 |
|
189 DLTRACE( ( _L("Deleting: %S"), &path ) ); |
|
190 |
|
191 CNcdStorageManager::RemoveDirectoryL( FileSession(), |
|
192 path ); |
|
193 |
|
194 CleanupStack::PopAndDestroy( &path ); |
|
195 |
|
196 // Updates the list of namespaces |
|
197 SaveNamespacesL(); |
|
198 DLTRACEOUT( ("") ); |
|
199 } |
|
200 |
|
201 |
|
202 // --------------------------------------------------------------------------- |
|
203 // Path generator |
|
204 // --------------------------------------------------------------------------- |
|
205 // |
|
206 void CNcdStorageClient::AppendRoot( TDes& aDes ) const |
|
207 { |
|
208 DLTRACEIN(("")); |
|
209 |
|
210 iOwner.AppendRoot( aDes ); |
|
211 aDes.Append( iUid ); |
|
212 aDes.Append( KDirectorySeparator ); |
|
213 |
|
214 DLTRACEOUT(("")); |
|
215 } |
|
216 |
|
217 // --------------------------------------------------------------------------- |
|
218 // File session getter |
|
219 // --------------------------------------------------------------------------- |
|
220 // |
|
221 RFs& CNcdStorageClient::FileSession() |
|
222 { |
|
223 DLTRACEIN(("")); |
|
224 return iOwner.FileSession(); |
|
225 } |
|
226 |
|
227 |
|
228 // --------------------------------------------------------------------------- |
|
229 // File manager getter |
|
230 // --------------------------------------------------------------------------- |
|
231 // |
|
232 CFileMan& CNcdStorageClient::FileManager() |
|
233 { |
|
234 return iOwner.FileManager(); |
|
235 } |
|
236 |
|
237 // --------------------------------------------------------------------------- |
|
238 // Client UID getter |
|
239 // --------------------------------------------------------------------------- |
|
240 // |
|
241 const TDesC& CNcdStorageClient::ClientUid() const |
|
242 { |
|
243 return iUid; |
|
244 } |
|
245 |
|
246 |
|
247 // --------------------------------------------------------------------------- |
|
248 // NamespacesL |
|
249 // --------------------------------------------------------------------------- |
|
250 // |
|
251 MDesCArray* CNcdStorageClient::NamespacesLC() const |
|
252 { |
|
253 DLTRACEIN(("")); |
|
254 CPtrCArray* array = new(ELeave) CPtrCArray( KListGranularity ); |
|
255 |
|
256 // Casting ensures that the popped pointer matches the returned pointer |
|
257 CleanupDeletePushL( static_cast<MDesCArray*>( array) ); |
|
258 array->SetReserveL( iStorages.Count() ); |
|
259 |
|
260 for ( TInt i = 0; i < iStorages.Count(); ++i ) |
|
261 { |
|
262 array->AppendL( iStorages[i]->Namespace() ); |
|
263 } |
|
264 |
|
265 return array; |
|
266 } |
|
267 |
|
268 |
|
269 // --------------------------------------------------------------------------- |
|
270 // Constructor |
|
271 // --------------------------------------------------------------------------- |
|
272 // |
|
273 CNcdStorageClient::CNcdStorageClient( MNcdStorageOwner& aOwner ) : |
|
274 iOwner( aOwner ) |
|
275 { |
|
276 } |
|
277 |
|
278 |
|
279 // --------------------------------------------------------------------------- |
|
280 // Searches for a storage that matches the given namespace |
|
281 // --------------------------------------------------------------------------- |
|
282 // |
|
283 TInt CNcdStorageClient::FindStorageByNamespace( |
|
284 const TDesC& aNamespace ) const |
|
285 { |
|
286 TInt count = iStorages.Count(); |
|
287 for ( TInt i = 0; i < count; ++i ) |
|
288 { |
|
289 if ( iStorages[ i ]->Namespace().Compare( aNamespace ) == 0) |
|
290 { |
|
291 return i; |
|
292 } |
|
293 } |
|
294 |
|
295 return KErrNotFound; |
|
296 } |
|
297 |
|
298 |
|
299 // --------------------------------------------------------------------------- |
|
300 // Creates a storage object for each found directory |
|
301 // --------------------------------------------------------------------------- |
|
302 // |
|
303 /* |
|
304 void CNcdStorageClient::CreateStoragesFromFileSystemL( const TDesC& aPath ) |
|
305 { |
|
306 DLTRACEIN(("")); |
|
307 CDir* dirList = NULL; |
|
308 CDir* fileList = NULL; |
|
309 User::LeaveIfError( FileSession().GetDir( aPath, |
|
310 KEntryAttNormal, ESortByName, fileList, dirList ) ); |
|
311 DLTRACE(("Creating storages")); |
|
312 TInt err = KErrNone; |
|
313 |
|
314 // No need for this |
|
315 delete fileList; |
|
316 |
|
317 CleanupStack::PushL( dirList ); |
|
318 |
|
319 for ( TInt i = 0; i < dirList->Count(); ++i ) |
|
320 { |
|
321 TRAP( err, CreateStorageL( (*dirList)[i].iName ) ); |
|
322 if ( err != KErrNone && err != KErrAlreadyExists ) |
|
323 { |
|
324 User::Leave( err ); |
|
325 } |
|
326 } |
|
327 CleanupStack::PopAndDestroy( dirList ); |
|
328 } |
|
329 */ |
|
330 |
|
331 // --------------------------------------------------------------------------- |
|
332 // Reads namespace encodings from the namespace file |
|
333 // --------------------------------------------------------------------------- |
|
334 // |
|
335 void CNcdStorageClient::ReadNamespacesL() |
|
336 { |
|
337 DLTRACEIN(("")); |
|
338 RBuf filename; |
|
339 CleanupClosePushL( filename ); |
|
340 filename.CreateL( KMaxPath ); |
|
341 |
|
342 AppendRoot( filename ); |
|
343 filename.Append( KNamespaceFile ); |
|
344 |
|
345 HBufC8* data = ReadFileL( FileSession(), filename ); |
|
346 CleanupStack::PopAndDestroy( &filename ); |
|
347 |
|
348 CleanupStack::PushL( data ); |
|
349 RDesReadStream reader( *data ); |
|
350 CleanupClosePushL( reader ); |
|
351 |
|
352 // number of namespaces |
|
353 TInt32 count = reader.ReadInt32L(); |
|
354 |
|
355 iStorages.ReserveL( count ); |
|
356 |
|
357 HBufC* namesp = NULL; |
|
358 HBufC* dir = NULL; |
|
359 DLINFO(("Internalizing %d namespaces")); |
|
360 while ( count ) |
|
361 { |
|
362 DLTRACE(("Internalizing namespace and directory")); |
|
363 InternalizeDesL( namesp, reader ); |
|
364 CleanupStack::PushL( namesp ); |
|
365 |
|
366 InternalizeDesL( dir, reader ); |
|
367 CleanupStack::PushL( dir ); |
|
368 |
|
369 TBool exists = DirectoryExistsL( *dir ); |
|
370 if ( exists ) |
|
371 { |
|
372 DLTRACE(( _L("Client nsp: %S in dir: %S"), |
|
373 namesp, dir )); |
|
374 |
|
375 // Ownership of the namesp and dir is transferred |
|
376 CNcdStorage* client = CNcdStorage::NewL( |
|
377 *this, namesp, dir ); |
|
378 CleanupStack::Pop( 2, namesp ); // dir, namesp |
|
379 |
|
380 // Won't fail because of the ReserveL-call |
|
381 iStorages.Append( client ); |
|
382 DLTRACE(("Client created successfully")); |
|
383 } |
|
384 else |
|
385 { |
|
386 DLTRACE(("Client doesn't exist anymore")); |
|
387 CleanupStack::PopAndDestroy( 2, namesp ); // dir, namesp |
|
388 } |
|
389 namesp = NULL; |
|
390 dir = NULL; |
|
391 --count; |
|
392 } |
|
393 CleanupStack::PopAndDestroy( 2, data ); // reader, data |
|
394 } |
|
395 |
|
396 // --------------------------------------------------------------------------- |
|
397 // Save namespaces |
|
398 // --------------------------------------------------------------------------- |
|
399 // |
|
400 void CNcdStorageClient::SaveNamespacesL() |
|
401 { |
|
402 DLTRACEIN(("")); |
|
403 TFileName tempName; |
|
404 |
|
405 // Get root dir |
|
406 RBuf target; |
|
407 CleanupClosePushL( target ); |
|
408 target.CreateL( KMaxPath ); |
|
409 AppendRoot( target ); |
|
410 |
|
411 DLINFO(( "Creating file write stream.." )); |
|
412 RFileWriteStream writer; |
|
413 CleanupClosePushL( writer ); |
|
414 |
|
415 DLINFO(( "Getting file session.." )); |
|
416 RFs& fs( FileSession() ); |
|
417 // Create a temp file |
|
418 User::LeaveIfError( writer.Temp( |
|
419 fs, |
|
420 target, |
|
421 tempName, |
|
422 EFileWrite | EFileStream ) ); |
|
423 |
|
424 writer.WriteInt32L( iStorages.Count() ); |
|
425 for ( TInt i = 0; i < iStorages.Count(); ++i ) |
|
426 { |
|
427 ExternalizeDesL( iStorages[i]->Namespace(), writer ); |
|
428 ExternalizeDesL( iStorages[i]->Directory(), writer ); |
|
429 } |
|
430 // Commit explicitly so we can react to errors |
|
431 writer.CommitL(); |
|
432 CleanupStack::PopAndDestroy( &writer ); |
|
433 |
|
434 // Append the namespace-file to root dir |
|
435 target.Append( KNamespaceFile ); |
|
436 |
|
437 // Replace the old file with the new one |
|
438 BaflUtils::DeleteFile( fs, target ); |
|
439 User::LeaveIfError( fs.Rename( tempName, target ) ); |
|
440 |
|
441 CleanupStack::PopAndDestroy( &target ); // target |
|
442 DLTRACEOUT(("File saved successfully")); |
|
443 |
|
444 } |
|
445 |
|
446 |
|
447 // --------------------------------------------------------------------------- |
|
448 // Checks if the directory exists |
|
449 // --------------------------------------------------------------------------- |
|
450 // |
|
451 TBool CNcdStorageClient::DirectoryExistsL( const TDesC& aDir ) |
|
452 { |
|
453 DLTRACEIN(( _L("Directory: %S"), &aDir )); |
|
454 RBuf path; |
|
455 CleanupClosePushL( path ); |
|
456 path.CreateL( KMaxPath ); |
|
457 AppendRoot( path ); |
|
458 path.Append( aDir ); |
|
459 |
|
460 TBool exists = BaflUtils::FolderExists( FileSession(), path ); |
|
461 CleanupStack::PopAndDestroy( &path ); |
|
462 return exists; |
|
463 } |
|
464 |