realtimenetprots/sipfw/SigComp/CompDeflate/src/Deflate.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SigComp/CompDeflate/src/Deflate.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,611 @@
+// 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        : CDeflate.cpp
+// Part of     : deflatecomp
+// deflate compressor.
+// Version     : 1.0
+//
+
+
+
+#include <e32base.h>
+#include <badesca.h>
+
+#include "Deflate.h"
+#include "SigCompDeflateContext.h"
+#include "MessageWriter.h"
+
+/** deflate stream header. btyppe == 01, last block bit set */
+static const TInt KDeflateStreamHeaderBits = ((1<<1) + 1);
+
+/** number of bits in deflate stream header */
+static const TInt KDeflateStreamHeaderBitsLength = 3;
+
+
+/*
+* Following table is used for length/offset encoding.
+* as defined in RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const TInt16 KLengthCode[] =
+    {
+    257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267,
+    268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271,
+    272, 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274,
+    274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275,
+    276, 276, 276, 276, 276, 276, 276, 276, 277, 277, 277, 277, 277, 277,
+    277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278,
+    278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 279, 279,
+    279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+    280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
+    280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
+    281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
+    281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282, 282, 282, 282,
+    282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
+    282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283, 283,
+    283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+    283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+    284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+    284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+    284, 284, 284, 285
+    };
+
+/*
+* Following table is used for length/offset encoding.
+* as defined in RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const TUint8 KDistanceCode[] =
+    {
+    0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,
+    8,  8, 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15,  0,  0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21,
+    21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25,
+    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26,
+    26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+    26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+    27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29,
+    29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+    29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+    29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+    29, 29, 29, 29, 29, 29, 29, 29
+    }; 
+
+/*
+* Following table is used for length/offset encoding.
+* as defined in RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const TUint8 KLengthExtraBits[] = 
+    {
+    0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0
+    };
+
+/*
+* Following table is used for length/offset encoding.
+* as defined in RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const TUint8 KDistanceExtraBits[] = 
+    {
+    0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13
+    };
+
+/*
+* Following table is used for length/offset encoding.
+* as defined in RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const TUint16 KLengthBases[] =
+    {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+    64, 80, 96, 112, 128, 160, 192, 224, 0
+    };
+
+/*
+* Following table is used for length/offset encoding.
+* as defined in RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const TUint16 KDistanceBases[] =
+    {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+    32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+    1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+    };
+
+/**
+* huffman tree table. Literal tree is used for encoding both literals
+* and offset/length pairs.
+* Tables comes from RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const CDeflate::TTreeNode KLiteralTree[] = 
+    {
+    { 12,  8}, {140,  8}, { 76,  8}, {204,  8}, { 44,  8},
+    {172,  8}, {108,  8}, {236,  8}, { 28,  8}, {156,  8},
+    { 92,  8}, {220,  8}, { 60,  8}, {188,  8}, {124,  8},
+    {252,  8}, {  2,  8}, {130,  8}, { 66,  8}, {194,  8},
+    { 34,  8}, {162,  8}, { 98,  8}, {226,  8}, { 18,  8},
+    {146,  8}, { 82,  8}, {210,  8}, { 50,  8}, {178,  8},
+    {114,  8}, {242,  8}, { 10,  8}, {138,  8}, { 74,  8},
+    {202,  8}, { 42,  8}, {170,  8}, {106,  8}, {234,  8},
+    { 26,  8}, {154,  8}, { 90,  8}, {218,  8}, { 58,  8},
+    {186,  8}, {122,  8}, {250,  8}, {  6,  8}, {134,  8},
+    { 70,  8}, {198,  8}, { 38,  8}, {166,  8}, {102,  8},
+    {230,  8}, { 22,  8}, {150,  8}, { 86,  8}, {214,  8},
+    { 54,  8}, {182,  8}, {118,  8}, {246,  8}, { 14,  8},
+    {142,  8}, { 78,  8}, {206,  8}, { 46,  8}, {174,  8},
+    {110,  8}, {238,  8}, { 30,  8}, {158,  8}, { 94,  8},
+    {222,  8}, { 62,  8}, {190,  8}, {126,  8}, {254,  8},
+    {  1,  8}, {129,  8}, { 65,  8}, {193,  8}, { 33,  8},
+    {161,  8}, { 97,  8}, {225,  8}, { 17,  8}, {145,  8},
+    { 81,  8}, {209,  8}, { 49,  8}, {177,  8}, {113,  8},
+    {241,  8}, {  9,  8}, {137,  8}, { 73,  8}, {201,  8},
+    { 41,  8}, {169,  8}, {105,  8}, {233,  8}, { 25,  8},
+    {153,  8}, { 89,  8}, {217,  8}, { 57,  8}, {185,  8},
+    {121,  8}, {249,  8}, {  5,  8}, {133,  8}, { 69,  8},
+    {197,  8}, { 37,  8}, {165,  8}, {101,  8}, {229,  8},
+    { 21,  8}, {149,  8}, { 85,  8}, {213,  8}, { 53,  8},
+    {181,  8}, {117,  8}, {245,  8}, { 13,  8}, {141,  8},
+    { 77,  8}, {205,  8}, { 45,  8}, {173,  8}, {109,  8},
+    {237,  8}, { 29,  8}, {157,  8}, { 93,  8}, {221,  8},
+    { 61,  8}, {189,  8}, {125,  8}, {253,  8}, { 19,  9},
+    {275,  9}, {147,  9}, {403,  9}, { 83,  9}, {339,  9},
+    {211,  9}, {467,  9}, { 51,  9}, {307,  9}, {179,  9},
+    {435,  9}, {115,  9}, {371,  9}, {243,  9}, {499,  9},
+    { 11,  9}, {267,  9}, {139,  9}, {395,  9}, { 75,  9},
+    {331,  9}, {203,  9}, {459,  9}, { 43,  9}, {299,  9},
+    {171,  9}, {427,  9}, {107,  9}, {363,  9}, {235,  9},
+    {491,  9}, { 27,  9}, {283,  9}, {155,  9}, {411,  9},
+    { 91,  9}, {347,  9}, {219,  9}, {475,  9}, { 59,  9},
+    {315,  9}, {187,  9}, {443,  9}, {123,  9}, {379,  9},
+    {251,  9}, {507,  9}, {  7,  9}, {263,  9}, {135,  9},
+    {391,  9}, { 71,  9}, {327,  9}, {199,  9}, {455,  9},
+    { 39,  9}, {295,  9}, {167,  9}, {423,  9}, {103,  9},
+    {359,  9}, {231,  9}, {487,  9}, { 23,  9}, {279,  9},
+    {151,  9}, {407,  9}, { 87,  9}, {343,  9}, {215,  9},
+    {471,  9}, { 55,  9}, {311,  9}, {183,  9}, {439,  9},
+    {119,  9}, {375,  9}, {247,  9}, {503,  9}, { 15,  9},
+    {271,  9}, {143,  9}, {399,  9}, { 79,  9}, {335,  9},
+    {207,  9}, {463,  9}, { 47,  9}, {303,  9}, {175,  9},
+    {431,  9}, {111,  9}, {367,  9}, {239,  9}, {495,  9},
+    { 31,  9}, {287,  9}, {159,  9}, {415,  9}, { 95,  9},
+    {351,  9}, {223,  9}, {479,  9}, { 63,  9}, {319,  9},
+    {191,  9}, {447,  9}, {127,  9}, {383,  9}, {255,  9},
+    {511,  9}, {  0,  7}, { 64,  7}, { 32,  7}, { 96,  7},
+    { 16,  7}, { 80,  7}, { 48,  7}, {112,  7}, {  8,  7},
+    { 72,  7}, { 40,  7}, {104,  7}, { 24,  7}, { 88,  7},
+    { 56,  7}, {120,  7}, {  4,  7}, { 68,  7}, { 36,  7},
+    {100,  7}, { 20,  7}, { 84,  7}, { 52,  7}, {116,  7},
+    {  3,  8}, {131,  8}, { 67,  8}, {195,  8}, { 35,  8},
+    {163,  8}, { 99,  8}, {227,  8}
+    };
+
+/**
+* huffman tree table. Distance tree is used for encoding distance.
+* Tables comes from RFC 1951 (DEFLATE Compressed Data Format
+* Specification version 1.3), chapter 3.2.5.
+*/
+const CDeflate::TTreeNode KDistanceTree[] =
+    {
+    { 0, 5}, {16, 5}, { 8, 5}, {24, 5}, { 4, 5},
+    {20, 5}, {12, 5}, {28, 5}, { 2, 5}, {18, 5},
+    {10, 5}, {26, 5}, { 6, 5}, {22, 5}, {14, 5},
+    {30, 5}, { 1, 5}, {17, 5}, { 9, 5}, {25, 5},
+    { 5, 5}, {21, 5}, {13, 5}, {29, 5}, { 3, 5},
+    {19, 5}, {11, 5}, {27, 5}, { 7, 5}, {23, 5}
+    };
+
+CDeflate* CDeflate::NewL(TBool aDynamic, CSigCompDeflateContext* aContext)
+    {
+    CDeflate* self= NewLC(aDynamic, aContext);
+    CleanupStack::Pop();
+    return self;
+    }
+
+CDeflate* CDeflate::NewLC(TBool aDynamic, CSigCompDeflateContext* aContext)
+    {
+    CDeflate* self= new (ELeave) CDeflate();
+    CleanupStack::PushL(self);
+    self->ConstructL(aDynamic, aContext);
+    return self;
+    }
+
+CDeflate::~CDeflate()
+    {
+    delete iHashTable;
+    delete iChainNodes;
+    }
+
+void CDeflate::CompressL(const TDesC8& aMessage,
+                         CMessageWriter* aMessageWriter)
+    {
+    iMessageWriter = aMessageWriter;
+    CArrayFixFlat<TUint8>* window = iDeflateContext->Window();
+
+    SendBitsL(KDeflateStreamHeaderBits,
+              KDeflateStreamHeaderBitsLength);
+
+    const TUint8* msgPtr = aMessage.Ptr();
+    TInt msgSize = aMessage.Length();
+    TInt processed = 0;
+    while (processed < msgSize)
+        {
+        processed += FillWindow(msgPtr + processed, msgSize - processed);
+
+        while (iLookAhead)
+            {
+            TInt position;
+            TInt length;
+            TInt currentPosition;
+            if (FindBestMatch(position, length))
+                {
+                //lazy matching:
+                if ( length < KNiceLazyMatchLength )
+                    {
+                    currentPosition = iDeflateContext->CurrentPosition();
+                    currentPosition++;
+                    iDeflateContext->SetCurrentPosition(currentPosition);
+                    TInt lazyPosition;
+                    TInt lazyLength;
+                    if (FindBestMatch(lazyPosition, lazyLength))
+                        {
+                        if (lazyLength > length)
+                            {
+                            InsertHash(iDeflateContext->CurrentPosition() - 1);
+                            EncodeLiteralL(
+                               window->At(iDeflateContext->CurrentPosition() - 1));
+                            iLookAhead--;
+                            length = lazyLength;
+                            position = lazyPosition;
+                            }
+                        else
+                            {
+                            currentPosition = iDeflateContext->CurrentPosition();
+                            currentPosition--;
+                            iDeflateContext->SetCurrentPosition(currentPosition);
+                            }
+                        }
+                    else
+                        {
+                        currentPosition = iDeflateContext->CurrentPosition();
+                        currentPosition--;
+                        iDeflateContext->SetCurrentPosition(currentPosition);
+                        }
+                    }
+                EncodeDistanceLengthPairL(iDeflateContext->CurrentPosition() -
+                                          position, length);
+                iLookAhead -= length;
+                while (length--)
+                    {
+                    InsertHash(iDeflateContext->CurrentPosition());
+                    currentPosition = iDeflateContext->CurrentPosition();
+                    currentPosition++;
+                    iDeflateContext->SetCurrentPosition(currentPosition);
+                    }
+                }
+            else
+                {
+                InsertHash(iDeflateContext->CurrentPosition());
+                EncodeLiteralL(window->At(iDeflateContext->CurrentPosition()));
+                currentPosition = iDeflateContext->CurrentPosition();
+                currentPosition++;
+                iDeflateContext->SetCurrentPosition(currentPosition);
+                iLookAhead--;
+                }
+            }
+        }
+
+    EncodeLiteralL(256);
+    FlushBitsL();
+    }
+
+void CDeflate::Reset(void)
+    {
+    iDeflateContext->SetCurrentPosition(0);
+    iLookAhead = 0;
+    ResetHashTable();
+    iBitBuffer = 0;
+    iBitsQueued = 0;
+    }
+
+void CDeflate::ResetHashTable(void)
+    {
+
+    TInt i;
+    if (iHashTable)
+        {
+        for (i = 0;i < iHashSize;i++)
+            {
+            (*iHashTable)[i] = 0;
+            }
+        }
+
+    if (iChainNodes)
+        {
+        for (i = 0;i < iDeflateContext->WindowSize();i++)
+            {
+            (*iChainNodes)[i] = 0;
+            }
+        }
+    }
+
+void CDeflate::SetDictionary(const TUint8* aPtr, TInt aSize)
+    {
+    if (aPtr)
+        {
+        ResetHashTable();
+        Mem::Copy(&iDeflateContext->Window()->At(0), aPtr, aSize);
+
+        for (TInt i = 0;i < aSize - 2;i++)
+            {
+            InsertHash(i);
+            }
+        iDeflateContext->SetCurrentPosition(aSize);
+        }
+    }
+
+void CDeflate::ChangeWindowSizeL(TInt aWindowSize)
+    {
+    if (aWindowSize != iDeflateContext->WindowSize())
+        {
+        iDeflateContext->SetWindowSize(aWindowSize);
+
+        CArrayFixFlat<TUint8>* window = new (ELeave)CArrayFixFlat<TUint8>(8);
+        iDeflateContext->SetWindow(window);
+        iDeflateContext->Window()->ResizeL(iDeflateContext->WindowSize() * 2);
+
+        delete iChainNodes;
+        iChainNodes = NULL;
+        iChainNodes = new (ELeave)CArrayFixFlat<TInt16>(8);
+        iChainNodes->ResizeL(iDeflateContext->WindowSize());
+        iChainMask = iDeflateContext->WindowSize() - 1;
+
+        ResetHashTable();
+        iDeflateContext->SetCurrentPosition(0);
+        iLookAhead = 0;
+        }
+    }
+
+void CDeflate::SendBitsL(TUint aValue, TUint aLength)
+    {
+    iBitBuffer |= aValue << iBitsQueued;
+    iBitsQueued += aLength;
+    while (iBitsQueued >= 8)
+        {
+        PutByteL(static_cast<TUint8>(iBitBuffer & 0xff));
+        iBitBuffer >>= 8;
+        iBitsQueued -= 8;
+        }
+    }
+
+void CDeflate::FlushBitsL()
+    {
+    if (iBitsQueued > 0)
+        {
+        PutByteL(static_cast<TUint8>(iBitBuffer));
+        }
+    iBitBuffer = 0;
+    iBitsQueued = 0;
+    } 
+
+void CDeflate::PutByteL(TUint8 aByte)
+    {
+    iMessageWriter->WriteByteL(aByte);
+    }
+
+void CDeflate::EncodeLiteralL(TInt aCode)
+    {
+    SendBitsL(KLiteralTree[aCode].iBits, KLiteralTree[aCode].iLength);
+    }
+
+void CDeflate::EncodeDistanceLengthPairL(TUint aDist, TUint aLength)
+    {
+    aLength -= KMinMatch;
+    aDist -= 1;
+
+    TInt code = KLengthCode[aLength];
+    EncodeLiteralL(code);
+    TUint extra = KLengthExtraBits[code - (KMaxMatch - 1)];
+    if (extra)
+        {
+        aLength -= KLengthBases[code - (KMaxMatch - 1)];
+        SendBitsL(aLength, extra);
+        }
+
+    if (aDist < KEncodeDistance)
+        {
+        code = KDistanceCode[aDist];
+        }
+    else
+        {
+        code = KDistanceCode[(aDist>>7) + KEncodeDistance];
+        }
+
+    SendBitsL(KDistanceTree[code].iBits, KDistanceTree[code].iLength);
+
+    extra = KDistanceExtraBits[code];
+    if (extra)
+        {
+        aDist -= KDistanceBases[code];
+        SendBitsL(aDist, extra);
+        } 
+    }
+
+TBool CDeflate::FindBestMatch(TInt& aMatchPos, TInt& aLength)
+    {
+    aMatchPos = 0;
+    if (iLookAhead > KMinMatch)
+        {
+        TInt position = iDeflateContext->CurrentPosition();
+        TInt16 currentPos = (*iHashTable)[CalcHash(
+                                 iDeflateContext->Window()->At(position),
+                                 iDeflateContext->Window()->At(position + 1),
+                                 iDeflateContext->Window()->At(position + 2))];
+        TInt chainLength = KMaxChainLength;
+        aLength = KMinMatch - 1;
+
+        while (currentPos && chainLength > 0)
+            {
+            TInt len = 0;
+						TUint8 *m = &iDeflateContext->Window()->At(position);
+						TUint8 *c = &iDeflateContext->Window()->At(currentPos);
+            while ((len < Min(KMaxMatch, iLookAhead)) &&
+                  ((position + len) < (2 * iDeflateContext->WindowSize())) &&
+                  (*m++ == *c++))
+                {
+                len++;
+                }
+
+            if ((len > aLength) &&
+                ((position - currentPos) < iDeflateContext->WindowSize()))
+                {
+                aMatchPos = currentPos;
+                aLength = len;
+                if ( aLength >= KGoodMatchLength )
+                    break;
+                }
+
+            if ( aLength >= KNiceMatchLength )
+                chainLength >>= 2;
+
+            currentPos = (*iChainNodes)[currentPos & iChainMask];
+            chainLength--;
+            }
+        }
+    return (aMatchPos > 0) ? ETrue : EFalse;
+    }
+
+TInt CDeflate::FillWindow(const TUint8* aPtr, TInt aBytes)
+    {
+    TInt position = iDeflateContext->CurrentPosition();
+    TInt processed = Min(aBytes, 2 * iDeflateContext->WindowSize() -
+                         (position + iLookAhead));
+
+    if (position >= (2 * iDeflateContext->WindowSize() - KMaxMatch))
+        {
+        Mem::Copy(&iDeflateContext->Window()->At(0),
+                &iDeflateContext->Window()->At(iDeflateContext->WindowSize()),
+                 iDeflateContext->WindowSize());
+        position -= iDeflateContext->WindowSize();
+        iDeflateContext->SetCurrentPosition(position);
+
+        TInt i;
+        for (i=0; i<iHashSize; i++)
+            {
+            TInt16 t = (*iHashTable)[i];
+            t = static_cast<TInt16>((t > iDeflateContext->WindowSize()) ?
+                                    (t - iDeflateContext->WindowSize()) : 0);
+            (*iHashTable)[i] = t;
+            }
+
+        for (i=0; i<iDeflateContext->WindowSize(); i++)
+            {
+            TInt16 t = (*iChainNodes)[i];
+            t = static_cast<TInt16>((t > iDeflateContext->WindowSize()) ?
+                                    (t - iDeflateContext->WindowSize()) : 0);
+            (*iChainNodes)[i] = t;
+            }
+
+        processed = Min(processed + iDeflateContext->WindowSize(), aBytes);
+        }
+
+    Mem::Copy(&iDeflateContext->Window()->At(position + iLookAhead),
+              aPtr, processed);
+    iLookAhead += processed;
+    return processed;
+    }
+
+void CDeflate::InsertHash(TInt aPosition)
+    {
+    if ((aPosition + 2) < 2 * (iDeflateContext->WindowSize()))
+        {
+        TUint hash = CalcHash(iDeflateContext->Window()->At(aPosition),
+                              iDeflateContext->Window()->At(aPosition + 1),
+                              iDeflateContext->Window()->At(aPosition + 2));
+        (*iChainNodes)[aPosition & iChainMask] = (*iHashTable)[hash];
+        (*iHashTable)[hash] = static_cast<TInt16>(aPosition);
+        }
+    }
+
+TInt CDeflate::CalcHash(TUint8 aA, TUint8 aB, TUint8 aC) const
+    {
+    return (((aA << (iHashShift2)) ^ (aB << iHashShift) ^ aC) & iHashMask);
+    }
+
+void CDeflate::ConstructL(TBool aDynamic, CSigCompDeflateContext* aContext)
+    {
+    iDynamic = aDynamic;
+    iDeflateContext = aContext;
+
+    iHashSize = 1 << KHashTableBits;
+    iHashMask = iHashSize - 1;
+    iHashShift = ((KHashTableBits + KMinMatch - 1) / KMinMatch);
+    iHashShift2 = iHashShift << 1;
+    iHashTable = new (ELeave)CArrayFixFlat<TInt16>(8);
+    iHashTable->ResizeL(iHashSize);
+
+    if (iDeflateContext->Window() != NULL)
+        {
+        iChainNodes = new (ELeave)CArrayFixFlat<TInt16>(8);
+        iChainNodes->ResizeL(iDeflateContext->WindowSize());
+        iChainMask = iDeflateContext->WindowSize() - 1;
+
+        ResetHashTable();
+        iLookAhead = 0;
+
+        if (iDynamic)
+            {
+            TInt position = aContext->CurrentPosition();
+
+            if (position > 2)
+                {
+                for (TInt i = 0;i < position - 2;i++)
+                    {
+                    InsertHash(i);
+                    }
+                }
+            }
+        else
+            {
+            iDeflateContext->SetCurrentPosition(0);
+            }
+        }
+    else
+        {
+        iDeflateContext->SetWindowSize(0);
+        }
+    }
+
+CDeflate::CDeflate()
+    {
+    }