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