1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zFolderInStream.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zFolderInStream.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive {
8baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z {
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCFolderInStream::CFolderInStream()
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _inStreamWithHashSpec = new CSequentialInStreamWithCRC;
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _inStreamWithHash = _inStreamWithHashSpec;
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt32 *fileIndices, UInt32 numFiles)
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _updateCallback = updateCallback;
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _numFiles = numFiles;
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _fileIndex = 0;
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _fileIndices = fileIndices;
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Processed.Clear();
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRCs.Clear();
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Sizes.Clear();
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _fileIsOpen = false;
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _currentSizeIsDefined = false;
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
30baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CFolderInStream::OpenStream()
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _filePos = 0;
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (_fileIndex < _numFiles)
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialInStream> stream;
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (result != S_OK && result != S_FALSE)
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return result;
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _fileIndex++;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _inStreamWithHashSpec->SetStream(stream);
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _inStreamWithHashSpec->Init();
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (stream)
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _fileIsOpen = true;
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<IStreamGetSize> streamGetSize;
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (streamGetSize)
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(streamGetSize->GetSize(&_currentSize));
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _currentSizeIsDefined = true;
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Sizes.Add(0);
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Processed.Add(result == S_OK);
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    AddDigest();
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
62baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CFolderInStream::AddDigest()
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRCs.Add(_inStreamWithHashSpec->GetCRC());
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
67baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CFolderInStream::CloseStream()
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _inStreamWithHashSpec->ReleaseStream();
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _fileIsOpen = false;
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _currentSizeIsDefined = false;
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Processed.Add(true);
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Sizes.Add(_filePos);
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  AddDigest();
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
79baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (processedSize != 0)
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *processedSize = 0;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (size > 0)
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_fileIsOpen)
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 processed2;
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(_inStreamWithHash->Read(data, size, &processed2));
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (processed2 == 0)
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(CloseStream());
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        continue;
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (processedSize != 0)
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *processedSize = processed2;
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _filePos += processed2;
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_fileIndex >= _numFiles)
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(OpenStream());
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
106baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *value = 0;
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index2 = (int)subStream;
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (index2 < 0 || subStream > Sizes.Size())
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (index2 < Sizes.Size())
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *value = Sizes[index2];
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_currentSizeIsDefined)
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_FALSE;
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *value = _currentSize;
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
124