From be3b47d0d504a3409ce66bd77bb8c0acff87c4f5 Mon Sep 17 00:00:00 2001 From: kh1 Date: Thu, 15 Mar 2012 14:53:47 +0100 Subject: Reorganize the tree, have better ifw.pri. Shadow build support. Change-Id: I01fb12537f863ed0744979973c7e4153889cc5cb Reviewed-by: Tim Jenssen --- .../7zip/unix/CPP/7zip/Compress/ZlibDecoder.cpp | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/libs/7zip/unix/CPP/7zip/Compress/ZlibDecoder.cpp (limited to 'src/libs/7zip/unix/CPP/7zip/Compress/ZlibDecoder.cpp') diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/ZlibDecoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/ZlibDecoder.cpp new file mode 100644 index 000000000..90d6715db --- /dev/null +++ b/src/libs/7zip/unix/CPP/7zip/Compress/ZlibDecoder.cpp @@ -0,0 +1,89 @@ +// ZlibDecoder.cpp + +#include "StdAfx.h" + +#include "../Common/StreamUtils.h" + +#include "ZlibDecoder.h" + +namespace NCompress { +namespace NZlib { + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } catch(...) { return S_FALSE; } + +#define ADLER_MOD 65521 +#define ADLER_LOOP_MAX 5550 + +UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size) +{ + UInt32 a = adler & 0xFFFF; + UInt32 b = (adler >> 16) & 0xFFFF; + while (size > 0) + { + unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size; + unsigned i; + for (i = 0; i < curSize; i++) + { + a += buf[i]; + b += a; + } + buf += curSize; + size -= curSize; + a %= ADLER_MOD; + b %= ADLER_MOD; + } + return (b << 16) + a; +} + +STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + HRESULT result = _stream->Write(data, size, &size); + _adler = Adler32_Update(_adler, (const Byte *)data, size); + if (processedSize != NULL) + *processedSize = size; + return result; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + DEFLATE_TRY_BEGIN + if (!AdlerStream) + AdlerStream = AdlerSpec = new COutStreamWithAdler; + if (!DeflateDecoder) + { + DeflateDecoderSpec = new NDeflate::NDecoder::CCOMCoder; + DeflateDecoderSpec->ZlibMode = true; + DeflateDecoder = DeflateDecoderSpec; + } + + Byte buf[2]; + RINOK(ReadStream_FALSE(inStream, buf, 2)); + int method = buf[0] & 0xF; + if (method != 8) + return S_FALSE; + // int dicSize = buf[0] >> 4; + if ((((UInt32)buf[0] << 8) + buf[1]) % 31 != 0) + return S_FALSE; + if ((buf[1] & 0x20) != 0) // dictPresent + return S_FALSE; + // int level = (buf[1] >> 6); + + AdlerSpec->SetStream(outStream); + AdlerSpec->Init(); + HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress); + AdlerSpec->ReleaseStream(); + + if (res == S_OK) + { + const Byte *p = DeflateDecoderSpec->ZlibFooter; + UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3]; + if (adler != AdlerSpec->GetAdler()) + return S_FALSE; + } + return res; + DEFLATE_TRY_END +} + +}} -- cgit v1.2.3