misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
changeset 12213 bb5522e88ab2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,122 @@
+// InOutTempBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InOutTempBuffer.h"
+#include "../../Common/Defs.h"
+// #include "Windows/Defs.h"
+
+#include "StreamUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static UInt32 kTmpBufferMemorySize = (1 << 20);
+
+static LPCTSTR kTempFilePrefixString = TEXT("iot");
+
+CInOutTempBuffer::CInOutTempBuffer():
+  _buffer(NULL)
+{
+}
+
+void CInOutTempBuffer::Create()
+{
+  _buffer = new Byte[kTmpBufferMemorySize];
+}
+
+CInOutTempBuffer::~CInOutTempBuffer()
+{
+  delete []_buffer;
+}
+void CInOutTempBuffer::InitWriting()
+{
+  _bufferPosition = 0;
+  _tmpFileCreated = false;
+  _fileSize = 0;
+}
+
+bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
+{
+  if (size == 0)
+    return true;
+  if(!_tmpFileCreated)
+  {
+    CSysString tempDirPath;
+    if(!MyGetTempPath(tempDirPath))
+      return false;
+    if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
+      return false;
+    // _outFile.SetOpenCreationDispositionCreateAlways();
+    if(!_outFile.Create(_tmpFileName, true))
+      return false;
+    _tmpFileCreated = true;
+  }
+  UInt32 processedSize;
+  if(!_outFile.Write(data, size, processedSize))
+    return false;
+  _fileSize += processedSize;
+  return (processedSize == size);
+}
+
+bool CInOutTempBuffer::FlushWrite()
+{
+  return _outFile.Close();
+}
+
+bool CInOutTempBuffer::Write(const void *data, UInt32 size)
+{
+  if(_bufferPosition < kTmpBufferMemorySize)
+  {
+    UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
+    memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
+    _bufferPosition += curSize;
+    size -= curSize;
+    data = ((const Byte *)data) + curSize;
+    _fileSize += curSize;
+  }
+  return WriteToFile(data, size);
+}
+
+bool CInOutTempBuffer::InitReading()
+{
+  _currentPositionInBuffer = 0;
+  if(_tmpFileCreated)
+    return _inFile.Open(_tmpFileName);
+  return true;
+}
+
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
+{
+  if (_currentPositionInBuffer < _bufferPosition)
+  {
+    UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
+    RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+    _currentPositionInBuffer += sizeToWrite;
+  }
+  if (!_tmpFileCreated)
+    return true;
+  for (;;)
+  {
+    UInt32 localProcessedSize;
+    if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
+      return E_FAIL;
+    if (localProcessedSize == 0)
+      return S_OK;
+    RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
+  }
+}
+
+STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if (!_buffer->Write(data, size))
+  {
+    if (processedSize != NULL)
+      *processedSize = 0;
+    return E_FAIL;
+  }
+  if (processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}