Mercurial > vba-linux
comparison src/win32/7zip/7z/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // 7zFolderOutStream.cpp | |
2 | |
3 #include "StdAfx.h" | |
4 | |
5 #include "7zFolderOutStream.h" | |
6 | |
7 namespace NArchive { | |
8 namespace N7z { | |
9 | |
10 CFolderOutStream::CFolderOutStream() | |
11 { | |
12 _outStreamWithHashSpec = new COutStreamWithCRC; | |
13 _outStreamWithHash = _outStreamWithHashSpec; | |
14 } | |
15 | |
16 HRESULT CFolderOutStream::Init( | |
17 const CArchiveDatabaseEx *archiveDatabase, | |
18 UInt32 ref2Offset, | |
19 UInt32 startIndex, | |
20 const CBoolVector *extractStatuses, | |
21 IArchiveExtractCallback *extractCallback, | |
22 bool testMode, | |
23 bool checkCrc) | |
24 { | |
25 _archiveDatabase = archiveDatabase; | |
26 _ref2Offset = ref2Offset; | |
27 _startIndex = startIndex; | |
28 | |
29 _extractStatuses = extractStatuses; | |
30 _extractCallback = extractCallback; | |
31 _testMode = testMode; | |
32 | |
33 _checkCrc = checkCrc; | |
34 | |
35 _currentIndex = 0; | |
36 _fileIsOpen = false; | |
37 return WriteEmptyFiles(); | |
38 } | |
39 | |
40 HRESULT CFolderOutStream::OpenFile() | |
41 { | |
42 Int32 askMode; | |
43 if((*_extractStatuses)[_currentIndex]) | |
44 askMode = _testMode ? | |
45 NArchive::NExtract::NAskMode::kTest : | |
46 NArchive::NExtract::NAskMode::kExtract; | |
47 else | |
48 askMode = NArchive::NExtract::NAskMode::kSkip; | |
49 CMyComPtr<ISequentialOutStream> realOutStream; | |
50 | |
51 UInt32 index = _startIndex + _currentIndex; | |
52 RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); | |
53 | |
54 _outStreamWithHashSpec->SetStream(realOutStream); | |
55 _outStreamWithHashSpec->Init(_checkCrc); | |
56 if (askMode == NArchive::NExtract::NAskMode::kExtract && | |
57 (!realOutStream)) | |
58 { | |
59 const CFileItem &fi = _archiveDatabase->Files[index]; | |
60 if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir) | |
61 askMode = NArchive::NExtract::NAskMode::kSkip; | |
62 } | |
63 return _extractCallback->PrepareOperation(askMode); | |
64 } | |
65 | |
66 HRESULT CFolderOutStream::WriteEmptyFiles() | |
67 { | |
68 for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) | |
69 { | |
70 UInt32 index = _startIndex + _currentIndex; | |
71 const CFileItem &fi = _archiveDatabase->Files[index]; | |
72 if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0) | |
73 return S_OK; | |
74 RINOK(OpenFile()); | |
75 RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); | |
76 _outStreamWithHashSpec->ReleaseStream(); | |
77 } | |
78 return S_OK; | |
79 } | |
80 | |
81 STDMETHODIMP CFolderOutStream::Write(const void *data, | |
82 UInt32 size, UInt32 *processedSize) | |
83 { | |
84 UInt32 realProcessedSize = 0; | |
85 while(_currentIndex < _extractStatuses->Size()) | |
86 { | |
87 if (_fileIsOpen) | |
88 { | |
89 UInt32 index = _startIndex + _currentIndex; | |
90 const CFileItem &fi = _archiveDatabase->Files[index]; | |
91 UInt64 fileSize = fi.Size; | |
92 | |
93 UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, | |
94 UInt64(size - realProcessedSize)); | |
95 | |
96 UInt32 processedSizeLocal; | |
97 RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, | |
98 numBytesToWrite, &processedSizeLocal)); | |
99 | |
100 _filePos += processedSizeLocal; | |
101 realProcessedSize += processedSizeLocal; | |
102 if (_filePos == fileSize) | |
103 { | |
104 bool digestsAreEqual; | |
105 if (fi.CrcDefined && _checkCrc) | |
106 digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC(); | |
107 else | |
108 digestsAreEqual = true; | |
109 | |
110 RINOK(_extractCallback->SetOperationResult( | |
111 digestsAreEqual ? | |
112 NArchive::NExtract::NOperationResult::kOK : | |
113 NArchive::NExtract::NOperationResult::kCRCError)); | |
114 _outStreamWithHashSpec->ReleaseStream(); | |
115 _fileIsOpen = false; | |
116 _currentIndex++; | |
117 } | |
118 if (realProcessedSize == size) | |
119 { | |
120 if (processedSize != NULL) | |
121 *processedSize = realProcessedSize; | |
122 return WriteEmptyFiles(); | |
123 } | |
124 } | |
125 else | |
126 { | |
127 RINOK(OpenFile()); | |
128 _fileIsOpen = true; | |
129 _filePos = 0; | |
130 } | |
131 } | |
132 if (processedSize != NULL) | |
133 *processedSize = size; | |
134 return S_OK; | |
135 } | |
136 | |
137 HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) | |
138 { | |
139 while(_currentIndex < _extractStatuses->Size()) | |
140 { | |
141 if (_fileIsOpen) | |
142 { | |
143 RINOK(_extractCallback->SetOperationResult(resultEOperationResult)); | |
144 _outStreamWithHashSpec->ReleaseStream(); | |
145 _fileIsOpen = false; | |
146 _currentIndex++; | |
147 } | |
148 else | |
149 { | |
150 RINOK(OpenFile()); | |
151 _fileIsOpen = true; | |
152 } | |
153 } | |
154 return S_OK; | |
155 } | |
156 | |
157 HRESULT CFolderOutStream::WasWritingFinished() | |
158 { | |
159 if (_currentIndex == _extractStatuses->Size()) | |
160 return S_OK; | |
161 return E_FAIL; | |
162 } | |
163 | |
164 }} |