installationservices/swi/source/sisfile/compresseddataprovider.cpp
changeset 0 ba25891c3a9e
--- /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 <ezdecompressor.h>
+#include <ezstream.h>
+
+#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);
+	}