Mercurial > vba-linux
view 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 |
line wrap: on
line source
1 // 7zFolderOutStream.cpp3 #include "StdAfx.h"5 #include "7zFolderOutStream.h"7 namespace NArchive {8 namespace N7z {10 CFolderOutStream::CFolderOutStream()11 {12 _outStreamWithHashSpec = new COutStreamWithCRC;13 _outStreamWithHash = _outStreamWithHashSpec;14 }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;29 _extractStatuses = extractStatuses;30 _extractCallback = extractCallback;31 _testMode = testMode;33 _checkCrc = checkCrc;35 _currentIndex = 0;36 _fileIsOpen = false;37 return WriteEmptyFiles();38 }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 else48 askMode = NArchive::NExtract::NAskMode::kSkip;49 CMyComPtr<ISequentialOutStream> realOutStream;51 UInt32 index = _startIndex + _currentIndex;52 RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));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 }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 }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;93 UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,94 UInt64(size - realProcessedSize));96 UInt32 processedSizeLocal;97 RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,98 numBytesToWrite, &processedSizeLocal));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 else108 digestsAreEqual = true;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 else126 {127 RINOK(OpenFile());128 _fileIsOpen = true;129 _filePos = 0;130 }131 }132 if (processedSize != NULL)133 *processedSize = size;134 return S_OK;135 }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 else149 {150 RINOK(OpenFile());151 _fileIsOpen = true;152 }153 }154 return S_OK;155 }157 HRESULT CFolderOutStream::WasWritingFinished()158 {159 if (_currentIndex == _extractStatuses->Size())160 return S_OK;161 return E_FAIL;162 }164 }}