Update contrib.
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
19 #include "oldzipfile.h"
20 #include "oldzipfilememberinputstream.h"
22 using namespace TOLDEZIP;
24 RZipFileMemberReaderStream::RZipFileMemberReaderStream(
27 TUint32 aCompressedSize,
28 TUint32 aUncompressedSize,
29 TUint32 aCompressionMethod):
31 iCompressionMethod(aCompressionMethod),
32 iCompressedSize(aCompressedSize),
33 iUncompressedSize(aUncompressedSize),
34 iFileOffset(aDataOffset)
39 RZipFileMemberReaderStream* RZipFileMemberReaderStream::NewL(
42 TUint32 aCompressedSize,
43 TUint32 aUncompressedSize,
44 TUint32 aCompressionMethod)
46 RZipFileMemberReaderStream* me = new(ELeave) RZipFileMemberReaderStream(aZipFile, aDataOffset, aCompressedSize,aUncompressedSize, aCompressionMethod);
47 CleanupStack::PushL(me);
49 CleanupStack::Pop(me);
54 Creates input stream to be used for reading the contents of the compressed file.
56 void RZipFileMemberReaderStream::ConstructL()
58 TInt err = inflateInit2(&iStream, -MAX_WBITS);
59 if (err == Z_MEM_ERROR)
61 User::Leave(KErrNoMemory);
66 Destructor. All dynamically allocated data structures for this stream are freed.
68 EXPORT_C RZipFileMemberReaderStream::~RZipFileMemberReaderStream()
74 Reads data from the stream buffer into the specified descriptor.
75 On return, contains the data read from the stream buffer
77 @param aDes The target descriptor for the data read from the stream buffer
78 @param aLength The maximum number of bytes to be read
79 @return KErrNone If all bytes read successfully.
80 @return KErrCorrupt If reading fails.
81 @return KErrEof If end of file is reached.
82 @return ... Any one of the system-wide error codes for other errors.
84 EXPORT_C TInt RZipFileMemberReaderStream::Read(TDes16& aDes, TInt aLength)
86 TUint32 numBytesRead = 0;
87 TInt err = Read(CONST_CAST(TByte*,(const TByte*)aDes.Ptr()), 2*aLength, &numBytesRead);
90 aDes.SetLength( (err==KErrEof) ? numBytesRead>>2 : 0 );
94 aDes.SetLength(numBytesRead>>2);
98 TInt RZipFileMemberReaderStream::Read(void)
103 if (Read(&b, 1, &numRead) == 1)
113 TInt RZipFileMemberReaderStream::Read(TDes8& aDes, TInt aLength)
115 TUint32 numBytesRead = 0;
116 TInt err = Read(CONST_CAST(TByte*,aDes.Ptr()), aLength, &numBytesRead);
119 aDes.SetLength( (err==KErrEof) ? numBytesRead : 0 );
123 aDes.SetLength(numBytesRead);
127 void RZipFileMemberReaderStream::ReadL(TDes16& aDes, TInt aLength)
129 User::LeaveIfError(Read(aDes, aLength));
132 void RZipFileMemberReaderStream::Release()
135 void RZipFileMemberReaderStream::Close()
139 TInt RZipFileMemberReaderStream::Read(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
141 if (iCompressionMethod == CZipArchive::EDeflated)
143 return GetBytes(aBytes, aLength, aRetLength);
147 return GetStoredBytes(aBytes, aLength, aRetLength);
151 TInt RZipFileMemberReaderStream::GetBytes(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
153 TUint32 bytesLeftToRead;
158 // Be careful not to confuse compressed bytes and uncompressed bytes.
159 // The length passed in is in uncompressed bytes, compressed bytes
160 // are mainly used in the GetCompressedBytes() function called.
161 // iBytesLength refers to the number of bytes already read.
162 // If the request is to read past the end of the file
163 // we should return KErrNone on the first instance, i.e. return all bytes
164 // read successfully. On the second instance return KErrEof, i.e. we have
165 // already read all the bytes when another request comes in, so return KErrEof.
166 // This follows the rules for reading an uncompressed file within this component
167 // and this is also the way that RFile::ReadL() does it.
169 if (aLength > iUncompressedSize)
171 aLength = iUncompressedSize; // no point trying to read more than we have
174 bytesLeftToRead = aLength;
176 while (bytesLeftToRead > 0)
178 if (iStream.avail_in == 0)
180 if (GetCompressedBytes() != KErrNone)
186 // The decompression will be done in the user provided memory.
187 iStream.next_out = &aBytes[iBytesLength];
188 iStream.avail_out = aLength - iBytesLength;
189 status = inflate(&iStream, Z_SYNC_FLUSH);
194 iBytesLength = aLength - iStream.avail_out;
197 case Z_STREAM_END: //EOF
198 if (iBytesLength == aLength - iStream.avail_out)
200 *aRetLength = iBytesLength;
205 iBytesLength = aLength - iStream.avail_out;
215 bytesLeftToRead = aLength - iBytesLength;
218 *aRetLength = iBytesLength;
222 TInt RZipFileMemberReaderStream::GetCompressedBytes(void)
224 if (iOffset < iCompressedSize)
227 TUint32 nBytesToRead;
229 nBytesLeft = iCompressedSize - iOffset;
230 nBytesToRead = (nBytesLeft > sizeof(iCompressedBytes)) ? sizeof(iCompressedBytes) : nBytesLeft;
231 if (iZipFile.Seek(iFileOffset) != KErrNone)
236 if (iZipFile.Read(iCompressedBytes, nBytesToRead) != KErrNone)
240 iFileOffset += nBytesToRead;
241 iOffset += nBytesToRead;
242 iStream.next_in = iCompressedBytes;
243 iStream.avail_in = nBytesToRead;
249 iCompressedBytes[0] = 0;
250 iStream.avail_in = 1;
251 iStream.next_in = iCompressedBytes;
261 TInt RZipFileMemberReaderStream::GetStoredBytes(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
265 if (aLength > iUncompressedSize)
267 aLength = iUncompressedSize; // no point trying to read more than we have
269 if (aLength == 0) // empty file like a directory
273 if (iOffset == iCompressedSize) // end of zip item.
277 if ((iOffset + aLength) > iCompressedSize)
279 aLength = iCompressedSize - iOffset; // adjust read to what is left
285 if (iZipFile.Seek(iFileOffset) != KErrNone)
289 status = iZipFile.Read(aBytes, aLength);
290 if (status == KErrNone)
292 iFileOffset += aLength;
294 *aRetLength = aLength;