1 // 7zFolderOutStream.cpp
5 #include "7zFolderOutStream.h"
10 CFolderOutStream::CFolderOutStream()
12 _outStreamWithHashSpec
= new COutStreamWithCRC
;
13 _outStreamWithHash
= _outStreamWithHashSpec
;
16 HRESULT
CFolderOutStream::Init(
17 const CArchiveDatabaseEx
*archiveDatabase
,
20 const CBoolVector
*extractStatuses
,
21 IArchiveExtractCallback
*extractCallback
,
24 _archiveDatabase
= archiveDatabase
;
25 _ref2Offset
= ref2Offset
;
26 _startIndex
= startIndex
;
28 _extractStatuses
= extractStatuses
;
29 _extractCallback
= extractCallback
;
34 return WriteEmptyFiles();
37 HRESULT
CFolderOutStream::OpenFile()
40 if((*_extractStatuses
)[_currentIndex
])
42 NArchive::NExtract::NAskMode::kTest
:
43 NArchive::NExtract::NAskMode::kExtract
;
45 askMode
= NArchive::NExtract::NAskMode::kSkip
;
46 CMyComPtr
<ISequentialOutStream
> realOutStream
;
48 UInt32 index
= _startIndex
+ _currentIndex
;
49 RINOK(_extractCallback
->GetStream(_ref2Offset
+ index
, &realOutStream
, askMode
));
51 _outStreamWithHashSpec
->Init(realOutStream
);
52 if (askMode
== NArchive::NExtract::NAskMode::kExtract
&&
55 const CFileItem
&fileInfo
= _archiveDatabase
->Files
[index
];
56 if (!fileInfo
.IsAnti
&& !fileInfo
.IsDirectory
)
57 askMode
= NArchive::NExtract::NAskMode::kSkip
;
59 return _extractCallback
->PrepareOperation(askMode
);
62 HRESULT
CFolderOutStream::WriteEmptyFiles()
64 for(;_currentIndex
< _extractStatuses
->Size(); _currentIndex
++)
66 UInt32 index
= _startIndex
+ _currentIndex
;
67 const CFileItem
&fileInfo
= _archiveDatabase
->Files
[index
];
68 if (!fileInfo
.IsAnti
&& !fileInfo
.IsDirectory
&& fileInfo
.UnPackSize
!= 0)
71 RINOK(_extractCallback
->SetOperationResult(
72 NArchive::NExtract::NOperationResult::kOK
));
73 _outStreamWithHashSpec
->ReleaseStream();
78 STDMETHODIMP
CFolderOutStream::Write(const void *data
,
79 UInt32 size
, UInt32
*processedSize
)
81 UInt32 realProcessedSize
= 0;
82 while(_currentIndex
< _extractStatuses
->Size())
86 UInt32 index
= _startIndex
+ _currentIndex
;
87 const CFileItem
&fileInfo
= _archiveDatabase
->Files
[index
];
88 UInt64 fileSize
= fileInfo
.UnPackSize
;
90 UInt32 numBytesToWrite
= (UInt32
)MyMin(fileSize
- _filePos
,
91 UInt64(size
- realProcessedSize
));
93 UInt32 processedSizeLocal
;
94 RINOK(_outStreamWithHash
->Write((const Byte
*)data
+ realProcessedSize
,
95 numBytesToWrite
, &processedSizeLocal
));
97 _filePos
+= processedSizeLocal
;
98 realProcessedSize
+= processedSizeLocal
;
99 if (_filePos
== fileSize
)
101 bool digestsAreEqual
;
102 if (fileInfo
.IsFileCRCDefined
)
103 digestsAreEqual
= fileInfo
.FileCRC
== _outStreamWithHashSpec
->GetCRC();
105 digestsAreEqual
= true;
107 RINOK(_extractCallback
->SetOperationResult(
109 NArchive::NExtract::NOperationResult::kOK
:
110 NArchive::NExtract::NOperationResult::kCRCError
));
111 _outStreamWithHashSpec
->ReleaseStream();
115 if (realProcessedSize
== size
)
117 if (processedSize
!= NULL
)
118 *processedSize
= realProcessedSize
;
119 return WriteEmptyFiles();
129 if (processedSize
!= NULL
)
130 *processedSize
= size
;
134 HRESULT
CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult
)
136 while(_currentIndex
< _extractStatuses
->Size())
140 RINOK(_extractCallback
->SetOperationResult(resultEOperationResult
));
141 _outStreamWithHashSpec
->ReleaseStream();
154 HRESULT
CFolderOutStream::WasWritingFinished()
156 if (_currentIndex
== _extractStatuses
->Size())