misc/libphysfs/lzma/CPP/7zip/Common/FilterCoder.cpp
changeset 12213 bb5522e88ab2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FilterCoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,264 @@
+// FilterCoder.cpp
+
+#include "StdAfx.h"
+
+#include "FilterCoder.h"
+extern "C" 
+{ 
+#include "../../../C/Alloc.h"
+}
+#include "../../Common/Defs.h"
+#include "StreamUtils.h"
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CFilterCoder::CFilterCoder()
+{ 
+  _buffer = (Byte *)::MidAlloc(kBufferSize); 
+}
+
+CFilterCoder::~CFilterCoder() 
+{ 
+  ::MidFree(_buffer); 
+}
+
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+{
+  if (_outSizeIsDefined)
+  {
+    UInt64 remSize = _outSize - _nowPos64;
+    if (size > remSize)
+      size = (UInt32)remSize;
+  }
+  UInt32 processedSize = 0;
+  RINOK(WriteStream(outStream, _buffer, size, &processedSize));
+  if (size != processedSize)
+    return E_FAIL;
+  _nowPos64 += processedSize;
+  return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+      ICompressProgressInfo *progress)
+{
+  RINOK(Init());
+  UInt32 bufferPos = 0;
+  _outSizeIsDefined = (outSize != 0);
+  if (_outSizeIsDefined)
+    _outSize = *outSize;
+
+  while(NeedMore())
+  {
+    UInt32 processedSize;
+    
+    // Change it: It can be optimized using ReadPart
+    RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+    
+    UInt32 endPos = bufferPos + processedSize;
+
+    bufferPos = Filter->Filter(_buffer, endPos);
+    if (bufferPos > endPos)
+    {
+      for (; endPos< bufferPos; endPos++)
+        _buffer[endPos] = 0;
+      bufferPos = Filter->Filter(_buffer, endPos);
+    }
+
+    if (bufferPos == 0)
+    {
+      if (endPos > 0)
+        return WriteWithLimit(outStream, endPos);
+      return S_OK;
+    }
+    RINOK(WriteWithLimit(outStream, bufferPos));
+    if (progress != NULL)
+    {
+      RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+    }
+    UInt32 i = 0;
+    while(bufferPos < endPos)
+      _buffer[i++] = _buffer[bufferPos++];
+    bufferPos = i;
+  }
+  return S_OK;
+}
+
+// #ifdef _ST_MODE
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
+{
+  _bufferPos = 0;
+  _outStream = outStream;
+  return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseOutStream()
+{
+  _outStream.Release();
+  return S_OK;
+};
+
+
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 processedSizeTotal = 0;
+  while(size > 0)
+  {
+    UInt32 sizeMax = kBufferSize - _bufferPos;
+    UInt32 sizeTemp = size;
+    if (sizeTemp > sizeMax)
+      sizeTemp = sizeMax;
+    memmove(_buffer + _bufferPos, data, sizeTemp);
+    size -= sizeTemp;
+    processedSizeTotal += sizeTemp;
+    data = (const Byte *)data + sizeTemp;
+    UInt32 endPos = _bufferPos + sizeTemp;
+    _bufferPos = Filter->Filter(_buffer, endPos);
+    if (_bufferPos == 0)
+    {
+      _bufferPos = endPos;
+      break;
+    }
+    if (_bufferPos > endPos)
+    {
+      if (size != 0)
+        return E_FAIL;
+      break;
+    }
+    RINOK(WriteWithLimit(_outStream, _bufferPos));
+    UInt32 i = 0;
+    while(_bufferPos < endPos)
+      _buffer[i++] = _buffer[_bufferPos++];
+    _bufferPos = i;
+  }
+  if (processedSize != NULL)
+    *processedSize = processedSizeTotal;
+  return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+  if (_bufferPos != 0)
+  {
+    UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
+    if (endPos > _bufferPos)
+    {
+      for (; _bufferPos < endPos; _bufferPos++)
+        _buffer[_bufferPos] = 0;
+      if (Filter->Filter(_buffer, endPos) != endPos)
+        return E_FAIL;
+    }
+    UInt32 processedSize;
+    RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+    if (_bufferPos != processedSize)
+      return E_FAIL;
+    _bufferPos = 0;
+  }
+  CMyComPtr<IOutStreamFlush> flush;
+  _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+  if (flush)
+    return  flush->Flush();
+  return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+  _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+  _inStream = inStream;
+  return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+  _inStream.Release();
+  return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 processedSizeTotal = 0;
+  while(size > 0)
+  {
+    if (_convertedPosBegin != _convertedPosEnd)
+    {
+      UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+      memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+      _convertedPosBegin += sizeTemp;
+      data = (void *)((Byte *)data + sizeTemp);
+      size -= sizeTemp;
+      processedSizeTotal += sizeTemp;
+      break;
+    }
+    int i;
+    for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+      _buffer[i] = _buffer[i + _convertedPosEnd];
+    _bufferPos = i;
+    _convertedPosBegin = _convertedPosEnd = 0;
+    UInt32 processedSizeTemp;
+    UInt32 size0 = kBufferSize - _bufferPos;
+    // Optimize it:
+    RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+    _bufferPos = _bufferPos + processedSizeTemp;
+    _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+    if (_convertedPosEnd == 0)
+    {
+      if (_bufferPos == 0)
+        break;
+      else
+      {
+        _convertedPosEnd = _bufferPos; // check it
+        continue;
+      }
+    }
+    if (_convertedPosEnd > _bufferPos)
+    {
+      for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+        _buffer[_bufferPos] = 0;
+      _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+    }
+  }
+  if (processedSize != NULL)
+    *processedSize = processedSizeTotal;
+  return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+  return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, 
+      const PROPVARIANT *properties, UInt32 numProperties)
+{
+  return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);
+}
+
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+  return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+
+/*
+STDMETHODIMP CFilterCoder::ResetSalt()
+{
+  return _CryptoResetSalt->ResetSalt();
+}
+*/
+
+STDMETHODIMP CFilterCoder::ResetInitVector()
+{
+  return _CryptoResetInitVector->ResetInitVector();
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+  return _setDecoderProperties->SetDecoderProperties2(data, size);
+}