other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 // InOutTempBuffer.cpp
michael@0 2
michael@0 3 #include "StdAfx.h"
michael@0 4
michael@0 5 #include "InOutTempBuffer.h"
michael@0 6 #include "../../Common/Defs.h"
michael@0 7 // #include "Windows/Defs.h"
michael@0 8
michael@0 9 #include "StreamUtils.h"
michael@0 10
michael@0 11 using namespace NWindows;
michael@0 12 using namespace NFile;
michael@0 13 using namespace NDirectory;
michael@0 14
michael@0 15 static UInt32 kTmpBufferMemorySize = (1 << 20);
michael@0 16
michael@0 17 static LPCTSTR kTempFilePrefixString = TEXT("iot");
michael@0 18
michael@0 19 CInOutTempBuffer::CInOutTempBuffer():
michael@0 20 _buffer(NULL)
michael@0 21 {
michael@0 22 }
michael@0 23
michael@0 24 void CInOutTempBuffer::Create()
michael@0 25 {
michael@0 26 _buffer = new Byte[kTmpBufferMemorySize];
michael@0 27 }
michael@0 28
michael@0 29 CInOutTempBuffer::~CInOutTempBuffer()
michael@0 30 {
michael@0 31 delete []_buffer;
michael@0 32 }
michael@0 33 void CInOutTempBuffer::InitWriting()
michael@0 34 {
michael@0 35 _bufferPosition = 0;
michael@0 36 _tmpFileCreated = false;
michael@0 37 _fileSize = 0;
michael@0 38 }
michael@0 39
michael@0 40 bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
michael@0 41 {
michael@0 42 if (size == 0)
michael@0 43 return true;
michael@0 44 if(!_tmpFileCreated)
michael@0 45 {
michael@0 46 CSysString tempDirPath;
michael@0 47 if(!MyGetTempPath(tempDirPath))
michael@0 48 return false;
michael@0 49 if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
michael@0 50 return false;
michael@0 51 // _outFile.SetOpenCreationDispositionCreateAlways();
michael@0 52 if(!_outFile.Create(_tmpFileName, true))
michael@0 53 return false;
michael@0 54 _tmpFileCreated = true;
michael@0 55 }
michael@0 56 UInt32 processedSize;
michael@0 57 if(!_outFile.Write(data, size, processedSize))
michael@0 58 return false;
michael@0 59 _fileSize += processedSize;
michael@0 60 return (processedSize == size);
michael@0 61 }
michael@0 62
michael@0 63 bool CInOutTempBuffer::FlushWrite()
michael@0 64 {
michael@0 65 return _outFile.Close();
michael@0 66 }
michael@0 67
michael@0 68 bool CInOutTempBuffer::Write(const void *data, UInt32 size)
michael@0 69 {
michael@0 70 if(_bufferPosition < kTmpBufferMemorySize)
michael@0 71 {
michael@0 72 UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
michael@0 73 memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
michael@0 74 _bufferPosition += curSize;
michael@0 75 size -= curSize;
michael@0 76 data = ((const Byte *)data) + curSize;
michael@0 77 _fileSize += curSize;
michael@0 78 }
michael@0 79 return WriteToFile(data, size);
michael@0 80 }
michael@0 81
michael@0 82 bool CInOutTempBuffer::InitReading()
michael@0 83 {
michael@0 84 _currentPositionInBuffer = 0;
michael@0 85 if(_tmpFileCreated)
michael@0 86 return _inFile.Open(_tmpFileName);
michael@0 87 return true;
michael@0 88 }
michael@0 89
michael@0 90 HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
michael@0 91 {
michael@0 92 if (_currentPositionInBuffer < _bufferPosition)
michael@0 93 {
michael@0 94 UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
michael@0 95 RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
michael@0 96 _currentPositionInBuffer += sizeToWrite;
michael@0 97 }
michael@0 98 if (!_tmpFileCreated)
michael@0 99 return true;
michael@0 100 while(true)
michael@0 101 {
michael@0 102 UInt32 localProcessedSize;
michael@0 103 if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
michael@0 104 return E_FAIL;
michael@0 105 if (localProcessedSize == 0)
michael@0 106 return S_OK;
michael@0 107 RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
michael@0 108 }
michael@0 109 }
michael@0 110
michael@0 111 STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
michael@0 112 {
michael@0 113 if (!_buffer->Write(data, size))
michael@0 114 {
michael@0 115 if (processedSize != NULL)
michael@0 116 *processedSize = 0;
michael@0 117 return E_FAIL;
michael@0 118 }
michael@0 119 if (processedSize != NULL)
michael@0 120 *processedSize = size;
michael@0 121 return S_OK;
michael@0 122 }

mercurial