--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/compressionlibs/ziplib/src/ezip/zipfilememberinputstream.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,294 @@
+// Copyright (c) 2003-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:
+//
+
+
+#include <zipfile.h>
+#include <zipfilememberinputstream.h>
+#include "libzcore.h"
+
+RZipFileMemberReaderStream::RZipFileMemberReaderStream(
+ CZipFile& aZipFile,
+ TUint32 aDataOffset,
+ TUint32 aCompressedSize,
+ TUint32 aUncompressedSize,
+ TUint32 aCompressionMethod):
+ iZipFile(aZipFile),
+ iCompressionMethod(aCompressionMethod),
+ iCompressedSize(aCompressedSize),
+ iUncompressedSize(aUncompressedSize),
+ iFileOffset(aDataOffset)
+ {
+ }
+
+
+RZipFileMemberReaderStream* RZipFileMemberReaderStream::NewL(
+ CZipFile& aZipFile,
+ TUint32 aDataOffset,
+ TUint32 aCompressedSize,
+ TUint32 aUncompressedSize,
+ TUint32 aCompressionMethod)
+ {
+ RZipFileMemberReaderStream* me = new(ELeave) RZipFileMemberReaderStream(aZipFile, aDataOffset, aCompressedSize,aUncompressedSize, aCompressionMethod);
+ CleanupStack::PushL(me);
+ me->ConstructL();
+ CleanupStack::Pop(me);
+ return me;
+ }
+
+/**
+Creates input stream to be used for reading the contents of the compressed file.
+*/
+void RZipFileMemberReaderStream::ConstructL()
+ {
+ TInt err = inflateInit2_r(&iStream, -MAX_WBITS);
+ if (err == Z_MEM_ERROR)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ }
+
+/**
+Destructor. All dynamically allocated data structures for this stream are freed.
+*/
+EXPORT_C RZipFileMemberReaderStream::~RZipFileMemberReaderStream()
+{
+ inflateEnd_r(&iStream);
+}
+
+/**
+Reads data from the stream buffer into the specified descriptor.
+On return, contains the data read from the stream buffer
+
+@param aDes The target descriptor for the data read from the stream buffer
+@param aLength The maximum number of bytes to be read
+@return KErrNone If all bytes read successfully.
+@return KErrCorrupt If reading fails.
+@return KErrEof If end of file is reached.
+@return ... Any one of the system-wide error codes for other errors.
+*/
+EXPORT_C TInt RZipFileMemberReaderStream::Read(TDes16& aDes, TInt aLength)
+{
+ TUint32 numBytesRead = 0;
+ TInt err = Read(CONST_CAST(TByte*,(const TByte*)aDes.Ptr()), 2*aLength, &numBytesRead);
+ if (err != KErrNone)
+ {
+ aDes.SetLength( (err==KErrEof) ? numBytesRead>>2 : 0 );
+ return err;
+ }
+
+ aDes.SetLength(numBytesRead>>2);
+ return KErrNone;
+}
+
+TInt RZipFileMemberReaderStream::Read(void)
+ {
+ TByte b;
+ TUint32 numRead = 0;
+
+ if (Read(&b, 1, &numRead) == 1)
+ {
+ return b;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+TInt RZipFileMemberReaderStream::Read(TDes8& aDes, TInt aLength)
+ {
+ TUint32 numBytesRead = 0;
+ TInt err = Read(CONST_CAST(TByte*,aDes.Ptr()), aLength, &numBytesRead);
+ if (err != KErrNone)
+ {
+ aDes.SetLength( (err==KErrEof) ? numBytesRead : 0 );
+ return err;
+ }
+
+ aDes.SetLength(numBytesRead);
+ return KErrNone;
+ }
+
+void RZipFileMemberReaderStream::ReadL(TDes16& aDes, TInt aLength)
+ {
+ User::LeaveIfError(Read(aDes, aLength));
+ }
+
+void RZipFileMemberReaderStream::Release()
+{}
+
+void RZipFileMemberReaderStream::Close()
+{}
+
+
+TInt RZipFileMemberReaderStream::Read(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
+ {
+ if (iCompressionMethod == CZipArchive::EDeflated)
+ {
+ return GetBytes(aBytes, aLength, aRetLength);
+ }
+ else
+ {
+ return GetStoredBytes(aBytes, aLength, aRetLength);
+ }
+ }
+
+TInt RZipFileMemberReaderStream::GetBytes(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
+ {
+ TUint32 bytesLeftToRead;
+ TInt status;
+
+ iBytesLength = 0;
+
+ // Be careful not to confuse compressed bytes and uncompressed bytes.
+ // The length passed in is in uncompressed bytes, compressed bytes
+ // are mainly used in the GetCompressedBytes() function called.
+ // iBytesLength refers to the number of bytes already read.
+ // If the request is to read past the end of the file
+ // we should return KErrNone on the first instance, i.e. return all bytes
+ // read successfully. On the second instance return KErrEof, i.e. we have
+ // already read all the bytes when another request comes in, so return KErrEof.
+ // This follows the rules for reading an uncompressed file within this component
+ // and this is also the way that RFile::ReadL() does it.
+
+ if (aLength > iUncompressedSize)
+ {
+ aLength = iUncompressedSize; // no point trying to read more than we have
+ }
+
+ bytesLeftToRead = aLength;
+
+ while (bytesLeftToRead > 0)
+ {
+ if (iStream.avail_in == 0)
+ {
+ if (GetCompressedBytes() != KErrNone)
+ {
+ return KErrCorrupt;
+ }
+ }
+
+ // The decompression will be done in the user provided memory.
+ iStream.next_out = &aBytes[iBytesLength];
+ iStream.avail_out = aLength - iBytesLength;
+ status = inflate_r(&iStream, Z_SYNC_FLUSH);
+
+ switch (status)
+ {
+ case Z_OK:
+ iBytesLength = aLength - iStream.avail_out;
+ break;
+
+ case Z_STREAM_END: //EOF
+ if (iBytesLength == aLength - iStream.avail_out)
+ {
+ *aRetLength = iBytesLength;
+ return KErrEof;
+ }
+ else
+ {
+ iBytesLength = aLength - iStream.avail_out;
+ break;
+ }
+ case Z_MEM_ERROR:
+ return KErrNoMemory;
+
+ default:
+ return KErrCorrupt;
+
+ }
+ bytesLeftToRead = aLength - iBytesLength;
+ }
+
+ *aRetLength = iBytesLength;
+ return KErrNone;
+ }
+
+TInt RZipFileMemberReaderStream::GetCompressedBytes(void)
+ {
+ if (iOffset < iCompressedSize)
+ {
+ TUint32 nBytesLeft;
+ TUint32 nBytesToRead;
+
+ nBytesLeft = iCompressedSize - iOffset;
+ nBytesToRead = (nBytesLeft > sizeof(iCompressedBytes)) ? sizeof(iCompressedBytes) : nBytesLeft;
+ if (iZipFile.Seek(iFileOffset) != KErrNone)
+ {
+ return KErrCorrupt;
+ }
+ else
+ if (iZipFile.Read(iCompressedBytes, nBytesToRead) != KErrNone)
+ {
+ return KErrCorrupt;
+ }
+ iFileOffset += nBytesToRead;
+ iOffset += nBytesToRead;
+ iStream.next_in = iCompressedBytes;
+ iStream.avail_in = nBytesToRead;
+ return KErrNone;
+ }
+ else
+ if (iDone == EFalse)
+ {
+ iCompressedBytes[0] = 0;
+ iStream.avail_in = 1;
+ iStream.next_in = iCompressedBytes;
+ iDone = ETrue;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrCorrupt;
+ }
+ }
+
+TInt RZipFileMemberReaderStream::GetStoredBytes(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
+ {
+ TInt status;
+
+ if (aLength > iUncompressedSize)
+ {
+ aLength = iUncompressedSize; // no point trying to read more than we have
+ }
+ if (aLength == 0) // empty file like a directory
+ {
+ return KErrNone;
+ }
+ if (iOffset == iCompressedSize) // end of zip item.
+ {
+ return KErrEof;
+ }
+ if ((iOffset + aLength) > iCompressedSize)
+ {
+ aLength = iCompressedSize - iOffset; // adjust read to what is left
+ if ( aLength <= 0 )
+ {
+ return KErrCorrupt;
+ }
+ }
+ if (iZipFile.Seek(iFileOffset) != KErrNone)
+ {
+ return KErrCorrupt;
+ }
+ status = iZipFile.Read(aBytes, aLength);
+ if (status == KErrNone)
+ {
+ iFileOffset += aLength;
+ iOffset += aLength;
+ *aRetLength = aLength;
+ }
+ return status;
+ }