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