misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
changeset 12218 bb5522e88ab2
equal deleted inserted replaced
12217:ea891871f481 12218:bb5522e88ab2
       
     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 }