Exemple #1
0
STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
  if (processedSize != NULL)
    *processedSize = 0;
  while (size > 0)
  {
    UInt32 sizeTemp = MyMin(size, kBufferSize - _bufferPos);
    memcpy(_buffer + _bufferPos, data, sizeTemp);
    size -= sizeTemp;
    if (processedSize != NULL)
      *processedSize += 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;
  }
  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())
  {
    size_t processedSize = kBufferSize - bufferPos;
    
    // Change it: It can be optimized using ReadPart
    RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize));
    
    UInt32 endPos = bufferPos + (UInt32)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;
}
Exemple #3
0
STDMETHODIMP CFilterCoder::Flush()
{
  if (_bufferPos != 0)
  {
    // _buffer contains only data refused by previous Filter->Filter call.
    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;
    }
    RINOK(WriteWithLimit(_outStream, _bufferPos));
    _bufferPos = 0;
  }
  CMyComPtr<IOutStreamFlush> flush;
  _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
  if (flush)
    return flush->Flush();
  return S_OK;
}