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