123 lines
2.8 KiB
C++
123 lines
2.8 KiB
C++
|
// InOutTempBuffer.cpp
|
||
|
|
||
|
#include "StdAfx.h"
|
||
|
|
||
|
#include "InOutTempBuffer.h"
|
||
|
#include "../../Common/Defs.h"
|
||
|
// #include "Windows/Defs.h"
|
||
|
|
||
|
#include "StreamUtils.h"
|
||
|
|
||
|
using namespace NWindows;
|
||
|
using namespace NFile;
|
||
|
using namespace NDirectory;
|
||
|
|
||
|
static UInt32 kTmpBufferMemorySize = (1 << 20);
|
||
|
|
||
|
static LPCTSTR kTempFilePrefixString = TEXT("iot");
|
||
|
|
||
|
CInOutTempBuffer::CInOutTempBuffer():
|
||
|
_buffer(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void CInOutTempBuffer::Create()
|
||
|
{
|
||
|
_buffer = new Byte[kTmpBufferMemorySize];
|
||
|
}
|
||
|
|
||
|
CInOutTempBuffer::~CInOutTempBuffer()
|
||
|
{
|
||
|
delete []_buffer;
|
||
|
}
|
||
|
void CInOutTempBuffer::InitWriting()
|
||
|
{
|
||
|
_bufferPosition = 0;
|
||
|
_tmpFileCreated = false;
|
||
|
_fileSize = 0;
|
||
|
}
|
||
|
|
||
|
bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
|
||
|
{
|
||
|
if (size == 0)
|
||
|
return true;
|
||
|
if(!_tmpFileCreated)
|
||
|
{
|
||
|
CSysString tempDirPath;
|
||
|
if(!MyGetTempPath(tempDirPath))
|
||
|
return false;
|
||
|
if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
|
||
|
return false;
|
||
|
// _outFile.SetOpenCreationDispositionCreateAlways();
|
||
|
if(!_outFile.Create(_tmpFileName, true))
|
||
|
return false;
|
||
|
_tmpFileCreated = true;
|
||
|
}
|
||
|
UInt32 processedSize;
|
||
|
if(!_outFile.Write(data, size, processedSize))
|
||
|
return false;
|
||
|
_fileSize += processedSize;
|
||
|
return (processedSize == size);
|
||
|
}
|
||
|
|
||
|
bool CInOutTempBuffer::FlushWrite()
|
||
|
{
|
||
|
return _outFile.Close();
|
||
|
}
|
||
|
|
||
|
bool CInOutTempBuffer::Write(const void *data, UInt32 size)
|
||
|
{
|
||
|
if(_bufferPosition < kTmpBufferMemorySize)
|
||
|
{
|
||
|
UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
|
||
|
memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
|
||
|
_bufferPosition += curSize;
|
||
|
size -= curSize;
|
||
|
data = ((const Byte *)data) + curSize;
|
||
|
_fileSize += curSize;
|
||
|
}
|
||
|
return WriteToFile(data, size);
|
||
|
}
|
||
|
|
||
|
bool CInOutTempBuffer::InitReading()
|
||
|
{
|
||
|
_currentPositionInBuffer = 0;
|
||
|
if(_tmpFileCreated)
|
||
|
return _inFile.Open(_tmpFileName);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
|
||
|
{
|
||
|
if (_currentPositionInBuffer < _bufferPosition)
|
||
|
{
|
||
|
UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
|
||
|
RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
|
||
|
_currentPositionInBuffer += sizeToWrite;
|
||
|
}
|
||
|
if (!_tmpFileCreated)
|
||
|
return true;
|
||
|
for (;;)
|
||
|
{
|
||
|
UInt32 localProcessedSize;
|
||
|
if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
|
||
|
return E_FAIL;
|
||
|
if (localProcessedSize == 0)
|
||
|
return S_OK;
|
||
|
RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||
|
{
|
||
|
if (!_buffer->Write(data, size))
|
||
|
{
|
||
|
if (processedSize != NULL)
|
||
|
*processedSize = 0;
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
if (processedSize != NULL)
|
||
|
*processedSize = size;
|
||
|
return S_OK;
|
||
|
}
|