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