tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

7zFolderInStream.cpp (2935B)


      1 // 7zFolderInStream.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "7zFolderInStream.h"
      6 
      7 namespace NArchive {
      8 namespace N7z {
      9 
     10 void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
     11    const UInt32 *indexes, unsigned numFiles)
     12 {
     13  _updateCallback = updateCallback;
     14  _indexes = indexes;
     15  _numFiles = numFiles;
     16  _index = 0;
     17  
     18  Processed.ClearAndReserve(numFiles);
     19  CRCs.ClearAndReserve(numFiles);
     20  Sizes.ClearAndReserve(numFiles);
     21  
     22  _pos = 0;
     23  _crc = CRC_INIT_VAL;
     24  _size_Defined = false;
     25  _size = 0;
     26 
     27  _stream.Release();
     28 }
     29 
     30 HRESULT CFolderInStream::OpenStream()
     31 {
     32  _pos = 0;
     33  _crc = CRC_INIT_VAL;
     34  _size_Defined = false;
     35  _size = 0;
     36 
     37  while (_index < _numFiles)
     38  {
     39    CMyComPtr<ISequentialInStream> stream;
     40    HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
     41    if (result != S_OK)
     42    {
     43      if (result != S_FALSE)
     44        return result;
     45    }
     46 
     47    _stream = stream;
     48    
     49    if (stream)
     50    {
     51      CMyComPtr<IStreamGetSize> streamGetSize;
     52      stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
     53      if (streamGetSize)
     54      {
     55        if (streamGetSize->GetSize(&_size) == S_OK)
     56          _size_Defined = true;
     57      }
     58      return S_OK;
     59    }
     60    
     61    _index++;
     62    RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
     63    AddFileInfo(result == S_OK);
     64  }
     65  return S_OK;
     66 }
     67 
     68 void CFolderInStream::AddFileInfo(bool isProcessed)
     69 {
     70  Processed.Add(isProcessed);
     71  Sizes.Add(_pos);
     72  CRCs.Add(CRC_GET_DIGEST(_crc));
     73 }
     74 
     75 STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
     76 {
     77  if (processedSize)
     78    *processedSize = 0;
     79  while (size != 0)
     80  {
     81    if (_stream)
     82    {
     83      UInt32 cur = size;
     84      const UInt32 kMax = (UInt32)1 << 20;
     85      if (cur > kMax)
     86        cur = kMax;
     87      RINOK(_stream->Read(data, cur, &cur));
     88      if (cur != 0)
     89      {
     90        _crc = CrcUpdate(_crc, data, cur);
     91        _pos += cur;
     92        if (processedSize)
     93          *processedSize = cur;
     94        return S_OK;
     95      }
     96      
     97      _stream.Release();
     98      _index++;
     99      AddFileInfo(true);
    100 
    101      _pos = 0;
    102      _crc = CRC_INIT_VAL;
    103      _size_Defined = false;
    104      _size = 0;
    105 
    106      RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
    107    }
    108    
    109    if (_index >= _numFiles)
    110      break;
    111    RINOK(OpenStream());
    112  }
    113  return S_OK;
    114 }
    115 
    116 STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
    117 {
    118  *value = 0;
    119  if (subStream > Sizes.Size())
    120    return S_FALSE; // E_FAIL;
    121  
    122  unsigned index = (unsigned)subStream;
    123  if (index < Sizes.Size())
    124  {
    125    *value = Sizes[index];
    126    return S_OK;
    127  }
    128  
    129  if (!_size_Defined)
    130  {
    131    *value = _pos;
    132    return S_FALSE;
    133  }
    134  
    135  *value = (_pos > _size ? _pos : _size);
    136  return S_OK;
    137 }
    138 
    139 }}