1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// InOutTempBuffer.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/7zCrc.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "InOutTempBuffer.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StreamUtils.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows; 11baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NFile; 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NDirectory; 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 14baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kTempBufSize = (1 << 20); 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic LPCTSTR kTempFilePrefixString = TEXT("7zt"); 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { } 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInOutTempBuffer::Create() 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_buf) 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buf = new Byte[kTempBufSize]; 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 26baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCInOutTempBuffer::~CInOutTempBuffer() 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync delete []_buf; 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 31baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInOutTempBuffer::InitWriting() 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bufPos = 0; 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _tempFileCreated = false; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _size = 0; 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _crc = CRC_INIT_VAL; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 39baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size == 0) 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_tempFileCreated) 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSysString tempDirPath; 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!MyGetTempPath(tempDirPath)) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tempFileName) == 0) 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_outFile.Create(_tempFileName, true)) 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _tempFileCreated = true; 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 processed; 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_outFile.Write(data, size, processed)) 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _crc = CrcUpdate(_crc, data, processed); 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _size += processed; 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (processed == size); 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 62baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CInOutTempBuffer::Write(const void *data, UInt32 size) 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_bufPos < kTempBufSize) 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 cur = MyMin(kTempBufSize - _bufPos, size); 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memcpy(_buf + _bufPos, data, cur); 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _crc = CrcUpdate(_crc, data, cur); 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bufPos += cur; 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size -= cur; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync data = ((const Byte *)data) + cur; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _size += cur; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteToFile(data, size); 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 77baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_outFile.Close()) 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size = 0; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 crc = CRC_INIT_VAL; 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_bufPos > 0) 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteStream(stream, _buf, _bufPos)); 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc = CrcUpdate(crc, _buf, _bufPos); 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size += _bufPos; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_tempFileCreated) 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NIO::CInFile inFile; 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!inFile.Open(_tempFileName)) 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (size < _size) 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 processed; 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!inFile.ReadPart(_buf, kTempBufSize, processed)) 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processed == 0) 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(WriteStream(stream, _buf, processed)); 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc = CrcUpdate(crc, _buf, processed); 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size += processed; 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (_crc == crc && size == _size) ? S_OK : E_FAIL; 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 111baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed) 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_buf->Write(data, size)) 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processed != NULL) 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processed = 0; 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processed != NULL) 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processed = size; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 123