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