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