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