Files
Aaru.Compression.Native/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp

154 lines
3.4 KiB
C++
Raw Normal View History

2021-10-19 21:27:23 +01:00
// Compress/CopyCoder.cpp
#include "StdAfx.h"
#include "../../../C/Alloc.h"
#include "CopyCoder.h"
namespace NCompress {
static const UInt32 kBufSize = 1 << 17;
CCopyCoder::~CCopyCoder()
{
::MidFree(_buf);
}
2023-09-24 03:13:03 +01:00
Z7_COM7F_IMF(CCopyCoder::SetFinishMode(UInt32 /* finishMode */))
2021-10-19 21:27:23 +01:00
{
return S_OK;
}
2023-09-24 03:13:03 +01:00
Z7_COM7F_IMF(CCopyCoder::Code(ISequentialInStream *inStream,
2021-10-19 21:27:23 +01:00
ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize,
2023-09-24 03:13:03 +01:00
ICompressProgressInfo *progress))
2021-10-19 21:27:23 +01:00
{
if (!_buf)
{
_buf = (Byte *)::MidAlloc(kBufSize);
if (!_buf)
return E_OUTOFMEMORY;
}
TotalSize = 0;
for (;;)
{
UInt32 size = kBufSize;
2023-09-24 03:13:03 +01:00
if (outSize)
{
const UInt64 rem = *outSize - TotalSize;
if (size > rem)
{
size = (UInt32)rem;
if (size == 0)
{
/* if we enable the following check,
we will make one call of Read(_buf, 0) for empty stream */
// if (TotalSize != 0)
return S_OK;
}
}
}
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
HRESULT readRes;
{
UInt32 pos = 0;
do
{
const UInt32 curSize = size - pos;
UInt32 processed = 0;
readRes = inStream->Read(_buf + pos, curSize, &processed);
if (processed > curSize)
return E_FAIL; // internal code failure
pos += processed;
if (readRes != S_OK || processed == 0)
break;
}
while (pos < kBufSize);
size = pos;
}
2021-10-19 21:27:23 +01:00
if (size == 0)
return readRes;
if (outStream)
{
UInt32 pos = 0;
do
{
2023-09-24 03:13:03 +01:00
const UInt32 curSize = size - pos;
UInt32 processed = 0;
const HRESULT res = outStream->Write(_buf + pos, curSize, &processed);
if (processed > curSize)
return E_FAIL; // internal code failure
pos += processed;
TotalSize += processed;
RINOK(res)
if (processed == 0)
2021-10-19 21:27:23 +01:00
return E_FAIL;
}
while (pos < size);
}
else
TotalSize += size;
2023-09-24 03:13:03 +01:00
RINOK(readRes)
if (size != kBufSize)
return S_OK;
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0)
2021-10-19 21:27:23 +01:00
{
2023-09-24 03:13:03 +01:00
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize))
2021-10-19 21:27:23 +01:00
}
}
}
2023-09-24 03:13:03 +01:00
Z7_COM7F_IMF(CCopyCoder::SetInStream(ISequentialInStream *inStream))
2021-10-19 21:27:23 +01:00
{
_inStream = inStream;
TotalSize = 0;
return S_OK;
}
2023-09-24 03:13:03 +01:00
Z7_COM7F_IMF(CCopyCoder::ReleaseInStream())
2021-10-19 21:27:23 +01:00
{
_inStream.Release();
return S_OK;
}
2023-09-24 03:13:03 +01:00
Z7_COM7F_IMF(CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize))
2021-10-19 21:27:23 +01:00
{
UInt32 realProcessedSize = 0;
HRESULT res = _inStream->Read(data, size, &realProcessedSize);
TotalSize += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return res;
}
2023-09-24 03:13:03 +01:00
Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize(UInt64 *value))
2021-10-19 21:27:23 +01:00
{
*value = TotalSize;
return S_OK;
}
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
{
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
2023-09-24 03:13:03 +01:00
RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress))
2021-10-19 21:27:23 +01:00
return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
}
}