os/ossrv/lowlevellibsandfws/apputils/multipartparser/src/gzipbufmgr.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.
     1 // Copyright (c) 2002-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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Decompression buffer manager for GZip data
    15 //
    16 
    17 #include <ezstream.h>
    18 #include "gzipbufmgr.h"
    19 //-----------------------------------------------------------------------------
    20 
    21 // NOTE: This code was taken from the DeflateFilter (s60/DeflateFilter/)
    22 
    23 // ----------------------------------------------------------------------------
    24 // StreamBufMgr::NewL
    25 // Two-phase constructor
    26 // ----------------------------------------------------------------------------
    27 //
    28 GZipBufMgr* GZipBufMgr::NewL(TPtrC8 in)
    29     {
    30     GZipBufMgr* self = new (ELeave)GZipBufMgr(in);
    31     CleanupStack::PushL(self);
    32     self->ConstructL();
    33     CleanupStack::Pop();
    34     return self;
    35     }//lint !e1746 const reference is not necessary here, because TPtrC8 takes only 4-bytes
    36 
    37 // ----------------------------------------------------------------------------
    38 // GZipBufMgr::GZipBufMgr
    39 // Constructor
    40 // ----------------------------------------------------------------------------
    41 //
    42 GZipBufMgr::GZipBufMgr(TPtrC8 in)
    43                     : iInput(in), iOutputDes(0, 0), iOutput(0),
    44                       iNeedInput(EFalse), iNeedOutput(EFalse), 
    45                       iFinalized(EFalse), iOffset(0), iID1(31), iID2(139)
    46     {
    47     } //lint !e1746
    48 
    49 // ----------------------------------------------------------------------------
    50 // GZipBufMgr::ConstructL
    51 // Initialize the output buffer
    52 // ----------------------------------------------------------------------------
    53 //
    54 void GZipBufMgr::ConstructL()
    55     {
    56     // Output buffer and descriptor
    57     iOutput = HBufC8::NewMaxL(1<<15);
    58     iOutputDes.Set(iOutput->Des());
    59 
    60     // Setup the GZip header, this sets iOffset to after the header and start
    61     // of the data
    62 	TEZGZipHeader header;
    63     ReadGZipHeaderL(header);
    64 
    65     // Move pass the header and set the buffer to the data
    66 	TPtrC8 data(REINTERPRET_CAST(const TUint8*, iInput.Ptr() + iOffset), iInput.Length() - iOffset);
    67 
    68     // Setup the data buffer
    69 	SetGZipBuffer(data);
    70 
    71     }
    72 
    73 // ----------------------------------------------------------------------------
    74 // GZipBufMgr::~GZipBufMgr
    75 // Destructor
    76 // ----------------------------------------------------------------------------
    77 //
    78 GZipBufMgr::~GZipBufMgr()
    79     {
    80     delete iOutput;
    81     iOutput = NULL;
    82     }
    83 
    84 // ----------------------------------------------------------------------------
    85 // GZipBufMgr::InitializeL
    86 // Overriden function from MEZBufferManager
    87 // ----------------------------------------------------------------------------
    88 //
    89 void GZipBufMgr::InitializeL(CEZZStream& aZStream)
    90     {
    91     // read more
    92     aZStream.SetInput(iInput);
    93     iOutputDes.SetLength(0);
    94     aZStream.SetOutput(iOutputDes);
    95     iNeedInput = EFalse;
    96     iNeedOutput = EFalse;
    97     }
    98 
    99 // ----------------------------------------------------------------------------
   100 // GZipBufMgr::NeedInputL
   101 // Overriden function from MEZBufferManager
   102 // ----------------------------------------------------------------------------
   103 //
   104 void GZipBufMgr::NeedInputL(CEZZStream& /*aZStream*/)
   105     {
   106     //aZStream.SetInput(iInput);
   107     iNeedInput = ETrue;
   108     }
   109 
   110 // ----------------------------------------------------------------------------
   111 // GZipBufMgr::NeedOutputL
   112 // Overriden function from MEZBufferManager
   113 // ----------------------------------------------------------------------------
   114 //
   115 void GZipBufMgr::NeedOutputL(CEZZStream& /*aZStream*/)
   116     {
   117     //aZStream.SetOutput(iOutputDes);
   118     iNeedOutput = ETrue;
   119     }
   120 
   121 // ----------------------------------------------------------------------------
   122 // GZipBufMgr::NeedOutputL
   123 // Overriden function from MEZBufferManager
   124 // ----------------------------------------------------------------------------
   125 //
   126 void GZipBufMgr::FinalizeL(CEZZStream& /*aZStream*/)
   127     {
   128     // do nothing now, should check the checksum value here
   129     // read the checksum value from the last chunk
   130     //const TInt32* checksum = REINTERPRET_CAST(const TInt32*, iInput.Ptr() + (iInput.Length() - sizeof(TInt32)*2));
   131     iFinalized = ETrue;
   132     }
   133 
   134 
   135 // ----------------------------------------------------------------------------
   136 // Public methods
   137 // ----------------------------------------------------------------------------
   138 
   139 // ----------------------------------------------------------------------------
   140 // GZipBufMgr::ReadGZipHeaderL
   141 // Read the header of Gzip-ed stream in Gzip format, RFC1952.
   142 // Sets the iOffset pointer, which marks the end of the header and start of the
   143 // data.  This method needs to be called (or iOffset set) before calling
   144 // SetGZipBuffer method.
   145 // ----------------------------------------------------------------------------
   146 //
   147 void GZipBufMgr::ReadGZipHeaderL(TEZGZipHeader& aHeader)
   148     {
   149     // construct a stream for reading
   150     RMemReadStream memBuf;
   151     memBuf.Open(iInput.Ptr(), iInput.Length());
   152     
   153     TInt obligatoryData = sizeof(aHeader.iId1) + sizeof(aHeader.iId2) +
   154                           sizeof(aHeader.iCompressionMethod) +
   155                           sizeof(aHeader.iFlags) + sizeof(aHeader.iTime) +
   156                           sizeof(aHeader.iExtraFlags) + sizeof(aHeader.iOs);
   157     
   158     // copy the header data
   159     TPtr8 des(&aHeader.iId1, 0, obligatoryData);
   160     TRAPD(error, memBuf.ReadL(des));
   161     
   162     if (error == KErrEof)
   163         {
   164         User::Leave(EZGZipFile::EBadGZipHeader);
   165         }
   166     
   167     if (des.Size() < obligatoryData)
   168         {
   169         // should consider the situation when not enough data has arrived
   170         User::Leave(EZGZipFile::EBadGZipHeader);
   171         }
   172     
   173     if (aHeader.iId1 != iID1 || aHeader.iId2 != iID2)
   174         {
   175         User::Leave(EZGZipFile::EBadGZipHeader);
   176         }
   177     
   178     if (aHeader.iFlags & (1 << EZGZipFile::EFExtra))
   179         {
   180         // The extra bit is set
   181         des.Set(REINTERPRET_CAST(TUint8 *, &aHeader.iXlen), 0, sizeof(aHeader.iXlen));
   182         memBuf.ReadL(des);
   183         if (des.Size() != sizeof(aHeader.iXlen) || aHeader.iXlen < 0) //lint !e737 sign/unsigned doesn't realy matter here
   184             {
   185             User::Leave(EZGZipFile::EBadGZipHeader);
   186             }
   187         
   188         aHeader.iExtra = HBufC8::NewMaxL(aHeader.iXlen);
   189         TPtr8 des1 = aHeader.iExtra->Des();
   190         memBuf.ReadL(des1);
   191         
   192         if (des1.Size() != aHeader.iXlen)
   193             {
   194             User::Leave(EZGZipFile::EBadGZipHeader);
   195             }
   196         }
   197     
   198     if (aHeader.iFlags & (1 << EZGZipFile::EFName))
   199         {
   200         // Read in filename
   201         ReadStringIntoDescriptorL(memBuf, &aHeader.iFname);
   202         }
   203     
   204     if (aHeader.iFlags & (1 << EZGZipFile::EFComment))
   205         {
   206         // Read in comment
   207         ReadStringIntoDescriptorL(memBuf, &aHeader.iComment);
   208         }
   209     
   210     if (aHeader.iFlags & (1 << EZGZipFile::EFHcrc))
   211         {
   212         des.Set(REINTERPRET_CAST(TUint8*, &aHeader.iCrc), 0, sizeof(aHeader.iCrc));
   213         memBuf.ReadL(des);
   214         if (des.Size() != sizeof(aHeader.iCrc)) //lint !e737 unsigned/signed doesn't matter
   215             {
   216             User::Leave(EZGZipFile::EBadGZipHeader);
   217             }
   218         }
   219     
   220     // Set iOffset to mark end of header and beginning of data
   221     iOffset = memBuf.Source()->TellL(MStreamBuf::ERead).Offset();
   222     
   223     memBuf.Close();
   224     }
   225 
   226 // ----------------------------------------------------------------------------
   227 // GZipBufMgr::ReadStringIntoDescriptorL
   228 // Read null-terminated strings into the buffer
   229 // ----------------------------------------------------------------------------
   230 //
   231 void GZipBufMgr::ReadStringIntoDescriptorL(RMemReadStream& aMem, HBufC8 **aDes) const
   232     {
   233     TInt i;
   234     CArrayFixFlat<TUint8> *bytes = new (ELeave) CArrayFixFlat<TUint8>(16);
   235     CleanupStack::PushL(bytes);
   236     TUint8 ch;
   237     
   238     while ((ch = aMem.ReadUint8L()) != '\0')
   239         {
   240         bytes->AppendL(ch);
   241         }
   242     
   243     *aDes = HBufC8::NewMaxL(bytes->Count());
   244     TPtr8 desPtr = (*aDes)->Des(); //lint because error #111 - separate desPtr used
   245     
   246     for (i = 0; i < bytes->Count(); i++)
   247         {
   248         desPtr[i] = (*bytes)[i]; //lint !e1058 force conversion here
   249         }
   250     
   251     CleanupStack::PopAndDestroy(); // delete bytes	
   252     }
   253 
   254 // ----------------------------------------------------------------------------
   255 // GZipBufMgr::SetBuffer
   256 // Set the input buffer
   257 // ----------------------------------------------------------------------------
   258 //
   259 void GZipBufMgr::SetGZipBuffer(TPtrC8 data)
   260     {
   261     iInput.Set(data);
   262     }//lint !e1746