|
1 /* |
|
2 * Copyright (c) 2007-2009 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: Common utilities for the Metadata System. |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifndef MDSUTILS_H |
|
19 #define MDSUTILS_H |
|
20 |
|
21 #include <ecom/implementationinformation.h> |
|
22 |
|
23 #include <e32math.h> |
|
24 |
|
25 const TInt KMdEErrHarvestingFailed = 300; // Error occured while harvesting - retry in case of this error |
|
26 const TInt KMdEErrHarvestingFailedPermanent = 301; // Error occured while harvesting - do not retry harvesting |
|
27 const TInt KMdEErrHarvestingFailedUnknown = 302; // Unknown error occurred - do not retry harvesting |
|
28 |
|
29 namespace MdsUtils |
|
30 { |
|
31 |
|
32 /** |
|
33 * CleanupPtrArray function is used for cleanup support of locally declared arrays. |
|
34 * |
|
35 * @param aArray An array to cleanup |
|
36 */ |
|
37 template<typename T> inline void CleanupPtrArray( TAny* aArray ) |
|
38 { |
|
39 static_cast<RPointerArray<T>*>(aArray)->ResetAndDestroy(); |
|
40 static_cast<RPointerArray<T>*>(aArray)->Close(); |
|
41 } |
|
42 |
|
43 /** |
|
44 * CleanupEComArray function is used for cleanup support of locally declared arrays. |
|
45 * |
|
46 * @param aArray An array to cleanup |
|
47 */ |
|
48 inline void CleanupEComArray( TAny* aArray ) |
|
49 { |
|
50 CleanupPtrArray<CImplementationInformation>( aArray ); |
|
51 } |
|
52 |
|
53 /** |
|
54 * Get file volume info from the file system. |
|
55 * @param aUri File URI. |
|
56 * @param aVolumeInfo Reference to the object where volume info is stored to. |
|
57 */ |
|
58 inline TInt GetVolumeInfo(const RFs& aFs, const TDesC& aUri, TVolumeInfo& aVolumeInfo ) |
|
59 { |
|
60 if ( aUri.Size() <= 0 ) |
|
61 { |
|
62 return KErrArgument; |
|
63 } |
|
64 |
|
65 TInt driveNumber( 0 ); |
|
66 TInt error( 0 ); |
|
67 |
|
68 error = aFs.CharToDrive( aUri[0], driveNumber ); |
|
69 |
|
70 if ( error != KErrNone ) |
|
71 { |
|
72 return error; |
|
73 } |
|
74 |
|
75 error = aFs.Volume( aVolumeInfo, driveNumber ); |
|
76 |
|
77 return error; |
|
78 } |
|
79 |
|
80 /** |
|
81 * Returns a 32-bit unsigned integer from the location pointed by |
|
82 * the parameter. |
|
83 * @param aPointer Memory pointer (input). |
|
84 * @return Converted integer. |
|
85 */ |
|
86 inline TUint32 ToUInt32L( TUint8* aPointer ) |
|
87 { |
|
88 if ( !aPointer ) |
|
89 { |
|
90 User::Leave( KErrGeneral ); |
|
91 } |
|
92 |
|
93 TUint32 ret = *( aPointer + 3 ); |
|
94 ret = ( ret << 8 ) + *( aPointer + 2 ); |
|
95 ret = ( ret << 8 ) + *( aPointer + 1 ); |
|
96 ret = ( ret << 8 ) + *aPointer; |
|
97 return ret; |
|
98 } |
|
99 |
|
100 /** |
|
101 * Returns a 16-bit unsigned integer from the location pointed by |
|
102 * the parameter. |
|
103 * @param aPointer Memory pointer (input). |
|
104 * @return Converted integer. |
|
105 */ |
|
106 inline TUint16 ToUInt16L( TUint8* aPointer ) |
|
107 { |
|
108 if ( !aPointer ) |
|
109 { |
|
110 User::Leave( KErrGeneral ); |
|
111 } |
|
112 |
|
113 TUint16 ret = *( aPointer + 1 ); |
|
114 ret = STATIC_CAST( TUint16, ( ret << 8 ) + *aPointer ); |
|
115 return ret; |
|
116 } |
|
117 |
|
118 /** |
|
119 * Converts GPS coordinates from Exif degrees to decimal representation. |
|
120 * @param aSourceDes Source descriptor. |
|
121 * @param aCoordinate Output coordinate (latitude or longitude). |
|
122 */ |
|
123 inline void ConvertFromDegreesToDecimalL( const TDes8& aSourceDes, TReal64& aCoordinate ) |
|
124 { |
|
125 if ( aSourceDes.MaxSize() < 24 ) |
|
126 { |
|
127 User::Leave( KErrArgument ); |
|
128 } |
|
129 |
|
130 TUint8* ptr = CONST_CAST( TUint8*, aSourceDes.Ptr() ); |
|
131 |
|
132 TUint32 degrees = ToUInt32L( ptr ); |
|
133 TUint32 deg_denominator = ToUInt32L( ptr + 4 ); |
|
134 TUint32 minutes = ToUInt32L( ptr + 8 ); |
|
135 TUint32 min_denominator = ToUInt32L( ptr + 12 ); |
|
136 TUint32 seconds = ToUInt32L( ptr + 16 ); |
|
137 TUint32 sec_denominator = ToUInt32L( ptr + 20 ); |
|
138 |
|
139 // check that coordinate doesn't contain division by zero |
|
140 // in those numerators which are not 0 |
|
141 if ( ( deg_denominator == 0 && degrees ) || |
|
142 ( min_denominator == 0 && minutes ) || |
|
143 ( sec_denominator == 0 && seconds ) ) |
|
144 { |
|
145 User::Leave( KErrCorrupt ); |
|
146 } |
|
147 |
|
148 aCoordinate = 0.0; |
|
149 |
|
150 if( degrees ) |
|
151 { |
|
152 TReal64 degreesReal = degrees; |
|
153 TReal64 deg_denominatorReal = deg_denominator; |
|
154 aCoordinate += degreesReal / deg_denominatorReal; |
|
155 } |
|
156 if( minutes ) |
|
157 { |
|
158 TReal64 minutesReal = minutes; |
|
159 TReal64 min_denominatorReal = min_denominator; |
|
160 aCoordinate += minutesReal / (min_denominatorReal * 60.0); |
|
161 } |
|
162 if( seconds ) |
|
163 { |
|
164 TReal64 secondsReal = seconds; |
|
165 TReal64 sec_denominatorReal = sec_denominator; |
|
166 aCoordinate += secondsReal / (sec_denominatorReal * 3600.0); |
|
167 } |
|
168 } |
|
169 |
|
170 /** |
|
171 * Converts GPS coordinates from decimal to degree representation used by Exif. |
|
172 * Method leaves with KErrArgument if max size of aTgtDes < 24. |
|
173 * @param aCoordinate Input coordinate (latitude or longitude). |
|
174 * @param aTgtDes Output descriptor. |
|
175 */ |
|
176 inline void ConvertFromDecimalToDegreesL( TReal64 aCoordinate, TDes8& aTgtDes ) |
|
177 { |
|
178 if ( aTgtDes.MaxSize() < 24 ) |
|
179 { |
|
180 User::Leave( KErrArgument ); |
|
181 } |
|
182 |
|
183 const TUint32 KDenominator1 = 1; |
|
184 const TUint32 KDenominator10M = 10000000; |
|
185 const TReal64 KDenominator10MReal = KDenominator10M; |
|
186 |
|
187 TReal64 degs64 = aCoordinate; |
|
188 |
|
189 TReal64 mins64 = 0.0; |
|
190 Math::Frac( mins64, degs64 ); |
|
191 mins64 *= 60.0; |
|
192 |
|
193 TReal64 secs64 = 0.0; |
|
194 Math::Frac( secs64, mins64 ); |
|
195 secs64 *= 60.0 * KDenominator10MReal; |
|
196 |
|
197 TUint32 degrees = (TUint32)( degs64 ); |
|
198 TUint32 minutes = (TUint32)( mins64 ); |
|
199 TUint32 seconds = (TUint32)( secs64 ); |
|
200 |
|
201 aTgtDes.Append( (TUint8*) °rees, 4 ); |
|
202 aTgtDes.Append( (TUint8*) &KDenominator1, 4 ); |
|
203 |
|
204 aTgtDes.Append( (TUint8*) &minutes, 4 ); |
|
205 aTgtDes.Append( (TUint8*) &KDenominator1, 4 ); |
|
206 |
|
207 aTgtDes.Append( (TUint8*) &seconds, 4 ); |
|
208 aTgtDes.Append( (TUint8*) &KDenominator10M, 4 ); |
|
209 } |
|
210 |
|
211 inline TBool IsValidProcessId( const TUid aUid ) |
|
212 { |
|
213 const TUint32 KMinProcessId = 0x10000000; |
|
214 const TUint32 KMaxProcessId = 0xFFFFFFFF; |
|
215 |
|
216 if ( aUid.iUid < KMinProcessId || aUid.iUid > KMaxProcessId ) |
|
217 { |
|
218 return EFalse; |
|
219 } |
|
220 return ETrue; |
|
221 } |
|
222 |
|
223 /** |
|
224 * Converts trap errors to harvesting errors. |
|
225 * @param aTrapError Trapped error to convert |
|
226 * @param aPluginError Output error |
|
227 */ |
|
228 inline void ConvertTrapError( TInt aTrapError, TInt &aPluginError ) |
|
229 { |
|
230 aPluginError = KErrNone; |
|
231 if ( aTrapError == KErrArgument || // -6 |
|
232 aTrapError == KErrCorrupt || // -20 |
|
233 aTrapError == KErrAccessDenied || // -21 |
|
234 aTrapError == KErrPermissionDenied || // -46 |
|
235 aTrapError == KErrNotFound || // -1 |
|
236 aTrapError == KErrNotSupported ) // -5 |
|
237 { |
|
238 aPluginError = KMdEErrHarvestingFailedPermanent; |
|
239 } |
|
240 else if ( aTrapError == KErrGeneral || // -2 |
|
241 aTrapError == KErrNoMemory || //-4 |
|
242 aTrapError == KErrInUse || // -14 |
|
243 aTrapError == KErrServerBusy || // -16 |
|
244 aTrapError == KErrLocked || // -22 |
|
245 aTrapError == KErrCouldNotConnect ) // -34 |
|
246 { |
|
247 aPluginError = KMdEErrHarvestingFailed; |
|
248 } |
|
249 else |
|
250 { |
|
251 aPluginError = KMdEErrHarvestingFailedUnknown; |
|
252 } |
|
253 } |
|
254 |
|
255 /** |
|
256 * Compare descriptors locale-independent |
|
257 * |
|
258 * @param aDes1 first descriptor to compare |
|
259 * @param aDes2 second descriptor to compare |
|
260 * |
|
261 * @return Positive, if this descriptor is greater than the specified |
|
262 * descriptor. Negative, if this descriptor is less than the |
|
263 * specified descriptor. Zero, if both descriptors have the same |
|
264 * length and the their contents are the same. |
|
265 */ |
|
266 inline TInt Compare(const TDesC& aDes1, const TDesC& aDes2) |
|
267 { |
|
268 return aDes1.CompareF( aDes2 ); |
|
269 } |
|
270 |
|
271 /** |
|
272 * Find descriptor locale-independent |
|
273 * |
|
274 * @param aWhereDes descriptor where to search |
|
275 * @param aWhatDes descriptor what to search |
|
276 * |
|
277 * @return The offset of the data sequence from the beginning of this |
|
278 * descriptor's data. KErrNotFound, if the data sequence cannot be |
|
279 * found. Zero, if the length of the search data sequence is zero. |
|
280 */ |
|
281 inline TInt Find(const TDesC& aWhereDes, const TDesC& aWhatDes) |
|
282 { |
|
283 return aWhereDes.FindF( aWhatDes ); |
|
284 } |
|
285 |
|
286 /** |
|
287 * Check if file exist in file system. Requires AllFiles capability. |
|
288 * |
|
289 * @param aFs handle to file server session |
|
290 * @param aFilename filename |
|
291 * |
|
292 * @return Does file exist |
|
293 */ |
|
294 inline TBool FileExists(RFs& aFs, const TDesC& aFilename) |
|
295 { |
|
296 TUint fileAttributes; |
|
297 // Att method is used instead of Entry method |
|
298 // because smaller stack memory usage (4 bytes vs. 548 bytes). |
|
299 // There is no performance difference between methods Att and Entry. |
|
300 return KErrNone == aFs.Att( aFilename, fileAttributes ); |
|
301 } |
|
302 |
|
303 /** |
|
304 * Get name from filename. For example 'Test' is returned from |
|
305 * 'C:\Data\Test.jpg'. aFilename must contain drive letter, path and |
|
306 * filename (file extension is not required). |
|
307 * |
|
308 * @param aFilename filename |
|
309 * @param aName returned name |
|
310 * |
|
311 * @return Does name exist (if true, lenght of aName is > 0) |
|
312 */ |
|
313 inline TBool GetName(const TDesC& aFilename, TPtrC& aName) |
|
314 { |
|
315 // find name (everything after last back slash) |
|
316 TInt pos = aFilename.LocateReverseF( '\\' ); |
|
317 if( pos >= 0 ) |
|
318 { |
|
319 aName.Set( aFilename.Mid( pos + 1 ) ); |
|
320 |
|
321 // remove extension |
|
322 TInt pos = aName.LocateReverseF( '.' ); |
|
323 if( pos >= 0 ) |
|
324 { |
|
325 aName.Set( aName.Left( pos ) ); |
|
326 } |
|
327 |
|
328 if( aName.Length() > 0 ) |
|
329 { |
|
330 return ETrue; |
|
331 } |
|
332 } |
|
333 |
|
334 return EFalse; |
|
335 } |
|
336 |
|
337 /** |
|
338 * Get name and extension from filename. For example 'Test.jpg' is |
|
339 * returned from 'C:\Data\Test.jpg'. aFilename must contain drive letter, |
|
340 * path and filename (file extension is not required). |
|
341 * |
|
342 * @param aFilename filename |
|
343 * @param aNameExt returned name and extension |
|
344 * |
|
345 * @return Does name and extension exist (if true, lenght of aNameExt is > 0) |
|
346 */ |
|
347 inline TBool GetNameExt(const TDesC& aFilename, TPtrC& aNameExt) |
|
348 { |
|
349 // find name (everything after last back slash) |
|
350 TInt pos = aFilename.LocateReverseF( '\\' ); |
|
351 if( pos >= 0 ) |
|
352 { |
|
353 aNameExt.Set( aFilename.Mid( pos + 1 ) ); |
|
354 |
|
355 if( aNameExt.Length() > 0 ) |
|
356 { |
|
357 return ETrue; |
|
358 } |
|
359 } |
|
360 |
|
361 return EFalse; |
|
362 } |
|
363 |
|
364 /** |
|
365 * Get extension from filename. For example 'jpg' is returned from |
|
366 * 'C:\Data\Test.jpg'. aFilename must contain drive letter, path and |
|
367 * filename (file extension is not required). |
|
368 * |
|
369 * @param aFilename filename |
|
370 * @param aExt returned extension |
|
371 * |
|
372 * @return Does extension exist (if true, lenght of aExt is > 0) |
|
373 */ |
|
374 inline TBool GetExt(const TDesC& aFilename, TPtrC& aExt) |
|
375 { |
|
376 // find extension (everything after last dot) |
|
377 TInt pos = aFilename.LocateReverseF( '.' ); |
|
378 if( pos >= 0 ) |
|
379 { |
|
380 aExt.Set( aFilename.Mid( pos + 1 ) ); |
|
381 |
|
382 if( aExt.Length() > 0 ) |
|
383 { |
|
384 return ETrue; |
|
385 } |
|
386 } |
|
387 |
|
388 return EFalse; |
|
389 } |
|
390 |
|
391 /** |
|
392 * Get path from filename. For example 'C:\Data\' is returned from |
|
393 * 'C:\Data\Test.jpg'. aFilename must contain drive letter, path and |
|
394 * filename (file extension is not required). |
|
395 * |
|
396 * @param aFilename filename |
|
397 * @param aPath returned path |
|
398 * |
|
399 * @return Does path exist (if true, lenght of aPath is > 0) |
|
400 */ |
|
401 inline TBool GetPath(const TDesC& aFilename, TPtrC& aPath) |
|
402 { |
|
403 // find path (everything before last back slash) |
|
404 TInt pos = aFilename.LocateReverseF( '\\' ); |
|
405 if( pos >= 0 ) |
|
406 { |
|
407 aPath.Set( aFilename.Left( pos + 1 ) ); |
|
408 |
|
409 if( aPath.Length() > 0 ) |
|
410 { |
|
411 return ETrue; |
|
412 } |
|
413 } |
|
414 |
|
415 return EFalse; |
|
416 } |
|
417 } |
|
418 |
|
419 /** |
|
420 * Serialize an array to a newly created descriptor buffer. |
|
421 * Leaves on error. |
|
422 * @param aArray Array to serialize. |
|
423 * @return A new output descriptor pointer. Ownership is transferred. |
|
424 */ |
|
425 template<typename T> |
|
426 HBufC8* SerializeArrayL( const RArray<T>& aArray ) |
|
427 { |
|
428 const TInt KItemCount = aArray.Count(); |
|
429 if ( KItemCount <= 0 ) |
|
430 { |
|
431 return NULL; |
|
432 } |
|
433 const TInt KItemSizeInBytes = sizeof( T ); |
|
434 const TInt KBufferLength = KItemSizeInBytes * KItemCount; |
|
435 |
|
436 HBufC8* buf = HBufC8::NewL( KBufferLength ); |
|
437 void* ptr = NULL; |
|
438 for ( TInt i = 0; i < KBufferLength; i += KItemSizeInBytes ) |
|
439 { |
|
440 const T& item = aArray[ i / KItemSizeInBytes ]; |
|
441 ptr = (void*)( buf->Ptr() + i ); |
|
442 Mem::Copy( ptr, &item, KItemSizeInBytes ); |
|
443 } |
|
444 |
|
445 buf->Des().SetLength( KBufferLength ); |
|
446 return buf; // ownership is transferred |
|
447 } |
|
448 |
|
449 /** |
|
450 * Deserialize an array from a descriptor buffer. |
|
451 * Leaves on error. |
|
452 * @param aDesc Descriptor containing the serialized array. |
|
453 * @param aArray Target array. |
|
454 */ |
|
455 template<typename T> |
|
456 void DeserializeArrayL( const TDesC8& aDesc, RArray<T>& aArray ) |
|
457 { |
|
458 aArray.Reset(); |
|
459 const TInt KItemSizeInBytes = sizeof( T ); |
|
460 const TInt KBufferLength = aDesc.Size(); |
|
461 const TInt KItemCount = KBufferLength / KItemSizeInBytes; |
|
462 aArray.Reserve( KItemCount ); |
|
463 |
|
464 for ( TInt i = 0; i < KItemCount; ++i ) |
|
465 { |
|
466 T item; |
|
467 void* ptr = (void*)( aDesc.Ptr() + i * KItemSizeInBytes ); |
|
468 Mem::Copy( &item, ptr, KItemSizeInBytes ); |
|
469 aArray.Append( item ); |
|
470 } |
|
471 } |
|
472 |
|
473 |
|
474 |
|
475 /** |
|
476 * Serialize a pointer array to a newly created descriptor buffer. |
|
477 * Leaves on error. |
|
478 * @param aArray Pointer Array to serialize. |
|
479 * @return A new output descriptor pointer. Ownership is transferred. |
|
480 */ |
|
481 template<typename T> |
|
482 HBufC8* SerializePointerArrayL( const RPointerArray<T>& aArray ) |
|
483 { |
|
484 const TInt KItemCount = aArray.Count(); |
|
485 if ( KItemCount <= 0 ) |
|
486 { |
|
487 return NULL; |
|
488 } |
|
489 const TInt KItemSizeInBytes = sizeof( T ); |
|
490 const TInt KBufferLength = KItemSizeInBytes * KItemCount; |
|
491 |
|
492 HBufC8* buf = HBufC8::NewL( KBufferLength ); |
|
493 void* ptr = NULL; |
|
494 for ( TInt i = 0; i < KBufferLength; i += KItemSizeInBytes ) |
|
495 { |
|
496 const T* item = aArray[ i / KItemSizeInBytes ]; // alkup. oli const T& |
|
497 ptr = (void*)( buf->Ptr() + i ); |
|
498 Mem::Copy( ptr, &item, KItemSizeInBytes ); |
|
499 } |
|
500 |
|
501 buf->Des().SetLength( KBufferLength ); |
|
502 return buf; // ownership is transferred |
|
503 } |
|
504 |
|
505 /** |
|
506 * Deserialize a pointer array from a descriptor buffer. |
|
507 * Leaves on error. |
|
508 * @param aDesc Descriptor containing the serialized array. |
|
509 * @param aArray Target Pointer Array. |
|
510 */ |
|
511 template<typename T> |
|
512 void DeserializePointerArrayL( const TDesC8& aDesc, RPointerArray<T>& aArray ) |
|
513 { |
|
514 aArray.Reset(); |
|
515 const TInt KItemSizeInBytes = sizeof( T ); |
|
516 const TInt KBufferLength = aDesc.Size(); |
|
517 const TInt KItemCount = KBufferLength / KItemSizeInBytes; |
|
518 aArray.Reserve( KItemCount ); |
|
519 |
|
520 for ( TInt i = 0; i < KItemCount; ++i ) |
|
521 { |
|
522 T* item; // alkup. oli pelkkä T ilman pointteria |
|
523 void* ptr = (void*)( aDesc.Ptr() + i * KItemSizeInBytes ); |
|
524 Mem::Copy( &item, ptr, KItemSizeInBytes ); |
|
525 aArray.Append( item ); |
|
526 } |
|
527 } |
|
528 |
|
529 #endif // MDSUTILS_H |