tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CopyCoder.cpp (2765B)


      1 // Compress/CopyCoder.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../C/Alloc.h"
      6 
      7 #include "CopyCoder.h"
      8 
      9 namespace NCompress {
     10 
     11 static const UInt32 kBufSize = 1 << 17;
     12 
     13 CCopyCoder::~CCopyCoder()
     14 {
     15  ::MidFree(_buf);
     16 }
     17 
     18 STDMETHODIMP CCopyCoder::SetFinishMode(UInt32 /* finishMode */)
     19 {
     20  return S_OK;
     21 }
     22 
     23 STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
     24    ISequentialOutStream *outStream,
     25    const UInt64 * /* inSize */, const UInt64 *outSize,
     26    ICompressProgressInfo *progress)
     27 {
     28  if (!_buf)
     29  {
     30    _buf = (Byte *)::MidAlloc(kBufSize);
     31    if (!_buf)
     32      return E_OUTOFMEMORY;
     33  }
     34 
     35  TotalSize = 0;
     36  
     37  for (;;)
     38  {
     39    UInt32 size = kBufSize;
     40    if (outSize && size > *outSize - TotalSize)
     41      size = (UInt32)(*outSize - TotalSize);
     42    if (size == 0)
     43      return S_OK;
     44    
     45    HRESULT readRes = inStream->Read(_buf, size, &size);
     46 
     47    if (size == 0)
     48      return readRes;
     49 
     50    if (outStream)
     51    {
     52      UInt32 pos = 0;
     53      do
     54      {
     55        UInt32 curSize = size - pos;
     56        HRESULT res = outStream->Write(_buf + pos, curSize, &curSize);
     57        pos += curSize;
     58        TotalSize += curSize;
     59        RINOK(res);
     60        if (curSize == 0)
     61          return E_FAIL;
     62      }
     63      while (pos < size);
     64    }
     65    else
     66      TotalSize += size;
     67 
     68    RINOK(readRes);
     69 
     70    if (progress)
     71    {
     72      RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
     73    }
     74  }
     75 }
     76 
     77 STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream)
     78 {
     79  _inStream = inStream;
     80  TotalSize = 0;
     81  return S_OK;
     82 }
     83 
     84 STDMETHODIMP CCopyCoder::ReleaseInStream()
     85 {
     86  _inStream.Release();
     87  return S_OK;
     88 }
     89 
     90 STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
     91 {
     92  UInt32 realProcessedSize = 0;
     93  HRESULT res = _inStream->Read(data, size, &realProcessedSize);
     94  TotalSize += realProcessedSize;
     95  if (processedSize)
     96    *processedSize = realProcessedSize;
     97  return res;
     98 }
     99 
    100 STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
    101 {
    102  *value = TotalSize;
    103  return S_OK;
    104 }
    105 
    106 HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
    107 {
    108  CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
    109  return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
    110 }
    111 
    112 HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
    113 {
    114  NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
    115  CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
    116  RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress));
    117  return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
    118 }
    119 
    120 }