Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / other-licenses / 7zstub / src / 7zip / Archive / 7z / 7zFolderOutStream.cpp
blob94afc6905e5d720427d4bfbcfcc92ce2faa177dc
1 // 7zFolderOutStream.cpp
3 #include "StdAfx.h"
5 #include "7zFolderOutStream.h"
7 namespace NArchive {
8 namespace N7z {
10 CFolderOutStream::CFolderOutStream()
12 _outStreamWithHashSpec = new COutStreamWithCRC;
13 _outStreamWithHash = _outStreamWithHashSpec;
16 HRESULT CFolderOutStream::Init(
17 const CArchiveDatabaseEx *archiveDatabase,
18 UInt32 ref2Offset,
19 UInt32 startIndex,
20 const CBoolVector *extractStatuses,
21 IArchiveExtractCallback *extractCallback,
22 bool testMode)
24 _archiveDatabase = archiveDatabase;
25 _ref2Offset = ref2Offset;
26 _startIndex = startIndex;
28 _extractStatuses = extractStatuses;
29 _extractCallback = extractCallback;
30 _testMode = testMode;
32 _currentIndex = 0;
33 _fileIsOpen = false;
34 return WriteEmptyFiles();
37 HRESULT CFolderOutStream::OpenFile()
39 Int32 askMode;
40 if((*_extractStatuses)[_currentIndex])
41 askMode = _testMode ?
42 NArchive::NExtract::NAskMode::kTest :
43 NArchive::NExtract::NAskMode::kExtract;
44 else
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 &&
53 (!realOutStream))
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)
69 return S_OK;
70 RINOK(OpenFile());
71 RINOK(_extractCallback->SetOperationResult(
72 NArchive::NExtract::NOperationResult::kOK));
73 _outStreamWithHashSpec->ReleaseStream();
75 return S_OK;
78 STDMETHODIMP CFolderOutStream::Write(const void *data,
79 UInt32 size, UInt32 *processedSize)
81 UInt32 realProcessedSize = 0;
82 while(_currentIndex < _extractStatuses->Size())
84 if (_fileIsOpen)
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();
104 else
105 digestsAreEqual = true;
107 RINOK(_extractCallback->SetOperationResult(
108 digestsAreEqual ?
109 NArchive::NExtract::NOperationResult::kOK :
110 NArchive::NExtract::NOperationResult::kCRCError));
111 _outStreamWithHashSpec->ReleaseStream();
112 _fileIsOpen = false;
113 _currentIndex++;
115 if (realProcessedSize == size)
117 if (processedSize != NULL)
118 *processedSize = realProcessedSize;
119 return WriteEmptyFiles();
122 else
124 RINOK(OpenFile());
125 _fileIsOpen = true;
126 _filePos = 0;
129 if (processedSize != NULL)
130 *processedSize = size;
131 return S_OK;
134 HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
136 while(_currentIndex < _extractStatuses->Size())
138 if (_fileIsOpen)
140 RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
141 _outStreamWithHashSpec->ReleaseStream();
142 _fileIsOpen = false;
143 _currentIndex++;
145 else
147 RINOK(OpenFile());
148 _fileIsOpen = true;
151 return S_OK;
154 HRESULT CFolderOutStream::WasWritingFinished()
156 if (_currentIndex == _extractStatuses->Size())
157 return S_OK;
158 return E_FAIL;