browserutilities/multipartparser/src/GZipBufMgr.cpp
changeset 0 dd21522fd290
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browserutilities/multipartparser/src/GZipBufMgr.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,265 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*  Decompression buffer manager for GZip data
+*
+*
+*/
+
+#include <EZStream.h>
+#include "GZipBufMgr.h"
+//-----------------------------------------------------------------------------
+
+// NOTE: This code was taken from the DeflateFilter (s60/DeflateFilter/)
+
+// ----------------------------------------------------------------------------
+// StreamBufMgr::NewL
+// Two-phase constructor
+// ----------------------------------------------------------------------------
+//
+GZipBufMgr* GZipBufMgr::NewL(TPtrC8 in)
+    {
+    GZipBufMgr* self = new (ELeave)GZipBufMgr(in);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }//lint !e1746 const reference is not necessary here, because TPtrC8 takes only 4-bytes
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::GZipBufMgr
+// Constructor
+// ----------------------------------------------------------------------------
+//
+GZipBufMgr::GZipBufMgr(TPtrC8 in)
+                    : iInput(in), iOutputDes(0, 0), iOutput(0),
+                      iNeedInput(EFalse), iNeedOutput(EFalse), 
+                      iFinalized(EFalse), iOffset(0), iID1(31), iID2(139)
+    {
+    } //lint !e1746
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::ConstructL
+// Initialize the output buffer
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::ConstructL()
+    {
+    // Output buffer and descriptor
+    iOutput = HBufC8::NewMaxL(1<<15);
+    iOutputDes.Set(iOutput->Des());
+
+    // Setup the GZip header, this sets iOffset to after the header and start
+    // of the data
+	TEZGZipHeader header;
+    ReadGZipHeaderL(header);
+
+    // Move pass the header and set the buffer to the data
+	TPtrC8 data(REINTERPRET_CAST(const TUint8*, iInput.Ptr() + iOffset), iInput.Length() - iOffset);
+
+    // Setup the data buffer
+	SetGZipBuffer(data);
+
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::~GZipBufMgr
+// Destructor
+// ----------------------------------------------------------------------------
+//
+GZipBufMgr::~GZipBufMgr()
+    {
+    delete iOutput;
+    iOutput = NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::InitializeL
+// Overriden function from MEZBufferManager
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::InitializeL(CEZZStream& aZStream)
+    {
+    // read more
+    aZStream.SetInput(iInput);
+    iOutputDes.SetLength(0);
+    aZStream.SetOutput(iOutputDes);
+    iNeedInput = EFalse;
+    iNeedOutput = EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::NeedInputL
+// Overriden function from MEZBufferManager
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::NeedInputL(CEZZStream& /*aZStream*/)
+    {
+    //aZStream.SetInput(iInput);
+    iNeedInput = ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::NeedOutputL
+// Overriden function from MEZBufferManager
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::NeedOutputL(CEZZStream& /*aZStream*/)
+    {
+    //aZStream.SetOutput(iOutputDes);
+    iNeedOutput = ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::NeedOutputL
+// Overriden function from MEZBufferManager
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::FinalizeL(CEZZStream& /*aZStream*/)
+    {
+    // do nothing now, should check the checksum value here
+    // read the checksum value from the last chunk
+    //const TInt32* checksum = REINTERPRET_CAST(const TInt32*, iInput.Ptr() + (iInput.Length() - sizeof(TInt32)*2));
+    iFinalized = ETrue;
+    }
+
+
+// ----------------------------------------------------------------------------
+// Public methods
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::ReadGZipHeaderL
+// Read the header of Gzip-ed stream in Gzip format, RFC1952.
+// Sets the iOffset pointer, which marks the end of the header and start of the
+// data.  This method needs to be called (or iOffset set) before calling
+// SetGZipBuffer method.
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::ReadGZipHeaderL(TEZGZipHeader& aHeader)
+    {
+    // construct a stream for reading
+    RMemReadStream memBuf;
+    memBuf.Open(iInput.Ptr(), iInput.Length());
+    
+    TInt obligatoryData = sizeof(aHeader.iId1) + sizeof(aHeader.iId2) +
+                          sizeof(aHeader.iCompressionMethod) +
+                          sizeof(aHeader.iFlags) + sizeof(aHeader.iTime) +
+                          sizeof(aHeader.iExtraFlags) + sizeof(aHeader.iOs);
+    
+    // copy the header data
+    TPtr8 des(&aHeader.iId1, 0, obligatoryData);
+    TRAPD(error, memBuf.ReadL(des));
+    
+    if (error == KErrEof)
+        {
+        User::Leave(EZGZipFile::EBadGZipHeader);
+        }
+    
+    if (des.Size() < obligatoryData)
+        {
+        // TODO: should consider the situation when not enough data has arrived
+        User::Leave(EZGZipFile::EBadGZipHeader);
+        }
+    
+    if (aHeader.iId1 != iID1 || aHeader.iId2 != iID2)
+        {
+        User::Leave(EZGZipFile::EBadGZipHeader);
+        }
+    
+    if (aHeader.iFlags & (1 << EZGZipFile::EFExtra))
+        {
+        // The extra bit is set
+        des.Set(REINTERPRET_CAST(TUint8 *, &aHeader.iXlen), 0, sizeof(aHeader.iXlen));
+        memBuf.ReadL(des);
+        if (des.Size() != sizeof(aHeader.iXlen) || aHeader.iXlen < 0) //lint !e737 sign/unsigned doesn't realy matter here
+            {
+            User::Leave(EZGZipFile::EBadGZipHeader);
+            }
+        
+        aHeader.iExtra = HBufC8::NewMaxL(aHeader.iXlen);
+        TPtr8 des1 = aHeader.iExtra->Des();
+        memBuf.ReadL(des1);
+        
+        if (des1.Size() != aHeader.iXlen)
+            {
+            User::Leave(EZGZipFile::EBadGZipHeader);
+            }
+        }
+    
+    if (aHeader.iFlags & (1 << EZGZipFile::EFName))
+        {
+        // Read in filename
+        ReadStringIntoDescriptorL(memBuf, &aHeader.iFname);
+        }
+    
+    if (aHeader.iFlags & (1 << EZGZipFile::EFComment))
+        {
+        // Read in comment
+        ReadStringIntoDescriptorL(memBuf, &aHeader.iComment);
+        }
+    
+    if (aHeader.iFlags & (1 << EZGZipFile::EFHcrc))
+        {
+        des.Set(REINTERPRET_CAST(TUint8*, &aHeader.iCrc), 0, sizeof(aHeader.iCrc));
+        memBuf.ReadL(des);
+        if (des.Size() != sizeof(aHeader.iCrc)) //lint !e737 unsigned/signed doesn't matter
+            {
+            User::Leave(EZGZipFile::EBadGZipHeader);
+            }
+        }
+    
+    // Set iOffset to mark end of header and beginning of data
+    iOffset = memBuf.Source()->TellL(MStreamBuf::ERead).Offset();
+    
+    memBuf.Close();
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::ReadStringIntoDescriptorL
+// Read null-terminated strings into the buffer
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::ReadStringIntoDescriptorL(RMemReadStream& aMem, HBufC8 **aDes) const
+    {
+    TInt i;
+    CArrayFixFlat<TUint8> *bytes = new (ELeave) CArrayFixFlat<TUint8>(16);
+    CleanupStack::PushL(bytes);
+    TUint8 ch;
+    
+    while ((ch = aMem.ReadUint8L()) != '\0')
+        {
+        bytes->AppendL(ch);
+        }
+    
+    *aDes = HBufC8::NewMaxL(bytes->Count());
+    TPtr8 desPtr = (*aDes)->Des(); //lint because error #111 - separate desPtr used
+    
+    for (i = 0; i < bytes->Count(); i++)
+        {
+        desPtr[i] = (*bytes)[i]; //lint !e1058 force conversion here
+        }
+    
+    CleanupStack::PopAndDestroy(); // delete bytes	
+    }
+
+// ----------------------------------------------------------------------------
+// GZipBufMgr::SetBuffer
+// Set the input buffer
+// ----------------------------------------------------------------------------
+//
+void GZipBufMgr::SetGZipBuffer(TPtrC8 data)
+    {
+    iInput.Set(data);
+    }//lint !e1746