Home | History | Annotate | Download | only in Compress
      1 // Compress/CopyCoder.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../C/Alloc.h"
      6 
      7 #include "../Common/StreamUtils.h"
      8 
      9 #include "CopyCoder.h"
     10 
     11 namespace NCompress {
     12 
     13 static const UInt32 kBufferSize = 1 << 17;
     14 
     15 CCopyCoder::~CCopyCoder()
     16 {
     17   ::MidFree(_buffer);
     18 }
     19 
     20 STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
     21     ISequentialOutStream *outStream,
     22     const UInt64 * /* inSize */, const UInt64 *outSize,
     23     ICompressProgressInfo *progress)
     24 {
     25   if (!_buffer)
     26   {
     27     _buffer = (Byte *)::MidAlloc(kBufferSize);
     28     if (!_buffer)
     29       return E_OUTOFMEMORY;
     30   }
     31 
     32   TotalSize = 0;
     33   for (;;)
     34   {
     35     UInt32 size = kBufferSize;
     36     if (outSize && size > *outSize - TotalSize)
     37       size = (UInt32)(*outSize - TotalSize);
     38     RINOK(inStream->Read(_buffer, size, &size));
     39     if (size == 0)
     40       break;
     41     if (outStream)
     42     {
     43       RINOK(WriteStream(outStream, _buffer, size));
     44     }
     45     TotalSize += size;
     46     if (progress)
     47     {
     48       RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
     49     }
     50   }
     51   return S_OK;
     52 }
     53 
     54 STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
     55 {
     56   *value = TotalSize;
     57   return S_OK;
     58 }
     59 
     60 HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
     61 {
     62   CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
     63   return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
     64 }
     65 
     66 HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
     67 {
     68   NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
     69   CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
     70   RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress));
     71   return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
     72 }
     73 
     74 }
     75