os/ossrv/compressionlibs/ziplib/test/oldezlib/zip/ZipFileMemberInputStream.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// $Revision: 1.1 $
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
sl@0
    19
#include "oldzipfile.h"
sl@0
    20
#include "oldzipfilememberinputstream.h"
sl@0
    21
sl@0
    22
using namespace TOLDEZIP;
sl@0
    23
sl@0
    24
RZipFileMemberReaderStream::RZipFileMemberReaderStream(
sl@0
    25
    CZipFile& aZipFile,
sl@0
    26
    TUint32   aDataOffset,
sl@0
    27
    TUint32   aCompressedSize,
sl@0
    28
    TUint32   aUncompressedSize,
sl@0
    29
    TUint32   aCompressionMethod):
sl@0
    30
    iZipFile(aZipFile),
sl@0
    31
	iCompressionMethod(aCompressionMethod),
sl@0
    32
    iCompressedSize(aCompressedSize),
sl@0
    33
    iUncompressedSize(aUncompressedSize),
sl@0
    34
	iFileOffset(aDataOffset)
sl@0
    35
    {    
sl@0
    36
    }
sl@0
    37
sl@0
    38
sl@0
    39
RZipFileMemberReaderStream* RZipFileMemberReaderStream::NewL(
sl@0
    40
	CZipFile& aZipFile,
sl@0
    41
    TUint32   aDataOffset,
sl@0
    42
    TUint32   aCompressedSize,
sl@0
    43
    TUint32   aUncompressedSize,
sl@0
    44
    TUint32   aCompressionMethod)
sl@0
    45
    {    
sl@0
    46
	RZipFileMemberReaderStream* me = new(ELeave) RZipFileMemberReaderStream(aZipFile, aDataOffset, aCompressedSize,aUncompressedSize, aCompressionMethod);
sl@0
    47
	CleanupStack::PushL(me);
sl@0
    48
	me->ConstructL();
sl@0
    49
	CleanupStack::Pop(me);
sl@0
    50
	return me;		
sl@0
    51
    }
sl@0
    52
sl@0
    53
/**
sl@0
    54
Creates input stream to be used for reading the contents of the compressed file.
sl@0
    55
*/
sl@0
    56
void RZipFileMemberReaderStream::ConstructL()
sl@0
    57
	{
sl@0
    58
	TInt err = inflateInit2(&iStream, -MAX_WBITS);
sl@0
    59
	if (err == Z_MEM_ERROR)
sl@0
    60
		{
sl@0
    61
		User::Leave(KErrNoMemory);
sl@0
    62
		}
sl@0
    63
	}
sl@0
    64
sl@0
    65
/**
sl@0
    66
Destructor. All dynamically allocated data structures for this stream are freed.
sl@0
    67
*/
sl@0
    68
EXPORT_C RZipFileMemberReaderStream::~RZipFileMemberReaderStream()
sl@0
    69
{
sl@0
    70
	inflateEnd(&iStream);
sl@0
    71
}
sl@0
    72
sl@0
    73
/**
sl@0
    74
Reads data from the stream buffer into the specified descriptor.
sl@0
    75
On return, contains the data read from the stream buffer
sl@0
    76
sl@0
    77
@param aDes The target descriptor for the data read from the stream buffer
sl@0
    78
@param aLength The maximum number of bytes to be read
sl@0
    79
@return KErrNone If all bytes read successfully.
sl@0
    80
@return	KErrCorrupt If reading fails.
sl@0
    81
@return KErrEof If end of file is reached.
sl@0
    82
@return ... Any one of the system-wide error codes for other errors.
sl@0
    83
*/
sl@0
    84
EXPORT_C TInt RZipFileMemberReaderStream::Read(TDes16& aDes, TInt aLength)
sl@0
    85
{
sl@0
    86
	TUint32 numBytesRead = 0;
sl@0
    87
	TInt err = Read(CONST_CAST(TByte*,(const TByte*)aDes.Ptr()), 2*aLength, &numBytesRead);
sl@0
    88
	if (err != KErrNone)
sl@0
    89
	{
sl@0
    90
		aDes.SetLength( (err==KErrEof) ? numBytesRead>>2 : 0 );
sl@0
    91
		return err;
sl@0
    92
	}
sl@0
    93
	
sl@0
    94
	aDes.SetLength(numBytesRead>>2);
sl@0
    95
	return KErrNone;
sl@0
    96
}
sl@0
    97
sl@0
    98
TInt RZipFileMemberReaderStream::Read(void)
sl@0
    99
	{
sl@0
   100
	TByte b;
sl@0
   101
	TUint32 numRead = 0;
sl@0
   102
	
sl@0
   103
	if (Read(&b, 1, &numRead) == 1)
sl@0
   104
		{
sl@0
   105
		return b;
sl@0
   106
		}
sl@0
   107
	else
sl@0
   108
		{
sl@0
   109
		return -1;
sl@0
   110
		}
sl@0
   111
	}
sl@0
   112
	
sl@0
   113
TInt RZipFileMemberReaderStream::Read(TDes8& aDes, TInt aLength)
sl@0
   114
	{
sl@0
   115
	TUint32 numBytesRead = 0;
sl@0
   116
	TInt err = Read(CONST_CAST(TByte*,aDes.Ptr()), aLength, &numBytesRead);
sl@0
   117
	if (err != KErrNone)
sl@0
   118
	{
sl@0
   119
		aDes.SetLength( (err==KErrEof) ? numBytesRead : 0 );
sl@0
   120
		return err;
sl@0
   121
	}
sl@0
   122
sl@0
   123
	aDes.SetLength(numBytesRead);
sl@0
   124
	return KErrNone;
sl@0
   125
	}
sl@0
   126
sl@0
   127
void RZipFileMemberReaderStream::ReadL(TDes16& aDes, TInt aLength)
sl@0
   128
	{
sl@0
   129
	User::LeaveIfError(Read(aDes, aLength));
sl@0
   130
	}
sl@0
   131
sl@0
   132
void RZipFileMemberReaderStream::Release()
sl@0
   133
{}
sl@0
   134
sl@0
   135
void RZipFileMemberReaderStream::Close()
sl@0
   136
{}
sl@0
   137
sl@0
   138
sl@0
   139
TInt RZipFileMemberReaderStream::Read(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
sl@0
   140
	{
sl@0
   141
	if (iCompressionMethod == CZipArchive::EDeflated)
sl@0
   142
		{
sl@0
   143
		return GetBytes(aBytes, aLength, aRetLength);
sl@0
   144
		}
sl@0
   145
	else
sl@0
   146
		{
sl@0
   147
		return GetStoredBytes(aBytes, aLength, aRetLength);
sl@0
   148
		}
sl@0
   149
	}
sl@0
   150
	
sl@0
   151
TInt RZipFileMemberReaderStream::GetBytes(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
sl@0
   152
	{
sl@0
   153
	TUint32 bytesLeftToRead;
sl@0
   154
	TInt	status;
sl@0
   155
sl@0
   156
	iBytesLength = 0;
sl@0
   157
sl@0
   158
	// Be careful not to confuse compressed bytes and uncompressed bytes.
sl@0
   159
	// The length passed in is in uncompressed bytes, compressed bytes
sl@0
   160
	// are mainly used in the GetCompressedBytes() function called.
sl@0
   161
	// iBytesLength refers to the number of bytes already read.
sl@0
   162
	// If the request is to read past the end of the file
sl@0
   163
	// we should return KErrNone on the first instance, i.e. return all bytes
sl@0
   164
	// read successfully. On the second instance return KErrEof, i.e. we have 
sl@0
   165
	// already read all the bytes when another request comes in, so return KErrEof.
sl@0
   166
	// This follows the rules for reading an uncompressed file within this component
sl@0
   167
	// and this is also the way that RFile::ReadL() does it.
sl@0
   168
sl@0
   169
	if (aLength > iUncompressedSize)
sl@0
   170
		{
sl@0
   171
		aLength = iUncompressedSize; // no point trying to read more than we have
sl@0
   172
		}
sl@0
   173
sl@0
   174
	bytesLeftToRead = aLength;
sl@0
   175
sl@0
   176
	while (bytesLeftToRead > 0) 
sl@0
   177
		{
sl@0
   178
		if (iStream.avail_in == 0)
sl@0
   179
			{
sl@0
   180
			if (GetCompressedBytes() != KErrNone)
sl@0
   181
				{
sl@0
   182
				return KErrCorrupt;
sl@0
   183
				}
sl@0
   184
			}
sl@0
   185
sl@0
   186
		// The decompression will be done in the user provided memory.
sl@0
   187
		iStream.next_out = &aBytes[iBytesLength];
sl@0
   188
		iStream.avail_out = aLength - iBytesLength;
sl@0
   189
		status = inflate(&iStream, Z_SYNC_FLUSH);
sl@0
   190
sl@0
   191
		switch (status)
sl@0
   192
			{
sl@0
   193
			case Z_OK:
sl@0
   194
				iBytesLength = aLength - iStream.avail_out;
sl@0
   195
				break;
sl@0
   196
				
sl@0
   197
			case Z_STREAM_END:	//EOF
sl@0
   198
				if (iBytesLength == aLength - iStream.avail_out)
sl@0
   199
					{
sl@0
   200
					*aRetLength = iBytesLength;
sl@0
   201
					return KErrEof;
sl@0
   202
					}
sl@0
   203
				else
sl@0
   204
					{
sl@0
   205
					iBytesLength = aLength - iStream.avail_out;
sl@0
   206
					break;
sl@0
   207
					}
sl@0
   208
			case Z_MEM_ERROR:
sl@0
   209
				return KErrNoMemory;
sl@0
   210
				
sl@0
   211
			default:
sl@0
   212
				return KErrCorrupt;
sl@0
   213
sl@0
   214
			}
sl@0
   215
		bytesLeftToRead = aLength - iBytesLength;
sl@0
   216
		}
sl@0
   217
sl@0
   218
	*aRetLength = iBytesLength;
sl@0
   219
	return KErrNone;
sl@0
   220
	}
sl@0
   221
sl@0
   222
TInt RZipFileMemberReaderStream::GetCompressedBytes(void)
sl@0
   223
	{
sl@0
   224
	if (iOffset < iCompressedSize)
sl@0
   225
		{
sl@0
   226
		TUint32	nBytesLeft;
sl@0
   227
		TUint32 nBytesToRead;
sl@0
   228
		
sl@0
   229
		nBytesLeft = iCompressedSize - iOffset;
sl@0
   230
		nBytesToRead = (nBytesLeft > sizeof(iCompressedBytes)) ? sizeof(iCompressedBytes) : nBytesLeft;
sl@0
   231
		if (iZipFile.Seek(iFileOffset) != KErrNone)
sl@0
   232
			{
sl@0
   233
			return KErrCorrupt; 
sl@0
   234
			}
sl@0
   235
		else
sl@0
   236
		if (iZipFile.Read(iCompressedBytes, nBytesToRead) != KErrNone)
sl@0
   237
			{
sl@0
   238
			return KErrCorrupt; 
sl@0
   239
			}
sl@0
   240
		iFileOffset += nBytesToRead;
sl@0
   241
		iOffset += nBytesToRead;
sl@0
   242
		iStream.next_in = iCompressedBytes;
sl@0
   243
		iStream.avail_in = nBytesToRead;
sl@0
   244
		return KErrNone;
sl@0
   245
		}
sl@0
   246
	else
sl@0
   247
	if (iDone == EFalse)
sl@0
   248
		{
sl@0
   249
		iCompressedBytes[0] = 0;
sl@0
   250
		iStream.avail_in = 1;
sl@0
   251
		iStream.next_in = iCompressedBytes;
sl@0
   252
		iDone = ETrue;
sl@0
   253
		return KErrNone;
sl@0
   254
		}
sl@0
   255
	else
sl@0
   256
		{
sl@0
   257
		return KErrCorrupt; 
sl@0
   258
		}
sl@0
   259
	}
sl@0
   260
	
sl@0
   261
TInt RZipFileMemberReaderStream::GetStoredBytes(TByte* aBytes, TUint32 aLength, TUint32* aRetLength)
sl@0
   262
	{
sl@0
   263
	TInt status;
sl@0
   264
	
sl@0
   265
	if (aLength > iUncompressedSize)
sl@0
   266
		{
sl@0
   267
		aLength = iUncompressedSize; // no point trying to read more than we have
sl@0
   268
		}
sl@0
   269
	if (aLength == 0) // empty file like a directory
sl@0
   270
		{
sl@0
   271
		return KErrNone;
sl@0
   272
		}
sl@0
   273
	if (iOffset == iCompressedSize) // end of zip item.
sl@0
   274
		{
sl@0
   275
		return KErrEof; 
sl@0
   276
		}
sl@0
   277
	if ((iOffset + aLength) > iCompressedSize)
sl@0
   278
		{
sl@0
   279
		aLength = iCompressedSize - iOffset; // adjust read to what is left
sl@0
   280
		if ( aLength <= 0 )
sl@0
   281
			{
sl@0
   282
			return KErrCorrupt; 
sl@0
   283
			}
sl@0
   284
		}
sl@0
   285
	if (iZipFile.Seek(iFileOffset) != KErrNone)
sl@0
   286
		{
sl@0
   287
		return KErrCorrupt; 
sl@0
   288
		}
sl@0
   289
	status = iZipFile.Read(aBytes, aLength);
sl@0
   290
	if (status == KErrNone)
sl@0
   291
		{
sl@0
   292
		iFileOffset += aLength;
sl@0
   293
		iOffset += aLength;
sl@0
   294
		*aRetLength = aLength;
sl@0
   295
		}
sl@0
   296
	return status;
sl@0
   297
	}