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