• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 7zFolderInStream.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "7zFolderInStream.h"
6 
7 namespace NArchive {
8 namespace N7z {
9 
Init(IArchiveUpdateCallback * updateCallback,const UInt32 * indexes,unsigned numFiles)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 
OpenStream()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 
AddFileInfo(bool isProcessed)68 void CFolderInStream::AddFileInfo(bool isProcessed)
69 {
70   Processed.Add(isProcessed);
71   Sizes.Add(_pos);
72   CRCs.Add(CRC_GET_DIGEST(_crc));
73 }
74 
Read(void * data,UInt32 size,UInt32 * processedSize)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 processed2;
84       RINOK(_stream->Read(data, size, &processed2));
85       if (processed2 != 0)
86       {
87         _crc = CrcUpdate(_crc, data, processed2);
88         _pos += processed2;
89         if (processedSize)
90           *processedSize = processed2;
91         return S_OK;
92       }
93 
94       _stream.Release();
95       _index++;
96       AddFileInfo(true);
97 
98       _pos = 0;
99       _crc = CRC_INIT_VAL;
100       _size_Defined = false;
101       _size = 0;
102 
103       RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
104     }
105 
106     if (_index >= _numFiles)
107       break;
108     RINOK(OpenStream());
109   }
110   return S_OK;
111 }
112 
GetSubStreamSize(UInt64 subStream,UInt64 * value)113 STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
114 {
115   *value = 0;
116   if (subStream > Sizes.Size())
117     return S_FALSE; // E_FAIL;
118 
119   unsigned index = (unsigned)subStream;
120   if (index < Sizes.Size())
121   {
122     *value = Sizes[index];
123     return S_OK;
124   }
125 
126   if (!_size_Defined)
127   {
128     *value = _pos;
129     return S_FALSE;
130   }
131 
132   *value = (_pos > _size ? _pos : _size);
133   return S_OK;
134 }
135 
136 }}
137