summaryrefslogtreecommitdiffstats
path: root/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Compress/PpmdDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Compress/PpmdDecoder.cpp')
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Compress/PpmdDecoder.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Compress/PpmdDecoder.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Compress/PpmdDecoder.cpp
new file mode 100644
index 000000000..0ac98c8b1
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Compress/PpmdDecoder.cpp
@@ -0,0 +1,183 @@
+// PpmdDecoder.cpp
+// 2009-05-30 : Igor Pavlov : Public domain
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Windows/Defs.h"
+
+#include "PpmdDecoder.h"
+
+namespace NCompress {
+namespace NPpmd {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ _order = properties[0];
+ _usedMemorySize = 0;
+ for (int i = 0; i < 4; i++)
+ _usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8);
+
+ if (_usedMemorySize > kMaxMemBlockSize)
+ return E_NOTIMPL;
+
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
+ return E_OUTOFMEMORY;
+
+ return S_OK;
+}
+
+class CDecoderFlusher
+{
+ CDecoder *_coder;
+public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _coder->Flush();
+ _coder->ReleaseStreams();
+ }
+};
+
+HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream)
+{
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _processedSize;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ const UInt32 startSize = size;
+
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _rangeDecoder.Init();
+ _remainLen = 0;
+ _info.MaxOrder = 0;
+ _info.StartModelRare(_order);
+ }
+ while (size != 0)
+ {
+ int symbol = _info.DecodeSymbol(&_rangeDecoder);
+ if (symbol < 0)
+ {
+ _remainLen = kLenIdFinished;
+ break;
+ }
+ if (memStream != 0)
+ *memStream++ = (Byte)symbol;
+ else
+ _outStream.WriteByte((Byte)symbol);
+ size--;
+ }
+ _processedSize += startSize - size;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ if (!_outStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+
+ SetInStream(inStream);
+ _outStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ for (;;)
+ {
+ _processedSize = _outStream.GetProcessedSize();
+ UInt32 curSize = (1 << 18);
+ RINOK(CodeSpec(curSize, NULL));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
+ {
+ UInt64 inSize = _rangeDecoder.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &_processedSize));
+ }
+ if (_outSizeDefined)
+ if (_outStream.GetProcessedSize() >= _outSize)
+ break;
+ }
+ flusher.NeedFlush = false;
+ return Flush();
+}
+
+#ifdef _NO_EXCEPTIONS
+
+#define PPMD_TRY_BEGIN
+#define PPMD_TRY_END
+
+#else
+
+#define PPMD_TRY_BEGIN try {
+#define PPMD_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const COutBufferException &e) { return e.ErrorCode; } \
+ catch(...) { return S_FALSE; }
+
+#endif
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ PPMD_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ PPMD_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ _rangeDecoder.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ _rangeDecoder.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ _outSizeDefined = (outSize != NULL);
+ if (_outSizeDefined)
+ _outSize = *outSize;
+ _processedSize = 0;
+ _remainLen = kLenIdNeedInit;
+ _outStream.Init();
+ return S_OK;
+}
+
+#ifndef NO_READ_FROM_CODER
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ PPMD_TRY_BEGIN
+ if (processedSize)
+ *processedSize = 0;
+ const UInt64 startPos = _processedSize;
+ RINOK(CodeSpec(size, (Byte *)data));
+ if (processedSize)
+ *processedSize = (UInt32)(_processedSize - startPos);
+ return Flush();
+ PPMD_TRY_END
+}
+
+#endif
+
+}}