diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SigComp/CompDeflate/src/Deflate.cpp --- /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 +#include + +#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* 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* window = new (ELeave)CArrayFixFlat(8); + iDeflateContext->SetWindow(window); + iDeflateContext->Window()->ResizeL(iDeflateContext->WindowSize() * 2); + + delete iChainNodes; + iChainNodes = NULL; + iChainNodes = new (ELeave)CArrayFixFlat(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(iBitBuffer & 0xff)); + iBitBuffer >>= 8; + iBitsQueued -= 8; + } + } + +void CDeflate::FlushBitsL() + { + if (iBitsQueued > 0) + { + PutByteL(static_cast(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((t > iDeflateContext->WindowSize()) ? + (t - iDeflateContext->WindowSize()) : 0); + (*iHashTable)[i] = t; + } + + for (i=0; iWindowSize(); i++) + { + TInt16 t = (*iChainNodes)[i]; + t = static_cast((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(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(8); + iHashTable->ResizeL(iHashSize); + + if (iDeflateContext->Window() != NULL) + { + iChainNodes = new (ELeave)CArrayFixFlat(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() + { + }