realtimenetprots/sipfw/SigComp/CompDeflate/src/DeflateComp.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     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 // Name        : CDeflateComp.cpp
       
    15 // Part of     : deflatecomp
       
    16 // deflate ECOM plugin, CSigCompCompressor implementation
       
    17 // Version     : 1.4
       
    18 //
       
    19 
       
    20 
       
    21 
       
    22 #include <e32base.h>
       
    23 #include <badesca.h>
       
    24 #include <hash.h>
       
    25 
       
    26 #include "Sigcomp.h"
       
    27 #include "sigcompcompartment.h"
       
    28 #include "SigCompStateMgr.h"
       
    29 
       
    30 #include "DeflateComp.h"
       
    31 #include "Deflate.h"
       
    32 #include "SigCompDeflateContext.h"
       
    33 #include "StateMgr.h"
       
    34 #include "Udvm.h"
       
    35 #include "sigcompstateitem.h"
       
    36 #include "MessageWriter.h"
       
    37 
       
    38 
       
    39 /** SIP dictionary hash */
       
    40 static const TUint8 KSIPDictionaryHash[] =
       
    41     {
       
    42     0xfb, 0xe5, 0x07, 0xdf, 0xe5, 0xe6, 0xaa, 0x5a, 0xf2, 0xab,
       
    43     0xb9, 0x14, 0xce, 0xaa, 0x05, 0xf9, 0x9c, 0xe6, 0x1b, 0xa5
       
    44     };
       
    45 
       
    46 /** size of the first part of SIP dictionary,
       
    47     phrases only. RFC 3485.*/
       
    48 const TInt KSIPDictionaryPhrasesSize = 0x0d8c;
       
    49 
       
    50 
       
    51 /** mask to get cpb value from returned parameters */
       
    52 //static const TInt KReturnedParametersCPBMask = 3;
       
    53 
       
    54 /** number of bits returned parameters has to be shifted right
       
    55     to get cpb value */
       
    56 static const TInt KReturnedParametersCPBShift = 6;
       
    57 
       
    58 /** mask to get dms value from returned parameters */
       
    59 static const TInt KReturnedParametersDMSMask = 7;
       
    60 
       
    61 /** number of bits returned parameters has to be shifted right
       
    62     to get dms value */
       
    63 static const TInt KReturnedParametersDMSShift = 3;
       
    64 
       
    65 /** mask to get sms value from returned parameters */
       
    66 static const TInt KReturnedParametersSMSMask = 7;
       
    67 
       
    68 /** number of bits returned parameters has to be shifted right
       
    69     to get sms value */
       
    70 static const TInt KReturnedParametersSMSShift = 0;
       
    71 
       
    72 
       
    73 /** RFC3220 chapter 7. each sigcomp message starts with 5 bits set to 1 */
       
    74 static const TInt KMessageCommonHeader = (0x1f << 3);
       
    75 
       
    76 /** T bit in message header */
       
    77 static const TInt KMessageHeaderTBit (1 << 2);
       
    78 
       
    79 /** length to be set in message header. 0x1 == 6 bytes of hash id length */
       
    80 static const TInt KMessageHeaderLen = 0x01;
       
    81 
       
    82 /** 'requested feedback is present' flag */
       
    83 static const TInt KRequestedFeedbackPresentFlag = 4;
       
    84 
       
    85 /** number of bits size of bytecode must be shifted left to get it
       
    86     on correct position in header*/
       
    87 static const TInt KBytecodeLengthShift = 4;
       
    88 
       
    89 /** number of bits bytecode destination must be shifted right to get
       
    90     correct bit representation of destination. note, the bit
       
    91     representation is actually (dest >> shift) - 1 */
       
    92 static const TInt KBytecodeDestinationShift = 6;
       
    93 
       
    94 /** number of bits cycles must be shifted left to het it on correct position
       
    95     in returned parameters field */
       
    96 //static const TInt KParametersCyclesShift = 6;
       
    97 
       
    98 /** number of bits memory size must be shifted left to get in on correct
       
    99     position in returned parameters field */
       
   100 //static const TInt KParametersMemorySizeShift = 3;
       
   101 
       
   102 _LIT8(KZero, "\0");
       
   103 _LIT8(KEightZeros, "\0\0\0\0\0\0\0\0");
       
   104 
       
   105 /** minimum circular buffer size */
       
   106 static const TInt KMinCBSize = (258/2+1);
       
   107 
       
   108 
       
   109 // ----------------------------------------------------------------------------
       
   110 
       
   111 CDeflateComp* CDeflateComp::NewL(TAny* aInitParams)
       
   112     {
       
   113     return new (ELeave)CDeflateComp(aInitParams);  
       
   114     }
       
   115 
       
   116 
       
   117 // ----------------------------------------------------------------------------
       
   118 
       
   119 CDeflateComp::CDeflateComp(TAny* aInitParams)
       
   120     {
       
   121     TCompressorInitParams* initParams = static_cast<TCompressorInitParams*>
       
   122                                         (aInitParams);
       
   123     iStateMgr = initParams->iStateMgr;
       
   124     iStateItem = initParams->iStateItem;
       
   125     iStateItemLength = initParams->iStateItemLength;
       
   126     iUploadState = initParams->iUploadState;
       
   127 
       
   128     // SIP dictionary
       
   129     if (iStateItem)
       
   130         {
       
   131         if (!Mem::Compare(iStateItem->iStateIdentifier,
       
   132                           sizeof(KSIPDictionaryHash),
       
   133                           KSIPDictionaryHash, sizeof(KSIPDictionaryHash)))
       
   134             {
       
   135             if (iStateItemLength > KSIPDictionaryPhrasesSize)
       
   136                 iStateItemLength = KSIPDictionaryPhrasesSize;
       
   137             }
       
   138 
       
   139         }
       
   140     }
       
   141 
       
   142 // ----------------------------------------------------------------------------
       
   143 
       
   144 CDeflateComp::~CDeflateComp()
       
   145     {
       
   146     }
       
   147 
       
   148 
       
   149 
       
   150 // ----------------------------------------------------------------------------
       
   151 
       
   152 TUint CDeflateComp::SetDictionary(const TStateItem* aDictionaryState,
       
   153                                   CDeflate* aDeflateComp,
       
   154                                 CSigCompDeflateContext* aDeflateContext) const
       
   155     {
       
   156     if (aDictionaryState)
       
   157         {
       
   158         TInt dictLength;
       
   159         const TUint8* ptr = aDictionaryState->iStateValue;
       
   160 
       
   161         dictLength = (iStateItemLength > aDeflateContext->WindowSize()) ?
       
   162                       aDeflateContext->WindowSize() : iStateItemLength;
       
   163 
       
   164         ptr += (iStateItemLength - dictLength);
       
   165 
       
   166         aDeflateComp->SetDictionary(ptr, dictLength);
       
   167         return 1;
       
   168         }
       
   169 
       
   170     return 0;
       
   171     }
       
   172 
       
   173 
       
   174 // ----------------------------------------------------------------------------
       
   175 
       
   176 void CDeflateComp::AppendDataL(CMessageWriter* aWriter, TUint8 aValue)
       
   177     {
       
   178     aWriter->WriteByteL(aValue);
       
   179     }
       
   180 
       
   181 
       
   182 // ----------------------------------------------------------------------------
       
   183 
       
   184 void CDeflateComp::AppendDataL(CMessageWriter* aWriter, TUint16 aValue)
       
   185     {
       
   186     TUint8 tmp = static_cast<TUint8>((aValue >> 8) & KMax8BitValueMask);
       
   187     aWriter->WriteByteL(tmp);
       
   188     tmp = static_cast<TUint8>(aValue & KMax8BitValueMask);
       
   189     aWriter->WriteByteL(tmp);
       
   190     }
       
   191 
       
   192 
       
   193 // ----------------------------------------------------------------------------
       
   194 
       
   195 void CDeflateComp::AppendDataL(CMessageWriter* aWriter, const TDesC8& aData)
       
   196     {
       
   197     aWriter->WriteBlockL(aData);
       
   198     }
       
   199 
       
   200 
       
   201 // ----------------------------------------------------------------------------
       
   202 
       
   203 void CDeflateComp::AppendRequestedFeedbackL(CMessageWriter *aWriter,
       
   204                                             const TDesC8& aRequestedFeedback)
       
   205     {
       
   206     if (aRequestedFeedback.Length())
       
   207         {
       
   208         const TUint8* rfdata = aRequestedFeedback.Ptr();
       
   209         if (rfdata[0] & KRequestedFeedbackPresentFlag)
       
   210             {
       
   211             AppendDataL(aWriter,
       
   212                         TPtrC8(&rfdata[1], 
       
   213                                aRequestedFeedback.Length() - 1));
       
   214             }
       
   215         }
       
   216     }
       
   217 
       
   218 
       
   219 // ----------------------------------------------------------------------------
       
   220 
       
   221 void CDeflateComp::CalculateBytecodeHashL(
       
   222                                CSigCompDeflateContext* aDeflateContext,
       
   223                                TDeflateCompBytecodeId aBytecode,
       
   224                                TUint8 aReturnedParameters)
       
   225     {
       
   226 
       
   227     CSHA1* sha1 = CSHA1::NewL();
       
   228     CleanupStack::PushL(sha1);
       
   229     sha1->Reset();
       
   230 
       
   231     // set state header
       
   232     TUint start = KDeflateBytecodes[aBytecode].iStateStart;
       
   233     TUint instr = KDeflateBytecodes[aBytecode].iBytecodeStart;
       
   234     TUint size = KDeflateBytecodes[aBytecode].iStateSize;
       
   235 
       
   236     TUint8 stateData[8+11];
       
   237     stateData[0] = static_cast<TUint8>((size >> 8) & 0xff);
       
   238     stateData[1] = static_cast<TUint8>(size & 0xff);
       
   239     stateData[2] = static_cast<TUint8>((start >> 8) & 0xff);
       
   240     stateData[3] = static_cast<TUint8>(start & 0xff);
       
   241     stateData[4] = static_cast<TUint8>((instr >> 8) & 0xff);
       
   242     stateData[5] = static_cast<TUint8>(instr & 0xff);
       
   243     stateData[6] = 0;
       
   244     stateData[7] = 6;
       
   245 
       
   246     // set bytecode values area
       
   247 
       
   248     switch (aBytecode)
       
   249         {
       
   250         case EStaticBytecode:
       
   251             {
       
   252 /*
       
   253 :state_area_start
       
   254 :dictionary_id                  pad (6)
       
   255 :dictionary_phrases_size        pad (2)
       
   256 :returned_parameters_location   pad (1)
       
   257 :returned_sigcomp_version       pad (1)
       
   258 :returned_parameters_zero       pad (1)
       
   259 */
       
   260             if (iStateItem)
       
   261                 {
       
   262                 Mem::Copy(&stateData[8],
       
   263                           iStateItem->iStateIdentifier,
       
   264                           KMinPartialStateLength);
       
   265                 stateData[8+6] = static_cast<TUint8>(
       
   266                                     (iStateItemLength >> 8) & 0xff);
       
   267                 stateData[8+7] = static_cast<TUint8>(
       
   268                                     iStateItemLength & 0xff);
       
   269                 }
       
   270             else
       
   271                 {
       
   272                 Mem::FillZ(&stateData[8], KMinPartialStateLength + 2);
       
   273                 }
       
   274             stateData[8+8] = static_cast<TUint8>(aReturnedParameters);
       
   275             stateData[8+9] = static_cast<TUint8>(KSigCompVersion);
       
   276             stateData[8+10] = static_cast<TUint8>(0);
       
   277 
       
   278             sha1->Hash(TPtrC8(stateData, 8+11));
       
   279             break;
       
   280             }
       
   281 
       
   282         case EStaticUploadBytecode:
       
   283             {
       
   284             // hash from feedback
       
   285             break;
       
   286             }
       
   287 
       
   288         case EDynamicBytecode:
       
   289             {
       
   290 /*
       
   291 :state_area_start
       
   292 :returned_parameters_location   pad (1)
       
   293 :returned_sigcomp_version       pad (1)
       
   294 :returned_parameters_zero       pad (1)
       
   295 */
       
   296             stateData[8+0] = static_cast<TUint8>(aReturnedParameters);
       
   297             stateData[8+1] = static_cast<TUint8>(KSigCompVersion);
       
   298             stateData[8+2] = static_cast<TUint8>(0);
       
   299 
       
   300             sha1->Hash(TPtrC8(stateData, 8+3));
       
   301             break;
       
   302             }
       
   303             
       
   304         case EDynamicUploadBytecode:
       
   305             {
       
   306             // hash from feedback
       
   307             break;
       
   308             }
       
   309         }
       
   310 
       
   311     TPtrC8 hash = sha1->Hash(TPtrC8(KDeflateBytecodes[aBytecode].iBytecode,
       
   312                                KDeflateBytecodes[aBytecode].iBytecodeSize));
       
   313 
       
   314     TInt toZero = KDeflateBytecodes[aBytecode].iStateSize -
       
   315                   KDeflateBytecodes[aBytecode].iBytecodeInit +
       
   316                   KDeflateBytecodes[aBytecode].iStateStart -
       
   317                   KDeflateBytecodes[aBytecode].iBytecodeSize;
       
   318     TInt i;
       
   319     for(i=0; i<toZero; i++)
       
   320         {
       
   321 // Not covered because current bytecodes not need that
       
   322 // I left the code there, as it may be usefull for other bytecodes.
       
   323         hash.Set(sha1->Hash(KZero));
       
   324         }
       
   325 
       
   326     aDeflateContext->SetBytecodeHash(hash.Ptr());
       
   327 
       
   328     CleanupStack::PopAndDestroy(sha1);
       
   329     }
       
   330 
       
   331 
       
   332 // ----------------------------------------------------------------------------
       
   333 
       
   334 TInt CDeflateComp::EncodeCyclesPerBit(
       
   335                                    CSigComp::TCyclesPerBit aCyclesPerBit) const
       
   336     {
       
   337     TInt result = 0;
       
   338     TUint value = aCyclesPerBit >> 5;
       
   339 
       
   340     while (value)
       
   341         {
       
   342         result++;
       
   343         value >>= 1;
       
   344         }
       
   345 
       
   346     return result;
       
   347     }
       
   348 
       
   349 
       
   350 // ----------------------------------------------------------------------------
       
   351 
       
   352 TInt CDeflateComp::EncodeMemorySize(CSigComp::TMemorySize aMemorySize) const
       
   353     {
       
   354     TInt result = 0;
       
   355     TUint value = aMemorySize >> 11;
       
   356 
       
   357     while (value)
       
   358         {
       
   359         result++;
       
   360         value >>= 1;
       
   361         }
       
   362 
       
   363     return result;
       
   364     }
       
   365 
       
   366 
       
   367 // ----------------------------------------------------------------------------
       
   368 
       
   369 CSigComp::TMemorySize CDeflateComp::DecodeMemorySize(TInt aMemorySize)
       
   370     {
       
   371 
       
   372     TInt result = aMemorySize ? 1 << (10+aMemorySize) : 0;
       
   373 
       
   374     return static_cast<CSigComp::TMemorySize>(result);
       
   375     }
       
   376 
       
   377 
       
   378 // ----------------------------------------------------------------------------
       
   379 
       
   380 TUint8 CDeflateComp::EncodeReturnedParameters(
       
   381                                MSigCompCompartmentContext* aCompartmentContext)
       
   382     {
       
   383     return static_cast<TUint8>(
       
   384         (EncodeCyclesPerBit(aCompartmentContext->CyclesPerBit()) <<
       
   385             KReturnedParametersCPBShift) |
       
   386         (EncodeMemorySize(aCompartmentContext->DecompressionMemorySize()) <<
       
   387             KReturnedParametersDMSShift) |
       
   388         (EncodeMemorySize(aCompartmentContext->StateMemorySize()) <<
       
   389             KReturnedParametersSMSShift));
       
   390     }
       
   391 
       
   392 
       
   393 // ----------------------------------------------------------------------------
       
   394 
       
   395 void CDeflateComp::ParseReturnedParameters(const TDesC8& aReturnedParameters,
       
   396                                        CSigCompDeflateContext* aDeflateContext)
       
   397     {
       
   398 
       
   399     if (aReturnedParameters.Length())
       
   400         {
       
   401         const TUint8* retpdata = aReturnedParameters.Ptr();
       
   402         TUint8 rp = *retpdata;
       
   403 
       
   404         aDeflateContext->SetDms(
       
   405             DecodeMemorySize((rp >> KReturnedParametersDMSShift) &
       
   406                 KReturnedParametersDMSMask));
       
   407         aDeflateContext->SetSms(
       
   408             DecodeMemorySize((rp >> KReturnedParametersSMSShift) &
       
   409                 KReturnedParametersSMSMask));
       
   410         }
       
   411     }
       
   412 
       
   413 
       
   414 // ----------------------------------------------------------------------------
       
   415 
       
   416 void CDeflateComp::AppendDataHeaderL(CMessageWriter* aWriter,
       
   417                                      TDeflateCompBytecodeId aBytecode,
       
   418                                      TUint8 aReturnedParameters,
       
   419                                      TInt aUdvmSize,
       
   420                                      TBool aFirstMessage,
       
   421                                      CSigCompDeflateContext* aDeflateContext)
       
   422     {
       
   423 
       
   424     switch (aBytecode)
       
   425         {
       
   426         case EStaticBytecode:
       
   427             {
       
   428 /*
       
   429     dictionary_id:                6 bytes (1st message only)
       
   430     dictionary_phrases_size:      2 bytes (1st message only)
       
   431     returned_parameters_location: 1 byte  (1st message only)
       
   432     returned_sigcomp_version:     1 byte  (1st message only)
       
   433     udvm_memory_size:             2 bytes
       
   434 */
       
   435             if (aFirstMessage)
       
   436                 {
       
   437                 if (iStateItem)
       
   438                     {
       
   439                     AppendDataL(aWriter,
       
   440                                 TPtrC8(iStateItem->iStateIdentifier,
       
   441                                        KMinPartialStateLength));
       
   442                     AppendDataL(aWriter,
       
   443                                 static_cast<TUint16>(iStateItemLength));
       
   444                     }
       
   445                 else
       
   446                     {
       
   447                     AppendDataL(aWriter, KEightZeros);
       
   448                     }
       
   449 
       
   450                 AppendDataL(aWriter, aReturnedParameters);
       
   451                 AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
       
   452                 }
       
   453 
       
   454             AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
       
   455 
       
   456             break;
       
   457             }
       
   458 
       
   459         case EStaticUploadBytecode:
       
   460             {
       
   461 /*
       
   462     udvm_memory_size:             2 bytes
       
   463     state_length                  2 bytes (1st message only)
       
   464     state value                   state_length bytes (1st message only)
       
   465     returned_parameters_location: 1 byte  (1st message only)
       
   466     returned_sigcomp_version:     1 byte  (1st message only)
       
   467 */
       
   468             AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
       
   469 
       
   470             if (aFirstMessage)
       
   471                 {
       
   472                 AppendDataL(aWriter, static_cast<TUint16>(iStateItemLength));
       
   473                 AppendDataL(aWriter, TPtrC8(iStateItem->iStateValue,
       
   474                                             iStateItemLength));
       
   475                 AppendDataL(aWriter, aReturnedParameters);
       
   476                 AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
       
   477                 }
       
   478 
       
   479             break;
       
   480             }
       
   481 
       
   482         case EDynamicBytecode:
       
   483             {
       
   484 /*
       
   485     returned_parameters_location: 1 byte  (1st message only)
       
   486     returned_sigcomp_version:     1 byte  (1st message only)
       
   487     udvm_memory_size:             2 bytes
       
   488     dictionary_phrases_size:      2 bytes
       
   489     dictionary_id:                6 bytes (if dictionary_phrases_size!=0)
       
   490     cbstate_size:                 2 bytes
       
   491     cbstate_id:                   6 bytes (if cbstate_size!=0)
       
   492 */
       
   493             if (aFirstMessage)
       
   494                 {
       
   495                 AppendDataL(aWriter, aReturnedParameters);
       
   496                 AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
       
   497                 }
       
   498 
       
   499             AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
       
   500 
       
   501             if (aDeflateContext->CBStateConfirmed())
       
   502                 {
       
   503                 AppendDataL(aWriter, static_cast<TUint16>(0));
       
   504                 AppendDataL(aWriter, static_cast<TUint16>(
       
   505                                 aDeflateContext->CBStateLength()));
       
   506                 AppendDataL(aWriter, TPtrC8(aDeflateContext->CBStateHash(),
       
   507                                             KMinPartialStateLength));
       
   508                 }
       
   509             else
       
   510                 {
       
   511                 if (iStateItem)
       
   512                     {
       
   513                     AppendDataL(aWriter, static_cast<TUint16>(
       
   514                                                 iStateItemLength));
       
   515                     AppendDataL(aWriter, TPtrC8(iStateItem->iStateIdentifier,
       
   516                                                 KMinPartialStateLength));
       
   517                     AppendDataL(aWriter, static_cast<TUint16>(0));
       
   518                     }
       
   519                 else
       
   520                     {
       
   521                     AppendDataL(aWriter, static_cast<TUint16>(0));
       
   522                     AppendDataL(aWriter, static_cast<TUint16>(0));
       
   523                     }
       
   524                 }
       
   525             break;
       
   526             }
       
   527 
       
   528         case EDynamicUploadBytecode:
       
   529             {
       
   530 /*
       
   531     udvm_memory_size:             2 bytes
       
   532     state_length                  2 bytes (1st message only)
       
   533     state value                   state_length bytes (1st message only)
       
   534     returned_parameters_location: 1 byte  (1st message only)
       
   535     returned_sigcomp_version:     1 byte  (1st message only)
       
   536     cbstate_size:                 2 bytes (nth message only)
       
   537     cbstate_id:                   6 bytes (if cbstate_size!=0)
       
   538 */
       
   539             AppendDataL(aWriter, static_cast<TUint16>(aUdvmSize));
       
   540 
       
   541             if (aFirstMessage)
       
   542                 {
       
   543                 AppendDataL(aWriter, static_cast<TUint16>(iStateItemLength));
       
   544                 AppendDataL(aWriter, TPtrC8(iStateItem->iStateValue,
       
   545                                             iStateItemLength));
       
   546                 AppendDataL(aWriter, aReturnedParameters);
       
   547                 AppendDataL(aWriter, static_cast<TUint8>(KSigCompVersion));
       
   548                 }
       
   549             else
       
   550                 {
       
   551                 if (aDeflateContext->CBStateConfirmed())
       
   552                     {
       
   553                     AppendDataL(aWriter, static_cast<TUint16>(
       
   554                                     aDeflateContext->CBStateLength()));
       
   555                     AppendDataL(aWriter, TPtrC8(aDeflateContext->CBStateHash(),
       
   556                                                 KMinPartialStateLength));
       
   557                     }
       
   558                 else
       
   559                     {
       
   560                     AppendDataL(aWriter, static_cast<TUint16>(0));
       
   561                     }
       
   562                 }
       
   563 
       
   564             break;
       
   565             }
       
   566         }
       
   567     }
       
   568 
       
   569     
       
   570 // ----------------------------------------------------------------------------
       
   571 
       
   572 TInt CDeflateComp::CalcCBSizeL(TInt& aUdvmSize,
       
   573                                 TDeflateCompBytecodeId aBytecode,
       
   574                                 CSigCompDeflateContext* aDeflateContext)
       
   575     {
       
   576 
       
   577     TInt cbSize = aUdvmSize - KDeflateBytecodes[aBytecode].iCBufStart;
       
   578 
       
   579     // no memory for bytecode and circular buffer
       
   580     if (cbSize < 0)
       
   581         return cbSize;
       
   582 
       
   583     switch (aBytecode)
       
   584         {
       
   585         case EStaticBytecode:
       
   586             {
       
   587             break;
       
   588             }
       
   589 
       
   590         case EStaticUploadBytecode:
       
   591             {
       
   592             break;
       
   593             }
       
   594 
       
   595         case EDynamicBytecode:
       
   596             {
       
   597             TInt availSms = aDeflateContext->Sms() -
       
   598                             KDeflateBytecodes[aBytecode].iStateSize -
       
   599                             KStateCostExtension;
       
   600 
       
   601             if (availSms <= 0)
       
   602                 {
       
   603                 return cbSize;
       
   604                 }
       
   605 
       
   606             if ((cbSize+2+KStateCostExtension) > availSms)
       
   607                 {
       
   608                 cbSize = availSms - 2 - KStateCostExtension;
       
   609                 aUdvmSize = cbSize + KDeflateBytecodes[aBytecode].iCBufStart;
       
   610                 }
       
   611 
       
   612             break;
       
   613             }
       
   614             
       
   615         case EDynamicUploadBytecode:
       
   616             {
       
   617             TInt availSms = aDeflateContext->Sms() -
       
   618                             KDeflateBytecodes[aBytecode].iStateSize -
       
   619                             KStateCostExtension -
       
   620                             iStateItemLength -
       
   621                             KStateCostExtension;
       
   622 
       
   623             if (availSms <= 0)
       
   624                 {
       
   625                 return cbSize;
       
   626                 }
       
   627 
       
   628             if ((cbSize+2+KStateCostExtension) > availSms)
       
   629                 {
       
   630                 cbSize = availSms - 2 - KStateCostExtension;
       
   631                 aUdvmSize = cbSize + KDeflateBytecodes[aBytecode].iCBufStart;
       
   632                 }
       
   633 
       
   634             break;
       
   635             }
       
   636         }
       
   637 
       
   638     return cbSize;
       
   639     }
       
   640 
       
   641 // ----------------------------------------------------------------------------
       
   642 
       
   643 CSigCompDeflateContext* CDeflateComp::DeflateContextL(
       
   644                                MSigCompCompartmentContext* aCompartmentContext)
       
   645     {
       
   646     CSigCompCompressionContext* tmpContext = 
       
   647                                    const_cast<CSigCompCompressionContext*>
       
   648                                    (aCompartmentContext->CompressionContext());
       
   649 
       
   650     CSigCompDeflateContext* deflateContext =
       
   651                                            static_cast<CSigCompDeflateContext*>
       
   652                                            (tmpContext);
       
   653 
       
   654     if (deflateContext == NULL)
       
   655         {
       
   656         deflateContext = new (ELeave)CSigCompDeflateContext();
       
   657         aCompartmentContext->SetCompressionContext(
       
   658                              static_cast<CSigCompCompressionContext*>
       
   659                              (deflateContext));
       
   660         deflateContext->SetUploadState(iUploadState);
       
   661         deflateContext->SetStateItem(iStateItem, iStateItemLength);
       
   662         }
       
   663     else
       
   664         {
       
   665         iUploadState = deflateContext->UploadState();
       
   666         iStateItem = deflateContext->StateItem();
       
   667         iStateItemLength = deflateContext->StateItemLength();
       
   668         }
       
   669 
       
   670     return deflateContext;
       
   671     }
       
   672 
       
   673 
       
   674 // ----------------------------------------------------------------------------
       
   675 
       
   676 CBufBase* CDeflateComp::CompressMessageL(
       
   677                               MSigCompCompartmentContext* aCompartmentContext,
       
   678                               const TDesC8& aMessage,
       
   679                               TBool aForStreamBasedProtocol)
       
   680     {
       
   681 
       
   682     if (aMessage.Length() == 0)
       
   683         {
       
   684         User::Leave(CSigComp::ECompressionFailure);
       
   685         }
       
   686 
       
   687     TBool dynamic = aCompartmentContext->IsDynamicCompression();
       
   688 
       
   689     CSigCompDeflateContext* deflateContext =
       
   690                                       DeflateContextL(aCompartmentContext);
       
   691 
       
   692     ParseReturnedParameters(aCompartmentContext->ReturnedParameters(),
       
   693                             deflateContext);
       
   694 
       
   695     // select bytecode
       
   696     TDeflateCompBytecodeId bytecode;
       
   697 
       
   698     if (iUploadState)
       
   699         {
       
   700         if (dynamic)
       
   701             bytecode = EDynamicUploadBytecode;
       
   702         else
       
   703             bytecode = EStaticUploadBytecode;
       
   704         }
       
   705     else
       
   706         {
       
   707         if (dynamic)
       
   708             bytecode = EDynamicBytecode;
       
   709         else
       
   710             bytecode = EStaticBytecode;
       
   711         }
       
   712 
       
   713     CBufFlat* outputBuffer = CBufFlat::NewL(32);
       
   714     CleanupStack::PushL(outputBuffer);
       
   715     outputBuffer->SetReserveL(32);
       
   716 
       
   717     CMessageWriter* messageWriter = new (ELeave)CMessageWriter(outputBuffer,
       
   718                                                       aForStreamBasedProtocol);
       
   719     CleanupStack::PushL(messageWriter);
       
   720 
       
   721     TInt msgPos = 0;
       
   722     while (msgPos < aMessage.Size())
       
   723         {
       
   724         TInt msgSize = aMessage.Size() - msgPos;
       
   725 
       
   726         if (aForStreamBasedProtocol)
       
   727             {
       
   728             if (msgSize > KMaxOutputSize)
       
   729                 {
       
   730                 msgSize = KMaxOutputSize;
       
   731                 }
       
   732             }
       
   733         else
       
   734             {
       
   735             if (msgSize > KMaxOutputSize)
       
   736                 {
       
   737                 User::Leave(CSigComp::ECompressionFailure);
       
   738                 }
       
   739             }
       
   740 
       
   741         TPtrC8 message(aMessage.Mid(msgPos, msgSize));
       
   742 
       
   743         const TDesC8& requestedFeedback =
       
   744                             aCompartmentContext->RequestedFeedback();
       
   745         const TDesC8& returnedFeedback =
       
   746                             aCompartmentContext->ReturnedFeedback();
       
   747 
       
   748         CDeflate* deflateComp = CDeflate::NewL(dynamic, deflateContext);
       
   749         CleanupStack::PushL(deflateComp);
       
   750 
       
   751         TUint8 returnedParameters =
       
   752                             EncodeReturnedParameters(aCompartmentContext);
       
   753 
       
   754         if (!deflateContext->BytecodeStateConfirmed())
       
   755             {
       
   756             if (returnedFeedback.Length())
       
   757                 {
       
   758                 if(deflateContext->UploadState())
       
   759                     {
       
   760                     deflateContext->SetBytecodeHash(returnedFeedback.Ptr() +
       
   761                                                     dynamic*8);
       
   762                     deflateContext->SetBytecodeStateConfirmed(ETrue);
       
   763                     }
       
   764                 else
       
   765                     {
       
   766                     CalculateBytecodeHashL(deflateContext, bytecode,
       
   767                                            returnedParameters);
       
   768                     deflateContext->SetBytecodeStateConfirmed(ETrue);
       
   769                     }
       
   770                 }
       
   771             }
       
   772 
       
   773         if (dynamic)
       
   774             {
       
   775             if (returnedFeedback.Length())
       
   776                 {
       
   777                 deflateContext->SetCBStateHash(returnedFeedback.Ptr());
       
   778                 TInt cbLen = (returnedFeedback.Ptr()[6]<<8) +
       
   779                              returnedFeedback.Ptr()[7];
       
   780                 deflateContext->SetCBStateLength(cbLen);
       
   781                 deflateContext->SetCBStateConfirmed(ETrue);
       
   782                 }
       
   783             else
       
   784                 {
       
   785                 deflateContext->SetCBStateConfirmed(EFalse);
       
   786                 deflateComp->Reset();
       
   787                 }
       
   788             }
       
   789 
       
   790         TUint8 header = KMessageCommonHeader;
       
   791 
       
   792         if (requestedFeedback.Length())
       
   793             {
       
   794             header |= KMessageHeaderTBit;
       
   795             }
       
   796 
       
   797         if(!deflateContext->BytecodeStateConfirmed())
       
   798             {
       
   799             AppendDataL(messageWriter, header);
       
   800             AppendRequestedFeedbackL(messageWriter, requestedFeedback);
       
   801 
       
   802             TUint16 lendest = static_cast<TUint16>(
       
   803                                 (KDeflateBytecodes[bytecode].iBytecodeSize <<
       
   804                                     KBytecodeLengthShift) |
       
   805                                 ((KDeflateBytecodes[bytecode].iBytecodeInit >>
       
   806                                     KBytecodeDestinationShift) - 1));
       
   807 
       
   808             AppendDataL(messageWriter, lendest);
       
   809             AppendDataL(messageWriter,
       
   810                         TPtrC8(KDeflateBytecodes[bytecode].iBytecode,
       
   811                                KDeflateBytecodes[bytecode].iBytecodeSize));
       
   812             }
       
   813         else
       
   814             {
       
   815             header |= KMessageHeaderLen;
       
   816             AppendDataL(messageWriter, header);
       
   817             AppendRequestedFeedbackL(messageWriter, requestedFeedback);
       
   818 
       
   819             AppendDataL(messageWriter,
       
   820                         TPtrC8(deflateContext->BytecodeHash(),
       
   821                                KMinPartialStateLength));
       
   822             }
       
   823 
       
   824         // calculate available memory on remote side
       
   825         TInt udvmSize = -1;
       
   826         TInt cbSize = -1;
       
   827         if (deflateContext->BytecodeStateConfirmed())
       
   828             {
       
   829             udvmSize = deflateContext->UdvmSize();
       
   830             cbSize = deflateContext->CBSize();
       
   831             }
       
   832         else
       
   833             {
       
   834             TInt dms = deflateContext->Dms();
       
   835             for (; (udvmSize < 0) || (cbSize < KMinCBSize); dms<<=1)
       
   836                 {
       
   837                 if (aForStreamBasedProtocol)
       
   838                     {
       
   839                     udvmSize = dms / 2;
       
   840                     }
       
   841                 else
       
   842                     {
       
   843                     // simulate compressed message size
       
   844                     TInt msgSize = outputBuffer->Size() + 2 +
       
   845                                    message.Length() + 50;
       
   846                     if(iUploadState &&
       
   847                        !deflateContext->BytecodeStateConfirmed())
       
   848                         msgSize += iStateItemLength;
       
   849 
       
   850                     udvmSize = dms - msgSize;
       
   851                     }
       
   852 
       
   853                 if (udvmSize > 0)
       
   854                     {
       
   855                     if (udvmSize > static_cast<TInt>(KMaxUdvmMemorySize))
       
   856                         {
       
   857                         udvmSize = KMaxUdvmMemorySize;
       
   858                         }
       
   859 
       
   860                     cbSize = CalcCBSizeL(udvmSize, bytecode, deflateContext);
       
   861                     }
       
   862                 }
       
   863                 deflateContext->SetUdvmSize(udvmSize);
       
   864                 deflateContext->SetCBSize(cbSize);
       
   865             }
       
   866 
       
   867         AppendDataHeaderL(messageWriter,
       
   868                           bytecode, returnedParameters, udvmSize,
       
   869                           !deflateContext->BytecodeStateConfirmed(),
       
   870                           deflateContext);
       
   871 
       
   872         //configure deflate compressor
       
   873         deflateComp->ChangeWindowSizeL(cbSize);
       
   874 
       
   875         if ((!dynamic) || (!deflateContext->CBStateConfirmed()))
       
   876             {
       
   877             SetDictionary(deflateContext->StateItem(),
       
   878                           deflateComp,
       
   879                           deflateContext);
       
   880             }
       
   881 
       
   882         //compress actual data
       
   883         deflateComp->CompressL(message, messageWriter);
       
   884         CleanupStack::PopAndDestroy(deflateComp);
       
   885 
       
   886         messageWriter->FlushAndTerminateL();
       
   887 
       
   888         // clean feedbacks
       
   889         aCompartmentContext->SetRequestedFeedbackL(KNullDesC8);
       
   890         aCompartmentContext->SetReturnedFeedbackL(KNullDesC8);
       
   891 
       
   892         msgPos += msgSize;
       
   893         }
       
   894     outputBuffer->Compress();
       
   895     CleanupStack::PopAndDestroy(messageWriter);
       
   896     CleanupStack::Pop(outputBuffer);
       
   897 
       
   898     return outputBuffer;
       
   899     }
       
   900 
       
   901 TBool CDeflateComp::IsDynamicCompressionSupported()
       
   902     {
       
   903     return ETrue;
       
   904     }