1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/lowlevellibsandfws/apputils/multipartparser/src/gzipbufmgr.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,262 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Decompression buffer manager for GZip data
1.18 +//
1.19 +
1.20 +#include <ezstream.h>
1.21 +#include "gzipbufmgr.h"
1.22 +//-----------------------------------------------------------------------------
1.23 +
1.24 +// NOTE: This code was taken from the DeflateFilter (s60/DeflateFilter/)
1.25 +
1.26 +// ----------------------------------------------------------------------------
1.27 +// StreamBufMgr::NewL
1.28 +// Two-phase constructor
1.29 +// ----------------------------------------------------------------------------
1.30 +//
1.31 +GZipBufMgr* GZipBufMgr::NewL(TPtrC8 in)
1.32 + {
1.33 + GZipBufMgr* self = new (ELeave)GZipBufMgr(in);
1.34 + CleanupStack::PushL(self);
1.35 + self->ConstructL();
1.36 + CleanupStack::Pop();
1.37 + return self;
1.38 + }//lint !e1746 const reference is not necessary here, because TPtrC8 takes only 4-bytes
1.39 +
1.40 +// ----------------------------------------------------------------------------
1.41 +// GZipBufMgr::GZipBufMgr
1.42 +// Constructor
1.43 +// ----------------------------------------------------------------------------
1.44 +//
1.45 +GZipBufMgr::GZipBufMgr(TPtrC8 in)
1.46 + : iInput(in), iOutputDes(0, 0), iOutput(0),
1.47 + iNeedInput(EFalse), iNeedOutput(EFalse),
1.48 + iFinalized(EFalse), iOffset(0), iID1(31), iID2(139)
1.49 + {
1.50 + } //lint !e1746
1.51 +
1.52 +// ----------------------------------------------------------------------------
1.53 +// GZipBufMgr::ConstructL
1.54 +// Initialize the output buffer
1.55 +// ----------------------------------------------------------------------------
1.56 +//
1.57 +void GZipBufMgr::ConstructL()
1.58 + {
1.59 + // Output buffer and descriptor
1.60 + iOutput = HBufC8::NewMaxL(1<<15);
1.61 + iOutputDes.Set(iOutput->Des());
1.62 +
1.63 + // Setup the GZip header, this sets iOffset to after the header and start
1.64 + // of the data
1.65 + TEZGZipHeader header;
1.66 + ReadGZipHeaderL(header);
1.67 +
1.68 + // Move pass the header and set the buffer to the data
1.69 + TPtrC8 data(REINTERPRET_CAST(const TUint8*, iInput.Ptr() + iOffset), iInput.Length() - iOffset);
1.70 +
1.71 + // Setup the data buffer
1.72 + SetGZipBuffer(data);
1.73 +
1.74 + }
1.75 +
1.76 +// ----------------------------------------------------------------------------
1.77 +// GZipBufMgr::~GZipBufMgr
1.78 +// Destructor
1.79 +// ----------------------------------------------------------------------------
1.80 +//
1.81 +GZipBufMgr::~GZipBufMgr()
1.82 + {
1.83 + delete iOutput;
1.84 + iOutput = NULL;
1.85 + }
1.86 +
1.87 +// ----------------------------------------------------------------------------
1.88 +// GZipBufMgr::InitializeL
1.89 +// Overriden function from MEZBufferManager
1.90 +// ----------------------------------------------------------------------------
1.91 +//
1.92 +void GZipBufMgr::InitializeL(CEZZStream& aZStream)
1.93 + {
1.94 + // read more
1.95 + aZStream.SetInput(iInput);
1.96 + iOutputDes.SetLength(0);
1.97 + aZStream.SetOutput(iOutputDes);
1.98 + iNeedInput = EFalse;
1.99 + iNeedOutput = EFalse;
1.100 + }
1.101 +
1.102 +// ----------------------------------------------------------------------------
1.103 +// GZipBufMgr::NeedInputL
1.104 +// Overriden function from MEZBufferManager
1.105 +// ----------------------------------------------------------------------------
1.106 +//
1.107 +void GZipBufMgr::NeedInputL(CEZZStream& /*aZStream*/)
1.108 + {
1.109 + //aZStream.SetInput(iInput);
1.110 + iNeedInput = ETrue;
1.111 + }
1.112 +
1.113 +// ----------------------------------------------------------------------------
1.114 +// GZipBufMgr::NeedOutputL
1.115 +// Overriden function from MEZBufferManager
1.116 +// ----------------------------------------------------------------------------
1.117 +//
1.118 +void GZipBufMgr::NeedOutputL(CEZZStream& /*aZStream*/)
1.119 + {
1.120 + //aZStream.SetOutput(iOutputDes);
1.121 + iNeedOutput = ETrue;
1.122 + }
1.123 +
1.124 +// ----------------------------------------------------------------------------
1.125 +// GZipBufMgr::NeedOutputL
1.126 +// Overriden function from MEZBufferManager
1.127 +// ----------------------------------------------------------------------------
1.128 +//
1.129 +void GZipBufMgr::FinalizeL(CEZZStream& /*aZStream*/)
1.130 + {
1.131 + // do nothing now, should check the checksum value here
1.132 + // read the checksum value from the last chunk
1.133 + //const TInt32* checksum = REINTERPRET_CAST(const TInt32*, iInput.Ptr() + (iInput.Length() - sizeof(TInt32)*2));
1.134 + iFinalized = ETrue;
1.135 + }
1.136 +
1.137 +
1.138 +// ----------------------------------------------------------------------------
1.139 +// Public methods
1.140 +// ----------------------------------------------------------------------------
1.141 +
1.142 +// ----------------------------------------------------------------------------
1.143 +// GZipBufMgr::ReadGZipHeaderL
1.144 +// Read the header of Gzip-ed stream in Gzip format, RFC1952.
1.145 +// Sets the iOffset pointer, which marks the end of the header and start of the
1.146 +// data. This method needs to be called (or iOffset set) before calling
1.147 +// SetGZipBuffer method.
1.148 +// ----------------------------------------------------------------------------
1.149 +//
1.150 +void GZipBufMgr::ReadGZipHeaderL(TEZGZipHeader& aHeader)
1.151 + {
1.152 + // construct a stream for reading
1.153 + RMemReadStream memBuf;
1.154 + memBuf.Open(iInput.Ptr(), iInput.Length());
1.155 +
1.156 + TInt obligatoryData = sizeof(aHeader.iId1) + sizeof(aHeader.iId2) +
1.157 + sizeof(aHeader.iCompressionMethod) +
1.158 + sizeof(aHeader.iFlags) + sizeof(aHeader.iTime) +
1.159 + sizeof(aHeader.iExtraFlags) + sizeof(aHeader.iOs);
1.160 +
1.161 + // copy the header data
1.162 + TPtr8 des(&aHeader.iId1, 0, obligatoryData);
1.163 + TRAPD(error, memBuf.ReadL(des));
1.164 +
1.165 + if (error == KErrEof)
1.166 + {
1.167 + User::Leave(EZGZipFile::EBadGZipHeader);
1.168 + }
1.169 +
1.170 + if (des.Size() < obligatoryData)
1.171 + {
1.172 + // should consider the situation when not enough data has arrived
1.173 + User::Leave(EZGZipFile::EBadGZipHeader);
1.174 + }
1.175 +
1.176 + if (aHeader.iId1 != iID1 || aHeader.iId2 != iID2)
1.177 + {
1.178 + User::Leave(EZGZipFile::EBadGZipHeader);
1.179 + }
1.180 +
1.181 + if (aHeader.iFlags & (1 << EZGZipFile::EFExtra))
1.182 + {
1.183 + // The extra bit is set
1.184 + des.Set(REINTERPRET_CAST(TUint8 *, &aHeader.iXlen), 0, sizeof(aHeader.iXlen));
1.185 + memBuf.ReadL(des);
1.186 + if (des.Size() != sizeof(aHeader.iXlen) || aHeader.iXlen < 0) //lint !e737 sign/unsigned doesn't realy matter here
1.187 + {
1.188 + User::Leave(EZGZipFile::EBadGZipHeader);
1.189 + }
1.190 +
1.191 + aHeader.iExtra = HBufC8::NewMaxL(aHeader.iXlen);
1.192 + TPtr8 des1 = aHeader.iExtra->Des();
1.193 + memBuf.ReadL(des1);
1.194 +
1.195 + if (des1.Size() != aHeader.iXlen)
1.196 + {
1.197 + User::Leave(EZGZipFile::EBadGZipHeader);
1.198 + }
1.199 + }
1.200 +
1.201 + if (aHeader.iFlags & (1 << EZGZipFile::EFName))
1.202 + {
1.203 + // Read in filename
1.204 + ReadStringIntoDescriptorL(memBuf, &aHeader.iFname);
1.205 + }
1.206 +
1.207 + if (aHeader.iFlags & (1 << EZGZipFile::EFComment))
1.208 + {
1.209 + // Read in comment
1.210 + ReadStringIntoDescriptorL(memBuf, &aHeader.iComment);
1.211 + }
1.212 +
1.213 + if (aHeader.iFlags & (1 << EZGZipFile::EFHcrc))
1.214 + {
1.215 + des.Set(REINTERPRET_CAST(TUint8*, &aHeader.iCrc), 0, sizeof(aHeader.iCrc));
1.216 + memBuf.ReadL(des);
1.217 + if (des.Size() != sizeof(aHeader.iCrc)) //lint !e737 unsigned/signed doesn't matter
1.218 + {
1.219 + User::Leave(EZGZipFile::EBadGZipHeader);
1.220 + }
1.221 + }
1.222 +
1.223 + // Set iOffset to mark end of header and beginning of data
1.224 + iOffset = memBuf.Source()->TellL(MStreamBuf::ERead).Offset();
1.225 +
1.226 + memBuf.Close();
1.227 + }
1.228 +
1.229 +// ----------------------------------------------------------------------------
1.230 +// GZipBufMgr::ReadStringIntoDescriptorL
1.231 +// Read null-terminated strings into the buffer
1.232 +// ----------------------------------------------------------------------------
1.233 +//
1.234 +void GZipBufMgr::ReadStringIntoDescriptorL(RMemReadStream& aMem, HBufC8 **aDes) const
1.235 + {
1.236 + TInt i;
1.237 + CArrayFixFlat<TUint8> *bytes = new (ELeave) CArrayFixFlat<TUint8>(16);
1.238 + CleanupStack::PushL(bytes);
1.239 + TUint8 ch;
1.240 +
1.241 + while ((ch = aMem.ReadUint8L()) != '\0')
1.242 + {
1.243 + bytes->AppendL(ch);
1.244 + }
1.245 +
1.246 + *aDes = HBufC8::NewMaxL(bytes->Count());
1.247 + TPtr8 desPtr = (*aDes)->Des(); //lint because error #111 - separate desPtr used
1.248 +
1.249 + for (i = 0; i < bytes->Count(); i++)
1.250 + {
1.251 + desPtr[i] = (*bytes)[i]; //lint !e1058 force conversion here
1.252 + }
1.253 +
1.254 + CleanupStack::PopAndDestroy(); // delete bytes
1.255 + }
1.256 +
1.257 +// ----------------------------------------------------------------------------
1.258 +// GZipBufMgr::SetBuffer
1.259 +// Set the input buffer
1.260 +// ----------------------------------------------------------------------------
1.261 +//
1.262 +void GZipBufMgr::SetGZipBuffer(TPtrC8 data)
1.263 + {
1.264 + iInput.Set(data);
1.265 + }//lint !e1746