sl@0: /* sl@0: * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * Implementation of utility functions for copying and streaming RArray/RpointerArray. sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: @released sl@0: */ sl@0: sl@0: #ifndef STREAMINGARRAY_INL sl@0: #define STREAMINGARRAY_INL sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // Traits classes - internally required by RArray/RPointerArray functions sl@0: sl@0: template sl@0: class TTraits sl@0: { sl@0: public: sl@0: static T* CopyL(const T& aRight) { return T::NewL(aRight);} sl@0: static T* ReadFromStreamL(RReadStream& aStream) { return T::NewL(aStream); } sl@0: static T* ReadFromStreamLC(RReadStream& aStream) { return T::NewLC(aStream); } sl@0: static void WriteToStreamL(const T& aItem, RWriteStream& aStream) { aStream << aItem; } sl@0: }; sl@0: sl@0: // Specialisation for HBufC sl@0: template <> sl@0: class TTraits sl@0: { sl@0: public: sl@0: static HBufC16* CopyL(const HBufC16& aOther) { return aOther.AllocL();} sl@0: static HBufC16* ReadFromStreamL(RReadStream& aStream) { return HBufC16::NewL(aStream, KMaxTInt); } sl@0: static HBufC16* ReadFromStreamLC(RReadStream& aStream) { return HBufC16::NewLC(aStream, KMaxTInt); } sl@0: static void WriteToStreamL(const HBufC16& aItem, RWriteStream& aStream) { aStream << aItem; } sl@0: }; sl@0: sl@0: template <> sl@0: class TTraits sl@0: { sl@0: public: sl@0: static HBufC8* CopyL(const HBufC8& aOther) { return aOther.AllocL();} sl@0: static HBufC8* ReadFromStreamL(RReadStream& aStream) { return HBufC8::NewL(aStream, KMaxTInt); } sl@0: static HBufC8* ReadFromStreamLC(RReadStream& aStream) { return HBufC8::NewLC(aStream, KMaxTInt); } sl@0: static void WriteToStreamL(const HBufC8& aItem, RWriteStream& aStream) { aStream << aItem; } sl@0: }; sl@0: sl@0: // Size calculator - internally required by RPointerArray functions sl@0: sl@0: template sl@0: TInt GetObjectBufferSizeL(const T& aObject) sl@0: { sl@0: TInt size(0); sl@0: RNullWriteStream nullstream; sl@0: CleanupClosePushL(nullstream); sl@0: nullstream << aObject; sl@0: nullstream.CommitL(); sl@0: size = nullstream.BytesWritten(); sl@0: CleanupStack::PopAndDestroy(&nullstream); sl@0: return size; sl@0: } sl@0: sl@0: template sl@0: TInt ExternalizedBufferSizeL(const RPointerArray& aArray) sl@0: /** sl@0: Calculates how much buffer is required for a pointers array to be externalized. sl@0: @param aArray The pointer array whose buffer size will be calculated. sl@0: @return Returns the number of bytes occupied by the elements of the pointer array. sl@0: */ sl@0: { sl@0: TInt totalSize(1); // 1-byte is reserved for the array count sl@0: TInt count = aArray.Count(); sl@0: sl@0: for (TInt i = 0; i < count; ++i) sl@0: { sl@0: totalSize += GetObjectBufferSizeL(*aArray[i]); sl@0: } sl@0: return totalSize; sl@0: } sl@0: sl@0: sl@0: // RPointerArray utilities sl@0: sl@0: template sl@0: void CopyPointerArrayL(RPointerArray& aTarget, const RPointerArray& aSource) sl@0: { sl@0: TInt arrayCount = aSource.Count(); sl@0: for (TInt i = 0; i < arrayCount; ++i) sl@0: { sl@0: T* item = TTraits::CopyL(*aSource[i]); sl@0: CleanupStack::PushL(item); sl@0: User::LeaveIfError(aTarget.Append(item)); sl@0: CleanupStack::Pop(item); sl@0: } sl@0: } sl@0: sl@0: template sl@0: HBufC8* ExternalizePointersArrayLC(const RPointerArray& aArray, TBool aAddLength) sl@0: { sl@0: TInt arraySize = ExternalizedBufferSizeL(aArray); sl@0: HBufC8 *arrayBuf = HBufC8::NewLC(arraySize + sizeof(TInt32)); sl@0: TPtr8 arrayPtr(arrayBuf->Des()); sl@0: sl@0: RDesWriteStream stream(arrayPtr); sl@0: stream.PushL(); sl@0: ExternalizePointersArrayL(aArray, stream, aAddLength); sl@0: stream.Pop(); sl@0: stream.Release(); sl@0: return arrayBuf; sl@0: } sl@0: sl@0: template sl@0: void ExternalizePointersArrayL(const RPointerArray& aArray, RWriteStream& aStream, TBool aAddLength) sl@0: { sl@0: TInt arrayCount = aArray.Count(); sl@0: if(aAddLength) sl@0: aStream << TCardinality(arrayCount); sl@0: for (TInt i = 0; i < arrayCount; ++i) sl@0: { sl@0: TTraits::WriteToStreamL(*aArray[i], aStream); sl@0: } sl@0: aStream.CommitL(); sl@0: } sl@0: sl@0: template sl@0: void InternalizePointersArrayL(RPointerArray& aArray, RReadStream& aStream, TBool aAddLength) sl@0: { sl@0: TInt count (0); sl@0: if(aAddLength) sl@0: { sl@0: TCardinality c; sl@0: aStream >> c; sl@0: count = c; sl@0: } sl@0: for (TInt i = 0; i < count; ++i) sl@0: { sl@0: T* item = TTraits::ReadFromStreamL(aStream); sl@0: CleanupStack::PushL(item); sl@0: User::LeaveIfError(aArray.Append(item)); sl@0: CleanupStack::Pop(item); sl@0: } sl@0: } sl@0: sl@0: sl@0: // Size calculator - internally required by RArray/RPointerArray functions sl@0: sl@0: template sl@0: TInt ExternalizedBufferSizeL(const RArray& aArray) sl@0: /** sl@0: Calculates how much buffer is required for a fixed length array to be externalized. sl@0: @param aArray The array whose buffer size will be calculated. sl@0: @return Returns the number of bytes of the array's dynamic memory. sl@0: */ sl@0: { sl@0: TInt totalSize(1); // 1-byte is reserved for the array count sl@0: TInt count = aArray.Count(); sl@0: sl@0: for (TInt i = 0; i < count; ++i) sl@0: { sl@0: totalSize += GetObjectBufferSizeL(TPckgC(aArray[i])); sl@0: } sl@0: return totalSize; sl@0: } sl@0: sl@0: sl@0: // RArray utilities sl@0: sl@0: template sl@0: void CopyFixedLengthArrayL(RArray& aTarget, const RArray& aSource) sl@0: { sl@0: TInt arrayCount = aSource.Count(); sl@0: for (TInt i = 0; i < arrayCount; ++i) sl@0: { sl@0: User::LeaveIfError(aTarget.Append(aSource[i])); sl@0: } sl@0: } sl@0: sl@0: template sl@0: HBufC8* ExternalizeFixedLengthArrayL(const RArray& aArray) sl@0: { sl@0: TInt arraySize = ExternalizedBufferSizeL(aArray, arraySize); sl@0: HBufC8 *arrayBuf = HBufC8::NewLC(arraySize + sizeof(TInt32)); sl@0: TPtr8 arrayPtr(arrayBuf->Des()); sl@0: sl@0: RDesWriteStream stream(arrayPtr); sl@0: stream.PushL(); sl@0: ExternalizeFixedLengthArrayL(aArray, stream); sl@0: stream.Pop(); sl@0: stream.Release(); sl@0: return arrayBuf; sl@0: } sl@0: sl@0: template sl@0: void ExternalizeFixedLengthArrayL(const RArray& aArray, RWriteStream& aStream) sl@0: { sl@0: TInt arrayCount = aArray.Count(); sl@0: aStream << TCardinality(arrayCount); sl@0: for (TInt i = 0; i < arrayCount; ++i) sl@0: { sl@0: aStream.WriteL(TPckgC(aArray[i])); sl@0: } sl@0: aStream.CommitL(); sl@0: } sl@0: sl@0: sl@0: template sl@0: void InternalizeFixedLengthArrayL(RArray& aArray, RReadStream& aStream) sl@0: { sl@0: TCardinality c; sl@0: aStream >> c; sl@0: TInt count = c; sl@0: for (TInt i = 0; i < count; ++i) sl@0: { sl@0: T item; sl@0: TPckg itemPckg(item); sl@0: aStream.ReadL(itemPckg); sl@0: User::LeaveIfError(aArray.Append(item)); sl@0: } sl@0: } sl@0: sl@0: #endif /* STREAMINGARRAY_INL*/