mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
123 lines
2.7 KiB
C++
123 lines
2.7 KiB
C++
|
// InOutTempBuffer.cpp
|
||
|
|
||
|
#include "StdAfx.h"
|
||
|
|
||
|
#include "../../../C/7zCrc.h"
|
||
|
|
||
|
#include "InOutTempBuffer.h"
|
||
|
#include "StreamUtils.h"
|
||
|
|
||
|
using namespace NWindows;
|
||
|
using namespace NFile;
|
||
|
using namespace NDirectory;
|
||
|
|
||
|
static const UInt32 kTempBufSize = (1 << 20);
|
||
|
|
||
|
static LPCTSTR kTempFilePrefixString = TEXT("7zt");
|
||
|
|
||
|
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
|
||
|
|
||
|
void CInOutTempBuffer::Create()
|
||
|
{
|
||
|
if (!_buf)
|
||
|
_buf = new Byte[kTempBufSize];
|
||
|
}
|
||
|
|
||
|
CInOutTempBuffer::~CInOutTempBuffer()
|
||
|
{
|
||
|
delete []_buf;
|
||
|
}
|
||
|
|
||
|
void CInOutTempBuffer::InitWriting()
|
||
|
{
|
||
|
_bufPos = 0;
|
||
|
_tempFileCreated = false;
|
||
|
_size = 0;
|
||
|
_crc = CRC_INIT_VAL;
|
||
|
}
|
||
|
|
||
|
bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
|
||
|
{
|
||
|
if (size == 0)
|
||
|
return true;
|
||
|
if (!_tempFileCreated)
|
||
|
{
|
||
|
CSysString tempDirPath;
|
||
|
if (!MyGetTempPath(tempDirPath))
|
||
|
return false;
|
||
|
if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tempFileName) == 0)
|
||
|
return false;
|
||
|
if (!_outFile.Create(_tempFileName, true))
|
||
|
return false;
|
||
|
_tempFileCreated = true;
|
||
|
}
|
||
|
UInt32 processed;
|
||
|
if (!_outFile.Write(data, size, processed))
|
||
|
return false;
|
||
|
_crc = CrcUpdate(_crc, data, processed);
|
||
|
_size += processed;
|
||
|
return (processed == size);
|
||
|
}
|
||
|
|
||
|
bool CInOutTempBuffer::Write(const void *data, UInt32 size)
|
||
|
{
|
||
|
if (_bufPos < kTempBufSize)
|
||
|
{
|
||
|
UInt32 cur = MyMin(kTempBufSize - _bufPos, size);
|
||
|
memcpy(_buf + _bufPos, data, cur);
|
||
|
_crc = CrcUpdate(_crc, data, cur);
|
||
|
_bufPos += cur;
|
||
|
size -= cur;
|
||
|
data = ((const Byte *)data) + cur;
|
||
|
_size += cur;
|
||
|
}
|
||
|
return WriteToFile(data, size);
|
||
|
}
|
||
|
|
||
|
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
|
||
|
{
|
||
|
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(_tempFileName))
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed)
|
||
|
{
|
||
|
if (!_buf->Write(data, size))
|
||
|
{
|
||
|
if (processed != NULL)
|
||
|
*processed = 0;
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
if (processed != NULL)
|
||
|
*processed = size;
|
||
|
return S_OK;
|
||
|
}
|