mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Add LZMA.
This commit is contained in:
171
3rdparty/lzma-21.03beta/CPP/7zip/Common/InOutTempBuffer.cpp
vendored
Normal file
171
3rdparty/lzma-21.03beta/CPP/7zip/Common/InOutTempBuffer.cpp
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
// InOutTempBuffer.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "InOutTempBuffer.h"
|
||||
#include "StreamUtils.h"
|
||||
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
#include "../../../C/7zCrc.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
static const size_t kTempBufSize = (1 << 20);
|
||||
|
||||
#define kTempFilePrefixString FTEXT("7zt")
|
||||
CInOutTempBuffer::~CInOutTempBuffer()
|
||||
{
|
||||
delete []_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
CInOutTempBuffer::CInOutTempBuffer()
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
: _buf(NULL)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
void CInOutTempBuffer::Create()
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
if (!_buf)
|
||||
_buf = new Byte[kTempBufSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
void CInOutTempBuffer::InitWriting()
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
_bufPos = 0;
|
||||
_crc = CRC_INIT_VAL;
|
||||
_tempFileCreated = false;
|
||||
#endif
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
static inline HRESULT Get_HRESULT_LastError()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD lastError = ::GetLastError();
|
||||
if (lastError != 0)
|
||||
return HRESULT_FROM_WIN32(lastError);
|
||||
#endif
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT CInOutTempBuffer::Write_HRESULT(const void *data, UInt32 size)
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
size_t cur = kTempBufSize - _bufPos;
|
||||
if (cur != 0)
|
||||
{
|
||||
if (cur > size)
|
||||
cur = size;
|
||||
memcpy(_buf + _bufPos, data, cur);
|
||||
_crc = CrcUpdate(_crc, data, cur);
|
||||
_bufPos += cur;
|
||||
_size += cur;
|
||||
size -= (UInt32)cur;
|
||||
data = ((const Byte *)data) + cur;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
|
||||
if (!_tempFileCreated)
|
||||
{
|
||||
if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
|
||||
return Get_HRESULT_LastError();
|
||||
_tempFileCreated = true;
|
||||
}
|
||||
UInt32 processed;
|
||||
if (!_outFile.Write(data, size, processed))
|
||||
return Get_HRESULT_LastError();
|
||||
_crc = CrcUpdate(_crc, data, processed);
|
||||
_size += processed;
|
||||
return (processed == size) ? S_OK : E_FAIL;
|
||||
|
||||
#else
|
||||
|
||||
const size_t newSize = _size + size;
|
||||
if (newSize < _size)
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_dynBuffer.EnsureCapacity(newSize))
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy(((Byte *)_dynBuffer) + _size, data, size);
|
||||
_size = newSize;
|
||||
return S_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
if (!_outFile.Close())
|
||||
return E_FAIL;
|
||||
|
||||
UInt64 size = 0;
|
||||
UInt32 crc = CRC_INIT_VAL;
|
||||
|
||||
if (_bufPos != 0)
|
||||
{
|
||||
RINOK(WriteStream(stream, _buf, _bufPos));
|
||||
crc = CrcUpdate(crc, _buf, _bufPos);
|
||||
size += _bufPos;
|
||||
}
|
||||
|
||||
if (_tempFileCreated)
|
||||
{
|
||||
NIO::CInFile inFile;
|
||||
if (!inFile.Open(_tempFile.GetPath()))
|
||||
return E_FAIL;
|
||||
while (size < _size)
|
||||
{
|
||||
UInt32 processed;
|
||||
if (!inFile.ReadPart(_buf, kTempBufSize, processed))
|
||||
return E_FAIL;
|
||||
if (processed == 0)
|
||||
break;
|
||||
RINOK(WriteStream(stream, _buf, processed));
|
||||
crc = CrcUpdate(crc, _buf, processed);
|
||||
size += processed;
|
||||
}
|
||||
}
|
||||
return (_crc == crc && size == _size) ? S_OK : E_FAIL;
|
||||
|
||||
#else
|
||||
|
||||
return WriteStream(stream, (const Byte *)_dynBuffer, _size);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed)
|
||||
{
|
||||
if (!_buf->Write(data, size))
|
||||
{
|
||||
if (processed)
|
||||
*processed = 0;
|
||||
return E_FAIL;
|
||||
}
|
||||
if (processed)
|
||||
*processed = size;
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user