Home | History | Annotate | Download | only in Common
      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 #define 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