diff -r 000000000000 -r ba25891c3a9e installationservices/swi/source/sisfile/compresseddataprovider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/installationservices/swi/source/sisfile/compresseddataprovider.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,191 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Definition of the Swi::CCompressedDataProvider +* +*/ + + +#include +#include + +#include "compresseddataprovider.h" + +using namespace Swi; + +/*static*/ CCompressedDataProvider* CCompressedDataProvider::NewLC(MSisDataProvider& aDataProvider, + TInt aBufferSize) + { + CCompressedDataProvider* self = new(ELeave) CCompressedDataProvider(aDataProvider); + CleanupStack::PushL(self); + self->ConstructL(aBufferSize); + return self; + } + +/*static*/ CCompressedDataProvider* CCompressedDataProvider::NewL(MSisDataProvider& aDataProvider, + TInt aBufferSize) + { + CCompressedDataProvider* self = NewLC(aDataProvider, aBufferSize); + CleanupStack::Pop(self); + return self; + } + +CCompressedDataProvider::CCompressedDataProvider(MSisDataProvider& aDataProvider) : iDataProvider(aDataProvider), + iInputDescriptor(NULL,0), + iOutputDescriptor(NULL,0), + iMore(ETrue) + { + } + +void CCompressedDataProvider::ConstructL(TInt aBufferSize) + { + TInt bufferSize; + if (aBufferSize > KDeflateBufferMaxSize) + { + bufferSize = KDeflateBufferMaxSize; + } + else + { + bufferSize = aBufferSize; + } + + iInputBuffer = HBufC8::NewL(bufferSize); + iOutputBuffer = HBufC8::NewL(bufferSize); + iInputDescriptor.Set(iInputBuffer->Des()); + iOutputDescriptor.Set(iOutputBuffer->Des()); + iDecompressor = CEZDecompressor::NewL(*this); + iBuffer = CBufFlat::NewL(bufferSize); + } + +CCompressedDataProvider::~CCompressedDataProvider() + { + delete iDecompressor; + delete iInputBuffer; + delete iOutputBuffer; + delete iBuffer; + } + +TInt CCompressedDataProvider::Read(TDes8& aDes) + { + return Read(aDes, aDes.MaxSize()); + } + +TInt CCompressedDataProvider::Read(TDes8& aDes, TInt aLength) + { + if (aLength < 0) // Cannot read a negative amount of data! + { + return KErrArgument; + } + + if (aLength > aDes.MaxSize()) // The descriptor is not big enough + { + return KErrOverflow; + } + + TInt needed = aLength; + + if (aLength > iBuffer->Size()) // will still need to decompress more + { + iBuffer->Read(0, aDes, iBuffer->Size()); // read any buffered data + needed -= iBuffer->Size(); + iBuffer->Reset(); // all data has been read, free the memory + } + else + { // enough data in the buffer no need to decompress more + iBuffer->Read(0, aDes, aLength); // read the whole length from buffered data + iBuffer->Delete(0, aLength); // delete the data that has been read from the buffer + return KErrNone; + } + + // Not enough data buffered yet... + // We need to uncompress more data! (if available) + + if (!iMore) // no more data to uncompress + { + return KErrNone; + } + + // If we are here we used up all the buffered data!! + + while (iMore) + { + TRAPD(error, iMore = iDecompressor->InflateL()); + if(KErrNone != error) + { + return error; + } + + TInt currentLength = aDes.Length(); + + if (needed > iBuffer->Size()) // will still need to decompress more + { + // Append the new data to the descriptor + aDes.SetLength(currentLength + iBuffer->Size()); + TPtr8 rest = aDes.MidTPtr(currentLength, iBuffer->Size()); + iBuffer->Read(0, rest, iBuffer->Size()); // read the buffered data + needed -= iBuffer->Size(); + iBuffer->Reset(); // all data has been read, free the memory + } + else + { // enough data in the buffer no need to decompress more + // Append the new data to the descriptor + aDes.SetLength(currentLength + needed); + TPtr8 rest = aDes.MidTPtr(currentLength, needed); + iBuffer->Read(0, rest, needed); // read the needed amount from buffered data + iBuffer->Delete(0, needed); // delete the data that has been read from the buffer + return KErrNone; + } + + if ((!iMore) || (needed==0)) // no more data to uncompress or needed + { + return KErrNone; + } + } + return KErrGeneral; + } + +TInt CCompressedDataProvider::Seek(TSeek /*aMode*/, TInt64& /*aPos*/) + { + // we cannot seek on a compressed stream at the moment! + return KErrNotSupported; + } + + +void CCompressedDataProvider::InitializeL(CEZZStream& aZStream) + { + User::LeaveIfError(iDataProvider.Read(iInputDescriptor)); + + aZStream.SetInput(iInputDescriptor); + aZStream.SetOutput(iOutputDescriptor); + } + +void CCompressedDataProvider::NeedInputL(CEZZStream& aZStream) + { + User::LeaveIfError(iDataProvider.Read(iInputDescriptor)); + aZStream.SetInput(iInputDescriptor); + } + +void CCompressedDataProvider::NeedOutputL(CEZZStream& aZStream) + { + TPtrC8 od = aZStream.OutputDescriptor(); + iBuffer->InsertL(iBuffer->Size(), od); // Should really check we are not blowing everything up!!! + iOutputDescriptor.SetLength(0); // reset since data now stored in buffer + aZStream.SetOutput(iOutputDescriptor); + } + +void CCompressedDataProvider::FinalizeL(CEZZStream& aZStream) + { + TPtrC8 od = aZStream.OutputDescriptor(); + iBuffer->InsertL(iBuffer->Size(), od); + }