diff -r 000000000000 -r c53acadfccc6 inc/mdsutils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/mdsutils.h Mon Jan 18 20:34:07 2010 +0200 @@ -0,0 +1,529 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Common utilities for the Metadata System. +* +*/ + +#ifndef MDSUTILS_H +#define MDSUTILS_H + +#include + +#include + +const TInt KMdEErrHarvestingFailed = 300; // Error occured while harvesting - retry in case of this error +const TInt KMdEErrHarvestingFailedPermanent = 301; // Error occured while harvesting - do not retry harvesting +const TInt KMdEErrHarvestingFailedUnknown = 302; // Unknown error occurred - do not retry harvesting + +namespace MdsUtils + { + + /** + * CleanupPtrArray function is used for cleanup support of locally declared arrays. + * + * @param aArray An array to cleanup + */ + template inline void CleanupPtrArray( TAny* aArray ) + { + static_cast*>(aArray)->ResetAndDestroy(); + static_cast*>(aArray)->Close(); + } + + /** + * CleanupEComArray function is used for cleanup support of locally declared arrays. + * + * @param aArray An array to cleanup + */ + inline void CleanupEComArray( TAny* aArray ) + { + CleanupPtrArray( aArray ); + } + + /** + * Get file volume info from the file system. + * @param aUri File URI. + * @param aVolumeInfo Reference to the object where volume info is stored to. + */ + inline TInt GetVolumeInfo(const RFs& aFs, const TDesC& aUri, TVolumeInfo& aVolumeInfo ) + { + if ( aUri.Size() <= 0 ) + { + return KErrArgument; + } + + TInt driveNumber( 0 ); + TInt error( 0 ); + + error = aFs.CharToDrive( aUri[0], driveNumber ); + + if ( error != KErrNone ) + { + return error; + } + + error = aFs.Volume( aVolumeInfo, driveNumber ); + + return error; + } + + /** + * Returns a 32-bit unsigned integer from the location pointed by + * the parameter. + * @param aPointer Memory pointer (input). + * @return Converted integer. + */ + inline TUint32 ToUInt32L( TUint8* aPointer ) + { + if ( !aPointer ) + { + User::Leave( KErrGeneral ); + } + + TUint32 ret = *( aPointer + 3 ); + ret = ( ret << 8 ) + *( aPointer + 2 ); + ret = ( ret << 8 ) + *( aPointer + 1 ); + ret = ( ret << 8 ) + *aPointer; + return ret; + } + + /** + * Returns a 16-bit unsigned integer from the location pointed by + * the parameter. + * @param aPointer Memory pointer (input). + * @return Converted integer. + */ + inline TUint16 ToUInt16L( TUint8* aPointer ) + { + if ( !aPointer ) + { + User::Leave( KErrGeneral ); + } + + TUint16 ret = *( aPointer + 1 ); + ret = STATIC_CAST( TUint16, ( ret << 8 ) + *aPointer ); + return ret; + } + + /** + * Converts GPS coordinates from Exif degrees to decimal representation. + * @param aSourceDes Source descriptor. + * @param aCoordinate Output coordinate (latitude or longitude). + */ + inline void ConvertFromDegreesToDecimalL( const TDes8& aSourceDes, TReal64& aCoordinate ) + { + if ( aSourceDes.MaxSize() < 24 ) + { + User::Leave( KErrArgument ); + } + + TUint8* ptr = CONST_CAST( TUint8*, aSourceDes.Ptr() ); + + TUint32 degrees = ToUInt32L( ptr ); + TUint32 deg_denominator = ToUInt32L( ptr + 4 ); + TUint32 minutes = ToUInt32L( ptr + 8 ); + TUint32 min_denominator = ToUInt32L( ptr + 12 ); + TUint32 seconds = ToUInt32L( ptr + 16 ); + TUint32 sec_denominator = ToUInt32L( ptr + 20 ); + + // check that coordinate doesn't contain division by zero + // in those numerators which are not 0 + if ( ( deg_denominator == 0 && degrees ) || + ( min_denominator == 0 && minutes ) || + ( sec_denominator == 0 && seconds ) ) + { + User::Leave( KErrCorrupt ); + } + + aCoordinate = 0.0; + + if( degrees ) + { + TReal64 degreesReal = degrees; + TReal64 deg_denominatorReal = deg_denominator; + aCoordinate += degreesReal / deg_denominatorReal; + } + if( minutes ) + { + TReal64 minutesReal = minutes; + TReal64 min_denominatorReal = min_denominator; + aCoordinate += minutesReal / (min_denominatorReal * 60.0); + } + if( seconds ) + { + TReal64 secondsReal = seconds; + TReal64 sec_denominatorReal = sec_denominator; + aCoordinate += secondsReal / (sec_denominatorReal * 3600.0); + } + } + + /** + * Converts GPS coordinates from decimal to degree representation used by Exif. + * Method leaves with KErrArgument if max size of aTgtDes < 24. + * @param aCoordinate Input coordinate (latitude or longitude). + * @param aTgtDes Output descriptor. + */ + inline void ConvertFromDecimalToDegreesL( TReal64 aCoordinate, TDes8& aTgtDes ) + { + if ( aTgtDes.MaxSize() < 24 ) + { + User::Leave( KErrArgument ); + } + + const TUint32 KDenominator1 = 1; + const TUint32 KDenominator10M = 10000000; + const TReal64 KDenominator10MReal = KDenominator10M; + + TReal64 degs64 = aCoordinate; + + TReal64 mins64 = 0.0; + Math::Frac( mins64, degs64 ); + mins64 *= 60.0; + + TReal64 secs64 = 0.0; + Math::Frac( secs64, mins64 ); + secs64 *= 60.0 * KDenominator10MReal; + + TUint32 degrees = (TUint32)( degs64 ); + TUint32 minutes = (TUint32)( mins64 ); + TUint32 seconds = (TUint32)( secs64 ); + + aTgtDes.Append( (TUint8*) °rees, 4 ); + aTgtDes.Append( (TUint8*) &KDenominator1, 4 ); + + aTgtDes.Append( (TUint8*) &minutes, 4 ); + aTgtDes.Append( (TUint8*) &KDenominator1, 4 ); + + aTgtDes.Append( (TUint8*) &seconds, 4 ); + aTgtDes.Append( (TUint8*) &KDenominator10M, 4 ); + } + + inline TBool IsValidProcessId( const TUid aUid ) + { + const TUint32 KMinProcessId = 0x10000000; + const TUint32 KMaxProcessId = 0xFFFFFFFF; + + if ( aUid.iUid < KMinProcessId || aUid.iUid > KMaxProcessId ) + { + return EFalse; + } + return ETrue; + } + + /** + * Converts trap errors to harvesting errors. + * @param aTrapError Trapped error to convert + * @param aPluginError Output error + */ + inline void ConvertTrapError( TInt aTrapError, TInt &aPluginError ) + { + aPluginError = KErrNone; + if ( aTrapError == KErrArgument || // -6 + aTrapError == KErrCorrupt || // -20 + aTrapError == KErrAccessDenied || // -21 + aTrapError == KErrPermissionDenied || // -46 + aTrapError == KErrNotFound || // -1 + aTrapError == KErrNotSupported ) // -5 + { + aPluginError = KMdEErrHarvestingFailedPermanent; + } + else if ( aTrapError == KErrGeneral || // -2 + aTrapError == KErrNoMemory || //-4 + aTrapError == KErrInUse || // -14 + aTrapError == KErrServerBusy || // -16 + aTrapError == KErrLocked || // -22 + aTrapError == KErrCouldNotConnect ) // -34 + { + aPluginError = KMdEErrHarvestingFailed; + } + else + { + aPluginError = KMdEErrHarvestingFailedUnknown; + } + } + + /** + * Compare descriptors locale-independent + * + * @param aDes1 first descriptor to compare + * @param aDes2 second descriptor to compare + * + * @return Positive, if this descriptor is greater than the specified + * descriptor. Negative, if this descriptor is less than the + * specified descriptor. Zero, if both descriptors have the same + * length and the their contents are the same. + */ + inline TInt Compare(const TDesC& aDes1, const TDesC& aDes2) + { + return aDes1.CompareF( aDes2 ); + } + + /** + * Find descriptor locale-independent + * + * @param aWhereDes descriptor where to search + * @param aWhatDes descriptor what to search + * + * @return The offset of the data sequence from the beginning of this + * descriptor's data. KErrNotFound, if the data sequence cannot be + * found. Zero, if the length of the search data sequence is zero. + */ + inline TInt Find(const TDesC& aWhereDes, const TDesC& aWhatDes) + { + return aWhereDes.FindF( aWhatDes ); + } + + /** + * Check if file exist in file system. Requires AllFiles capability. + * + * @param aFs handle to file server session + * @param aFilename filename + * + * @return Does file exist + */ + inline TBool FileExists(RFs& aFs, const TDesC& aFilename) + { + TUint fileAttributes; + // Att method is used instead of Entry method + // because smaller stack memory usage (4 bytes vs. 548 bytes). + // There is no performance difference between methods Att and Entry. + return KErrNone == aFs.Att( aFilename, fileAttributes ); + } + + /** + * Get name from filename. For example 'Test' is returned from + * 'C:\Data\Test.jpg'. aFilename must contain drive letter, path and + * filename (file extension is not required). + * + * @param aFilename filename + * @param aName returned name + * + * @return Does name exist (if true, lenght of aName is > 0) + */ + inline TBool GetName(const TDesC& aFilename, TPtrC& aName) + { + // find name (everything after last back slash) + TInt pos = aFilename.LocateReverseF( '\\' ); + if( pos >= 0 ) + { + aName.Set( aFilename.Mid( pos + 1 ) ); + + // remove extension + TInt pos = aName.LocateReverseF( '.' ); + if( pos >= 0 ) + { + aName.Set( aName.Left( pos ) ); + } + + if( aName.Length() > 0 ) + { + return ETrue; + } + } + + return EFalse; + } + + /** + * Get name and extension from filename. For example 'Test.jpg' is + * returned from 'C:\Data\Test.jpg'. aFilename must contain drive letter, + * path and filename (file extension is not required). + * + * @param aFilename filename + * @param aNameExt returned name and extension + * + * @return Does name and extension exist (if true, lenght of aNameExt is > 0) + */ + inline TBool GetNameExt(const TDesC& aFilename, TPtrC& aNameExt) + { + // find name (everything after last back slash) + TInt pos = aFilename.LocateReverseF( '\\' ); + if( pos >= 0 ) + { + aNameExt.Set( aFilename.Mid( pos + 1 ) ); + + if( aNameExt.Length() > 0 ) + { + return ETrue; + } + } + + return EFalse; + } + + /** + * Get extension from filename. For example 'jpg' is returned from + * 'C:\Data\Test.jpg'. aFilename must contain drive letter, path and + * filename (file extension is not required). + * + * @param aFilename filename + * @param aExt returned extension + * + * @return Does extension exist (if true, lenght of aExt is > 0) + */ + inline TBool GetExt(const TDesC& aFilename, TPtrC& aExt) + { + // find extension (everything after last dot) + TInt pos = aFilename.LocateReverseF( '.' ); + if( pos >= 0 ) + { + aExt.Set( aFilename.Mid( pos + 1 ) ); + + if( aExt.Length() > 0 ) + { + return ETrue; + } + } + + return EFalse; + } + + /** + * Get path from filename. For example 'C:\Data\' is returned from + * 'C:\Data\Test.jpg'. aFilename must contain drive letter, path and + * filename (file extension is not required). + * + * @param aFilename filename + * @param aPath returned path + * + * @return Does path exist (if true, lenght of aPath is > 0) + */ + inline TBool GetPath(const TDesC& aFilename, TPtrC& aPath) + { + // find path (everything before last back slash) + TInt pos = aFilename.LocateReverseF( '\\' ); + if( pos >= 0 ) + { + aPath.Set( aFilename.Left( pos + 1 ) ); + + if( aPath.Length() > 0 ) + { + return ETrue; + } + } + + return EFalse; + } + } + + /** + * Serialize an array to a newly created descriptor buffer. + * Leaves on error. + * @param aArray Array to serialize. + * @return A new output descriptor pointer. Ownership is transferred. + */ + template + HBufC8* SerializeArrayL( const RArray& aArray ) + { + const TInt KItemCount = aArray.Count(); + if ( KItemCount <= 0 ) + { + return NULL; + } + const TInt KItemSizeInBytes = sizeof( T ); + const TInt KBufferLength = KItemSizeInBytes * KItemCount; + + HBufC8* buf = HBufC8::NewL( KBufferLength ); + void* ptr = NULL; + for ( TInt i = 0; i < KBufferLength; i += KItemSizeInBytes ) + { + const T& item = aArray[ i / KItemSizeInBytes ]; + ptr = (void*)( buf->Ptr() + i ); + Mem::Copy( ptr, &item, KItemSizeInBytes ); + } + + buf->Des().SetLength( KBufferLength ); + return buf; // ownership is transferred + } + + /** + * Deserialize an array from a descriptor buffer. + * Leaves on error. + * @param aDesc Descriptor containing the serialized array. + * @param aArray Target array. + */ + template + void DeserializeArrayL( const TDesC8& aDesc, RArray& aArray ) + { + aArray.Reset(); + const TInt KItemSizeInBytes = sizeof( T ); + const TInt KBufferLength = aDesc.Size(); + const TInt KItemCount = KBufferLength / KItemSizeInBytes; + aArray.Reserve( KItemCount ); + + for ( TInt i = 0; i < KItemCount; ++i ) + { + T item; + void* ptr = (void*)( aDesc.Ptr() + i * KItemSizeInBytes ); + Mem::Copy( &item, ptr, KItemSizeInBytes ); + aArray.Append( item ); + } + } + + + + /** + * Serialize a pointer array to a newly created descriptor buffer. + * Leaves on error. + * @param aArray Pointer Array to serialize. + * @return A new output descriptor pointer. Ownership is transferred. + */ + template + HBufC8* SerializePointerArrayL( const RPointerArray& aArray ) + { + const TInt KItemCount = aArray.Count(); + if ( KItemCount <= 0 ) + { + return NULL; + } + const TInt KItemSizeInBytes = sizeof( T ); + const TInt KBufferLength = KItemSizeInBytes * KItemCount; + + HBufC8* buf = HBufC8::NewL( KBufferLength ); + void* ptr = NULL; + for ( TInt i = 0; i < KBufferLength; i += KItemSizeInBytes ) + { + const T* item = aArray[ i / KItemSizeInBytes ]; // alkup. oli const T& + ptr = (void*)( buf->Ptr() + i ); + Mem::Copy( ptr, &item, KItemSizeInBytes ); + } + + buf->Des().SetLength( KBufferLength ); + return buf; // ownership is transferred + } + + /** + * Deserialize a pointer array from a descriptor buffer. + * Leaves on error. + * @param aDesc Descriptor containing the serialized array. + * @param aArray Target Pointer Array. + */ + template + void DeserializePointerArrayL( const TDesC8& aDesc, RPointerArray& aArray ) + { + aArray.Reset(); + const TInt KItemSizeInBytes = sizeof( T ); + const TInt KBufferLength = aDesc.Size(); + const TInt KItemCount = KBufferLength / KItemSizeInBytes; + aArray.Reserve( KItemCount ); + + for ( TInt i = 0; i < KItemCount; ++i ) + { + T* item; // alkup. oli pelkkä T ilman pointteria + void* ptr = (void*)( aDesc.Ptr() + i * KItemSizeInBytes ); + Mem::Copy( &item, ptr, KItemSizeInBytes ); + aArray.Append( item ); + } + } + +#endif // MDSUTILS_H