realtimenetprots/sipfw/SigComp/CompDeflate/src/DeflateComp.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SigComp/CompDeflate/src/DeflateComp.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,904 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Name        : CDeflateComp.cpp
+// Part of     : deflatecomp
+// deflate ECOM plugin, CSigCompCompressor implementation
+// Version     : 1.4
+//
+
+
+
+#include <e32base.h>
+#include <badesca.h>
+#include <hash.h>
+
+#include "Sigcomp.h"
+#include "sigcompcompartment.h"
+#include "SigCompStateMgr.h"
+
+#include "DeflateComp.h"
+#include "Deflate.h"
+#include "SigCompDeflateContext.h"
+#include "StateMgr.h"
+#include "Udvm.h"
+#include "sigcompstateitem.h"
+#include "MessageWriter.h"
+
+
+/** SIP dictionary hash */
+static const TUint8 KSIPDictionaryHash[] =
+    {
+    0xfb, 0xe5, 0x07, 0xdf, 0xe5, 0xe6, 0xaa, 0x5a, 0xf2, 0xab,
+    0xb9, 0x14, 0xce, 0xaa, 0x05, 0xf9, 0x9c, 0xe6, 0x1b, 0xa5
+    };
+
+/** size of the first part of SIP dictionary,
+    phrases only. RFC 3485.*/
+const TInt KSIPDictionaryPhrasesSize = 0x0d8c;
+
+
+/** mask to get cpb value from returned parameters */
+//static const TInt KReturnedParametersCPBMask = 3;
+
+/** number of bits returned parameters has to be shifted right
+    to get cpb value */
+static const TInt KReturnedParametersCPBShift = 6;
+
+/** mask to get dms value from returned parameters */
+static const TInt KReturnedParametersDMSMask = 7;
+
+/** number of bits returned parameters has to be shifted right
+    to get dms value */
+static const TInt KReturnedParametersDMSShift = 3;
+
+/** mask to get sms value from returned parameters */
+static const TInt KReturnedParametersSMSMask = 7;
+
+/** number of bits returned parameters has to be shifted right
+    to get sms value */
+static const TInt KReturnedParametersSMSShift = 0;
+
+
+/** RFC3220 chapter 7. each sigcomp message starts with 5 bits set to 1 */
+static const TInt KMessageCommonHeader = (0x1f << 3);
+
+/** T bit in message header */
+static const TInt KMessageHeaderTBit (1 << 2);
+
+/** length to be set in message header. 0x1 == 6 bytes of hash id length */
+static const TInt KMessageHeaderLen = 0x01;
+
+/** 'requested feedback is present' flag */
+static const TInt KRequestedFeedbackPresentFlag = 4;
+
+/** number of bits size of bytecode must be shifted left to get it
+    on correct position in header*/
+static const TInt KBytecodeLengthShift = 4;
+
+/** number of bits bytecode destination must be shifted right to get
+    correct bit representation of destination. note, the bit
+    representation is actually (dest >> shift) - 1 */
+static const TInt KBytecodeDestinationShift = 6;
+
+/** number of bits cycles must be shifted left to het it on correct position
+    in returned parameters field */
+//static const TInt KParametersCyclesShift = 6;
+
+/** number of bits memory size must be shifted left to get in on correct
+    position in returned parameters field */
+//static const TInt KParametersMemorySizeShift = 3;
+
+_LIT8(KZero, "\0");
+_LIT8(KEightZeros, "\0\0\0\0\0\0\0\0");
+
+/** minimum circular buffer size */
+static const TInt KMinCBSize = (258/2+1);
+
+
+// ----------------------------------------------------------------------------
+
+CDeflateComp* CDeflateComp::NewL(TAny* aInitParams)
+    {
+    return new (ELeave)CDeflateComp(aInitParams);  
+    }
+
+
+// ----------------------------------------------------------------------------
+
+CDeflateComp::CDeflateComp(TAny* aInitParams)
+    {
+    TCompressorInitParams* initParams = static_cast<TCompressorInitParams*>
+                                        (aInitParams);
+    iStateMgr = initParams->iStateMgr;
+    iStateItem = initParams->iStateItem;
+    iStateItemLength = initParams->iStateItemLength;
+    iUploadState = initParams->iUploadState;
+
+    // SIP dictionary
+    if (iStateItem)
+        {
+        if (!Mem::Compare(iStateItem->iStateIdentifier,
+                          sizeof(KSIPDictionaryHash),
+                          KSIPDictionaryHash, sizeof(KSIPDictionaryHash)))
+            {
+            if (iStateItemLength > KSIPDictionaryPhrasesSize)
+                iStateItemLength = KSIPDictionaryPhrasesSize;
+            }
+
+        }
+    }
+
+// ----------------------------------------------------------------------------
+
+CDeflateComp::~CDeflateComp()
+    {
+    }
+
+
+
+// ----------------------------------------------------------------------------
+
+TUint CDeflateComp::SetDictionary(const TStateItem* aDictionaryState,
+                                  CDeflate* aDeflateComp,
+                                CSigCompDeflateContext* aDeflateContext) const
+    {
+    if (aDictionaryState)
+        {
+        TInt dictLength;
+        const TUint8* ptr = aDictionaryState->iStateValue;
+
+        dictLength = (iStateItemLength > aDeflateContext->WindowSize()) ?
+                      aDeflateContext->WindowSize() : iStateItemLength;
+
+        ptr += (iStateItemLength - dictLength);
+
+        aDeflateComp->SetDictionary(ptr, dictLength);
+        return 1;
+        }
+
+    return 0;
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::AppendDataL(CMessageWriter* aWriter, TUint8 aValue)
+    {
+    aWriter->WriteByteL(aValue);
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::AppendDataL(CMessageWriter* aWriter, TUint16 aValue)
+    {
+    TUint8 tmp = static_cast<TUint8>((aValue >> 8) & KMax8BitValueMask);
+    aWriter->WriteByteL(tmp);
+    tmp = static_cast<TUint8>(aValue & KMax8BitValueMask);
+    aWriter->WriteByteL(tmp);
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::AppendDataL(CMessageWriter* aWriter, const TDesC8& aData)
+    {
+    aWriter->WriteBlockL(aData);
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::AppendRequestedFeedbackL(CMessageWriter *aWriter,
+                                            const TDesC8& aRequestedFeedback)
+    {
+    if (aRequestedFeedback.Length())
+        {
+        const TUint8* rfdata = aRequestedFeedback.Ptr();
+        if (rfdata[0] & KRequestedFeedbackPresentFlag)
+            {
+            AppendDataL(aWriter,
+                        TPtrC8(&rfdata[1], 
+                               aRequestedFeedback.Length() - 1));
+            }
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::CalculateBytecodeHashL(
+                               CSigCompDeflateContext* aDeflateContext,
+                               TDeflateCompBytecodeId aBytecode,
+                               TUint8 aReturnedParameters)
+    {
+
+    CSHA1* sha1 = CSHA1::NewL();
+    CleanupStack::PushL(sha1);
+    sha1->Reset();
+
+    // set state header
+    TUint start = KDeflateBytecodes[aBytecode].iStateStart;
+    TUint instr = KDeflateBytecodes[aBytecode].iBytecodeStart;
+    TUint size = KDeflateBytecodes[aBytecode].iStateSize;
+
+    TUint8 stateData[8+11];
+    stateData[0] = static_cast<TUint8>((size >> 8) & 0xff);
+    stateData[1] = static_cast<TUint8>(size & 0xff);
+    stateData[2] = static_cast<TUint8>((start >> 8) & 0xff);
+    stateData[3] = static_cast<TUint8>(start & 0xff);
+    stateData[4] = static_cast<TUint8>((instr >> 8) & 0xff);
+    stateData[5] = static_cast<TUint8>(instr & 0xff);
+    stateData[6] = 0;
+    stateData[7] = 6;
+
+    // set bytecode values area
+
+    switch (aBytecode)
+        {
+        case EStaticBytecode:
+            {
+/*
+:state_area_start
+:dictionary_id                  pad (6)
+:dictionary_phrases_size        pad (2)
+:returned_parameters_location   pad (1)
+:returned_sigcomp_version       pad (1)
+:returned_parameters_zero       pad (1)
+*/
+            if (iStateItem)
+                {
+                Mem::Copy(&stateData[8],
+                          iStateItem->iStateIdentifier,
+                          KMinPartialStateLength);
+                stateData[8+6] = static_cast<TUint8>(
+                                    (iStateItemLength >> 8) & 0xff);
+                stateData[8+7] = static_cast<TUint8>(
+                                    iStateItemLength & 0xff);
+                }
+            else
+                {
+                Mem::FillZ(&stateData[8], KMinPartialStateLength + 2);
+                }
+            stateData[8+8] = static_cast<TUint8>(aReturnedParameters);
+            stateData[8+9] = static_cast<TUint8>(KSigCompVersion);
+            stateData[8+10] = static_cast<TUint8>(0);
+
+            sha1->Hash(TPtrC8(stateData, 8+11));
+            break;
+            }
+
+        case EStaticUploadBytecode:
+            {
+            // hash from feedback
+            break;
+            }
+
+        case EDynamicBytecode:
+            {
+/*
+:state_area_start
+:returned_parameters_location   pad (1)
+:returned_sigcomp_version       pad (1)
+:returned_parameters_zero       pad (1)
+*/
+            stateData[8+0] = static_cast<TUint8>(aReturnedParameters);
+            stateData[8+1] = static_cast<TUint8>(KSigCompVersion);
+            stateData[8+2] = static_cast<TUint8>(0);
+
+            sha1->Hash(TPtrC8(stateData, 8+3));
+            break;
+            }
+            
+        case EDynamicUploadBytecode:
+            {
+            // hash from feedback
+            break;
+            }
+        }
+
+    TPtrC8 hash = sha1->Hash(TPtrC8(KDeflateBytecodes[aBytecode].iBytecode,
+                               KDeflateBytecodes[aBytecode].iBytecodeSize));
+
+    TInt toZero = KDeflateBytecodes[aBytecode].iStateSize -
+                  KDeflateBytecodes[aBytecode].iBytecodeInit +
+                  KDeflateBytecodes[aBytecode].iStateStart -
+                  KDeflateBytecodes[aBytecode].iBytecodeSize;
+    TInt i;
+    for(i=0; i<toZero; i++)
+        {
+// Not covered because current bytecodes not need that
+// I left the code there, as it may be usefull for other bytecodes.
+        hash.Set(sha1->Hash(KZero));
+        }
+
+    aDeflateContext->SetBytecodeHash(hash.Ptr());
+
+    CleanupStack::PopAndDestroy(sha1);
+    }
+
+
+// ----------------------------------------------------------------------------
+
+TInt CDeflateComp::EncodeCyclesPerBit(
+                                   CSigComp::TCyclesPerBit aCyclesPerBit) const
+    {
+    TInt result = 0;
+    TUint value = aCyclesPerBit >> 5;
+
+    while (value)
+        {
+        result++;
+        value >>= 1;
+        }
+
+    return result;
+    }
+
+
+// ----------------------------------------------------------------------------
+
+TInt CDeflateComp::EncodeMemorySize(CSigComp::TMemorySize aMemorySize) const
+    {
+    TInt result = 0;
+    TUint value = aMemorySize >> 11;
+
+    while (value)
+        {
+        result++;
+        value >>= 1;
+        }
+
+    return result;
+    }
+
+
+// ----------------------------------------------------------------------------
+
+CSigComp::TMemorySize CDeflateComp::DecodeMemorySize(TInt aMemorySize)
+    {
+
+    TInt result = aMemorySize ? 1 << (10+aMemorySize) : 0;
+
+    return static_cast<CSigComp::TMemorySize>(result);
+    }
+
+
+// ----------------------------------------------------------------------------
+
+TUint8 CDeflateComp::EncodeReturnedParameters(
+                               MSigCompCompartmentContext* aCompartmentContext)
+    {
+    return static_cast<TUint8>(
+        (EncodeCyclesPerBit(aCompartmentContext->CyclesPerBit()) <<
+            KReturnedParametersCPBShift) |
+        (EncodeMemorySize(aCompartmentContext->DecompressionMemorySize()) <<
+            KReturnedParametersDMSShift) |
+        (EncodeMemorySize(aCompartmentContext->StateMemorySize()) <<
+            KReturnedParametersSMSShift));
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::ParseReturnedParameters(const TDesC8& aReturnedParameters,
+                                       CSigCompDeflateContext* aDeflateContext)
+    {
+
+    if (aReturnedParameters.Length())
+        {
+        const TUint8* retpdata = aReturnedParameters.Ptr();
+        TUint8 rp = *retpdata;
+
+        aDeflateContext->SetDms(
+            DecodeMemorySize((rp >> KReturnedParametersDMSShift) &
+                KReturnedParametersDMSMask));
+        aDeflateContext->SetSms(
+            DecodeMemorySize((rp >> KReturnedParametersSMSShift) &
+                KReturnedParametersSMSMask));
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+
+void CDeflateComp::AppendDataHeaderL(CMessageWriter* aWriter,
+                                     TDeflateCompBytecodeId aBytecode,
+                                     TUint8 aReturnedParameters,
+                                     TInt aUdvmSize,
+                                     TBool aFirstMessage,
+                                     CSigCompDeflateContext* aDeflateContext)
+    {
+
+    switch (aBytecode)
+        {
+        case EStaticBytecode:
+            {
+/*
+    dictionary_id:                6 bytes (1st message only)
+    dictionary_phrases_size:      2 bytes (1st message only)
+    returned_parameters_location: 1 byte  (1st message only)
+    returned_sigcomp_version:     1 byte  (1st message only)
+    udvm_memory_size:             2 bytes
+*/
+            if (aFirstMessage)
+                {
+                if (iStateItem)
+                    {
+                    AppendDataL(aWriter,
+                                TPtrC8(iStateItem->iStateIdentifier,
+                                       KMinPartialStateLength));
+                    AppendDataL(aWriter,
+                                static_cast<TUint16>(iStateItemLength));
+                    }
+                else
+                    {
+                    AppendDataL(aWriter, KEightZeros);
+                    }
+
+                AppendDataL(aWriter, aReturnedParameters);
+                AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
+                }
+
+            AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
+
+            break;
+            }
+
+        case EStaticUploadBytecode:
+            {
+/*
+    udvm_memory_size:             2 bytes
+    state_length                  2 bytes (1st message only)
+    state value                   state_length bytes (1st message only)
+    returned_parameters_location: 1 byte  (1st message only)
+    returned_sigcomp_version:     1 byte  (1st message only)
+*/
+            AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
+
+            if (aFirstMessage)
+                {
+                AppendDataL(aWriter, static_cast<TUint16>(iStateItemLength));
+                AppendDataL(aWriter, TPtrC8(iStateItem->iStateValue,
+                                            iStateItemLength));
+                AppendDataL(aWriter, aReturnedParameters);
+                AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
+                }
+
+            break;
+            }
+
+        case EDynamicBytecode:
+            {
+/*
+    returned_parameters_location: 1 byte  (1st message only)
+    returned_sigcomp_version:     1 byte  (1st message only)
+    udvm_memory_size:             2 bytes
+    dictionary_phrases_size:      2 bytes
+    dictionary_id:                6 bytes (if dictionary_phrases_size!=0)
+    cbstate_size:                 2 bytes
+    cbstate_id:                   6 bytes (if cbstate_size!=0)
+*/
+            if (aFirstMessage)
+                {
+                AppendDataL(aWriter, aReturnedParameters);
+                AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
+                }
+
+            AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
+
+            if (aDeflateContext->CBStateConfirmed())
+                {
+                AppendDataL(aWriter, static_cast<TUint16>(0));
+                AppendDataL(aWriter, static_cast<TUint16>(
+                                aDeflateContext->CBStateLength()));
+                AppendDataL(aWriter, TPtrC8(aDeflateContext->CBStateHash(),
+                                            KMinPartialStateLength));
+                }
+            else
+                {
+                if (iStateItem)
+                    {
+                    AppendDataL(aWriter, static_cast<TUint16>(
+                                                iStateItemLength));
+                    AppendDataL(aWriter, TPtrC8(iStateItem->iStateIdentifier,
+                                                KMinPartialStateLength));
+                    AppendDataL(aWriter, static_cast<TUint16>(0));
+                    }
+                else
+                    {
+                    AppendDataL(aWriter, static_cast<TUint16>(0));
+                    AppendDataL(aWriter, static_cast<TUint16>(0));
+                    }
+                }
+            break;
+            }
+
+        case EDynamicUploadBytecode:
+            {
+/*
+    udvm_memory_size:             2 bytes
+    state_length                  2 bytes (1st message only)
+    state value                   state_length bytes (1st message only)
+    returned_parameters_location: 1 byte  (1st message only)
+    returned_sigcomp_version:     1 byte  (1st message only)
+    cbstate_size:                 2 bytes (nth message only)
+    cbstate_id:                   6 bytes (if cbstate_size!=0)
+*/
+            AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
+
+            if (aFirstMessage)
+                {
+                AppendDataL(aWriter, static_cast<TUint16>(iStateItemLength));
+                AppendDataL(aWriter, TPtrC8(iStateItem->iStateValue,
+                                            iStateItemLength));
+                AppendDataL(aWriter, aReturnedParameters);
+                AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
+                }
+            else
+                {
+                if (aDeflateContext->CBStateConfirmed())
+                    {
+                    AppendDataL(aWriter, static_cast<TUint16>(
+                                    aDeflateContext->CBStateLength()));
+                    AppendDataL(aWriter, TPtrC8(aDeflateContext->CBStateHash(),
+                                                KMinPartialStateLength));
+                    }
+                else
+                    {
+                    AppendDataL(aWriter, static_cast<TUint16>(0));
+                    }
+                }
+
+            break;
+            }
+        }
+    }
+
+    
+// ----------------------------------------------------------------------------
+
+TInt CDeflateComp::CalcCBSizeL(TInt& aUdvmSize,
+                                TDeflateCompBytecodeId aBytecode,
+                                CSigCompDeflateContext* aDeflateContext)
+    {
+
+    TInt cbSize = aUdvmSize - KDeflateBytecodes[aBytecode].iCBufStart;
+
+    // no memory for bytecode and circular buffer
+    if (cbSize < 0)
+        return cbSize;
+
+    switch (aBytecode)
+        {
+        case EStaticBytecode:
+            {
+            break;
+            }
+
+        case EStaticUploadBytecode:
+            {
+            break;
+            }
+
+        case EDynamicBytecode:
+            {
+            TInt availSms = aDeflateContext->Sms() -
+                            KDeflateBytecodes[aBytecode].iStateSize -
+                            KStateCostExtension;
+
+            if (availSms <= 0)
+                {
+                return cbSize;
+                }
+
+            if ((cbSize+2+KStateCostExtension) > availSms)
+                {
+                cbSize = availSms - 2 - KStateCostExtension;
+                aUdvmSize = cbSize + KDeflateBytecodes[aBytecode].iCBufStart;
+                }
+
+            break;
+            }
+            
+        case EDynamicUploadBytecode:
+            {
+            TInt availSms = aDeflateContext->Sms() -
+                            KDeflateBytecodes[aBytecode].iStateSize -
+                            KStateCostExtension -
+                            iStateItemLength -
+                            KStateCostExtension;
+
+            if (availSms <= 0)
+                {
+                return cbSize;
+                }
+
+            if ((cbSize+2+KStateCostExtension) > availSms)
+                {
+                cbSize = availSms - 2 - KStateCostExtension;
+                aUdvmSize = cbSize + KDeflateBytecodes[aBytecode].iCBufStart;
+                }
+
+            break;
+            }
+        }
+
+    return cbSize;
+    }
+
+// ----------------------------------------------------------------------------
+
+CSigCompDeflateContext* CDeflateComp::DeflateContextL(
+                               MSigCompCompartmentContext* aCompartmentContext)
+    {
+    CSigCompCompressionContext* tmpContext = 
+                                   const_cast<CSigCompCompressionContext*>
+                                   (aCompartmentContext->CompressionContext());
+
+    CSigCompDeflateContext* deflateContext =
+                                           static_cast<CSigCompDeflateContext*>
+                                           (tmpContext);
+
+    if (deflateContext == NULL)
+        {
+        deflateContext = new (ELeave)CSigCompDeflateContext();
+        aCompartmentContext->SetCompressionContext(
+                             static_cast<CSigCompCompressionContext*>
+                             (deflateContext));
+        deflateContext->SetUploadState(iUploadState);
+        deflateContext->SetStateItem(iStateItem, iStateItemLength);
+        }
+    else
+        {
+        iUploadState = deflateContext->UploadState();
+        iStateItem = deflateContext->StateItem();
+        iStateItemLength = deflateContext->StateItemLength();
+        }
+
+    return deflateContext;
+    }
+
+
+// ----------------------------------------------------------------------------
+
+CBufBase* CDeflateComp::CompressMessageL(
+                              MSigCompCompartmentContext* aCompartmentContext,
+                              const TDesC8& aMessage,
+                              TBool aForStreamBasedProtocol)
+    {
+
+    if (aMessage.Length() == 0)
+        {
+        User::Leave(CSigComp::ECompressionFailure);
+        }
+
+    TBool dynamic = aCompartmentContext->IsDynamicCompression();
+
+    CSigCompDeflateContext* deflateContext =
+                                      DeflateContextL(aCompartmentContext);
+
+    ParseReturnedParameters(aCompartmentContext->ReturnedParameters(),
+                            deflateContext);
+
+    // select bytecode
+    TDeflateCompBytecodeId bytecode;
+
+    if (iUploadState)
+        {
+        if (dynamic)
+            bytecode = EDynamicUploadBytecode;
+        else
+            bytecode = EStaticUploadBytecode;
+        }
+    else
+        {
+        if (dynamic)
+            bytecode = EDynamicBytecode;
+        else
+            bytecode = EStaticBytecode;
+        }
+
+    CBufFlat* outputBuffer = CBufFlat::NewL(32);
+    CleanupStack::PushL(outputBuffer);
+    outputBuffer->SetReserveL(32);
+
+    CMessageWriter* messageWriter = new (ELeave)CMessageWriter(outputBuffer,
+                                                      aForStreamBasedProtocol);
+    CleanupStack::PushL(messageWriter);
+
+    TInt msgPos = 0;
+    while (msgPos < aMessage.Size())
+        {
+        TInt msgSize = aMessage.Size() - msgPos;
+
+        if (aForStreamBasedProtocol)
+            {
+            if (msgSize > KMaxOutputSize)
+                {
+                msgSize = KMaxOutputSize;
+                }
+            }
+        else
+            {
+            if (msgSize > KMaxOutputSize)
+                {
+                User::Leave(CSigComp::ECompressionFailure);
+                }
+            }
+
+        TPtrC8 message(aMessage.Mid(msgPos, msgSize));
+
+        const TDesC8& requestedFeedback =
+                            aCompartmentContext->RequestedFeedback();
+        const TDesC8& returnedFeedback =
+                            aCompartmentContext->ReturnedFeedback();
+
+        CDeflate* deflateComp = CDeflate::NewL(dynamic, deflateContext);
+        CleanupStack::PushL(deflateComp);
+
+        TUint8 returnedParameters =
+                            EncodeReturnedParameters(aCompartmentContext);
+
+        if (!deflateContext->BytecodeStateConfirmed())
+            {
+            if (returnedFeedback.Length())
+                {
+                if(deflateContext->UploadState())
+                    {
+                    deflateContext->SetBytecodeHash(returnedFeedback.Ptr() +
+                                                    dynamic*8);
+                    deflateContext->SetBytecodeStateConfirmed(ETrue);
+                    }
+                else
+                    {
+                    CalculateBytecodeHashL(deflateContext, bytecode,
+                                           returnedParameters);
+                    deflateContext->SetBytecodeStateConfirmed(ETrue);
+                    }
+                }
+            }
+
+        if (dynamic)
+            {
+            if (returnedFeedback.Length())
+                {
+                deflateContext->SetCBStateHash(returnedFeedback.Ptr());
+                TInt cbLen = (returnedFeedback.Ptr()[6]<<8) +
+                             returnedFeedback.Ptr()[7];
+                deflateContext->SetCBStateLength(cbLen);
+                deflateContext->SetCBStateConfirmed(ETrue);
+                }
+            else
+                {
+                deflateContext->SetCBStateConfirmed(EFalse);
+                deflateComp->Reset();
+                }
+            }
+
+        TUint8 header = KMessageCommonHeader;
+
+        if (requestedFeedback.Length())
+            {
+            header |= KMessageHeaderTBit;
+            }
+
+        if(!deflateContext->BytecodeStateConfirmed())
+            {
+            AppendDataL(messageWriter, header);
+            AppendRequestedFeedbackL(messageWriter, requestedFeedback);
+
+            TUint16 lendest = static_cast<TUint16>(
+                                (KDeflateBytecodes[bytecode].iBytecodeSize <<
+                                    KBytecodeLengthShift) |
+                                ((KDeflateBytecodes[bytecode].iBytecodeInit >>
+                                    KBytecodeDestinationShift) - 1));
+
+            AppendDataL(messageWriter, lendest);
+            AppendDataL(messageWriter,
+                        TPtrC8(KDeflateBytecodes[bytecode].iBytecode,
+                               KDeflateBytecodes[bytecode].iBytecodeSize));
+            }
+        else
+            {
+            header |= KMessageHeaderLen;
+            AppendDataL(messageWriter, header);
+            AppendRequestedFeedbackL(messageWriter, requestedFeedback);
+
+            AppendDataL(messageWriter,
+                        TPtrC8(deflateContext->BytecodeHash(),
+                               KMinPartialStateLength));
+            }
+
+        // calculate available memory on remote side
+        TInt udvmSize = -1;
+        TInt cbSize = -1;
+        if (deflateContext->BytecodeStateConfirmed())
+            {
+            udvmSize = deflateContext->UdvmSize();
+            cbSize = deflateContext->CBSize();
+            }
+        else
+            {
+            TInt dms = deflateContext->Dms();
+            for (; (udvmSize < 0) || (cbSize < KMinCBSize); dms<<=1)
+                {
+                if (aForStreamBasedProtocol)
+                    {
+                    udvmSize = dms / 2;
+                    }
+                else
+                    {
+                    // simulate compressed message size
+                    TInt msgSize = outputBuffer->Size() + 2 +
+                                   message.Length() + 50;
+                    if(iUploadState &&
+                       !deflateContext->BytecodeStateConfirmed())
+                        msgSize += iStateItemLength;
+
+                    udvmSize = dms - msgSize;
+                    }
+
+                if (udvmSize > 0)
+                    {
+                    if (udvmSize > static_cast<TInt>(KMaxUdvmMemorySize))
+                        {
+                        udvmSize = KMaxUdvmMemorySize;
+                        }
+
+                    cbSize = CalcCBSizeL(udvmSize, bytecode, deflateContext);
+                    }
+                }
+                deflateContext->SetUdvmSize(udvmSize);
+                deflateContext->SetCBSize(cbSize);
+            }
+
+        AppendDataHeaderL(messageWriter,
+                          bytecode, returnedParameters, udvmSize,
+                          !deflateContext->BytecodeStateConfirmed(),
+                          deflateContext);
+
+        //configure deflate compressor
+        deflateComp->ChangeWindowSizeL(cbSize);
+
+        if ((!dynamic) || (!deflateContext->CBStateConfirmed()))
+            {
+            SetDictionary(deflateContext->StateItem(),
+                          deflateComp,
+                          deflateContext);
+            }
+
+        //compress actual data
+        deflateComp->CompressL(message, messageWriter);
+        CleanupStack::PopAndDestroy(deflateComp);
+
+        messageWriter->FlushAndTerminateL();
+
+        // clean feedbacks
+        aCompartmentContext->SetRequestedFeedbackL(KNullDesC8);
+        aCompartmentContext->SetReturnedFeedbackL(KNullDesC8);
+
+        msgPos += msgSize;
+        }
+    outputBuffer->Compress();
+    CleanupStack::PopAndDestroy(messageWriter);
+    CleanupStack::Pop(outputBuffer);
+
+    return outputBuffer;
+    }
+
+TBool CDeflateComp::IsDynamicCompressionSupported()
+    {
+    return ETrue;
+    }