diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2007-06-26 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:52 +0300 |
commit | fd8b1d78b496fe38193bf8c5e86af3b43f0b022d (patch) | |
tree | 5b1e3812ed4d8b6037e5035faf3b638849f618e2 /CPP/7zip/Archive/Common | |
parent | 0b33f700a66fcf7f55f92b92e0b3e5c7014d769a (diff) |
4.48 beta
Diffstat (limited to 'CPP/7zip/Archive/Common')
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer.cpp | 19 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer.h | 32 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer2.cpp | 6 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer2.h | 20 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer2MT.cpp | 257 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer2MT.h | 123 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixerMT.cpp | 97 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixerMT.h | 68 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/HandlerOut.cpp | 609 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/HandlerOut.h | 84 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/ItemNameUtils.h | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/MultiStream.h | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/ParseProperties.cpp | 33 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/ParseProperties.h | 3 |
14 files changed, 1051 insertions, 304 deletions
diff --git a/CPP/7zip/Archive/Common/CoderMixer.cpp b/CPP/7zip/Archive/Common/CoderMixer.cpp new file mode 100755 index 00000000..db626fe1 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer.cpp @@ -0,0 +1,19 @@ +// CoderMixer.cpp + +#include "StdAfx.h" + +#include "CoderMixer.h" + +namespace NCoderMixer { + +void CCoderInfo::SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + InSizeAssigned = (inSize != 0); + if (InSizeAssigned) + InSizeValue = *inSize; + OutSizeAssigned = (outSize != 0); + if (OutSizeAssigned) + OutSizeValue = *outSize; +} + +} diff --git a/CPP/7zip/Archive/Common/CoderMixer.h b/CPP/7zip/Archive/Common/CoderMixer.h new file mode 100755 index 00000000..6379dd80 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer.h @@ -0,0 +1,32 @@ +// CoderMixer.h + +#ifndef __CODER_MIXER_H +#define __CODER_MIXER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCoderMixer { + +struct CCoderInfo +{ + CMyComPtr<ICompressCoder> Coder; + CMyComPtr<ISequentialInStream> InStream; + CMyComPtr<ISequentialOutStream> OutStream; + CMyComPtr<ICompressProgressInfo> Progress; + + UInt64 InSizeValue; + UInt64 OutSizeValue; + bool InSizeAssigned; + bool OutSizeAssigned; + + void ReInit() + { + InSizeAssigned = OutSizeAssigned = false; + } + + void SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize); +}; + +} +#endif diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp index 8f46e985..d11e9e60 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -4,7 +4,7 @@ #include "CoderMixer2.h" -namespace NCoderMixer2 { +namespace NCoderMixer { CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): _srcBindInfo(srcBindInfo) @@ -81,7 +81,7 @@ void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); } -CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): +CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): NumInStreams(numInStreams), NumOutStreams(numOutStreams) { @@ -111,7 +111,7 @@ static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, } } -void CCoderInfo::SetCoderInfo(const UInt64 **inSizes, +void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) { SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h index 597a7b60..be68c680 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2.h +++ b/CPP/7zip/Archive/Common/CoderMixer2.h @@ -3,12 +3,12 @@ #ifndef __CODER_MIXER2_H #define __CODER_MIXER2_H -#include "../../../Common/Vector.h" +#include "../../../Common/MyVector.h" #include "../../../Common/Types.h" #include "../../../Common/MyCom.h" #include "../../ICoder.h" -namespace NCoderMixer2 { +namespace NCoderMixer { struct CBindPair { @@ -127,7 +127,7 @@ struct CBindInfo class CBindReverseConverter { UInt32 _numSrcOutStreams; - NCoderMixer2::CBindInfo _srcBindInfo; + NCoderMixer::CBindInfo _srcBindInfo; CRecordVector<UInt32> _srcInToDestOutMap; CRecordVector<UInt32> _srcOutToDestInMap; CRecordVector<UInt32> _destInToSrcOutMap; @@ -135,11 +135,11 @@ public: UInt32 NumSrcInStreams; CRecordVector<UInt32> DestOutToSrcInMap; - CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo); - void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo); + CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo); + void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo); }; -struct CCoderInfo +struct CCoderInfo2 { CMyComPtr<ICompressCoder> Coder; CMyComPtr<ICompressCoder2> Coder2; @@ -151,8 +151,14 @@ struct CCoderInfo CRecordVector<const UInt64 *> InSizePointers; CRecordVector<const UInt64 *> OutSizePointers; - CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); + CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams); void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); + + HRESULT QueryInterface(REFGUID iid, void** pp) const + { + IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2; + return p->QueryInterface(iid, pp); + } }; class CCoderMixer2 diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index 8a37a10d..bff689dd 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -3,16 +3,11 @@ #include "StdAfx.h" #include "CoderMixer2MT.h" -#include "CrossThreadProgress.h" -using namespace NWindows; -using namespace NSynchronization; +namespace NCoderMixer { -namespace NCoderMixer2 { - -CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): - ExitEvent(NULL), - CCoderInfo(numInStreams, numOutStreams) +CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): + CCoderInfo2(numInStreams, numOutStreams) { InStreams.Reserve(NumInStreams); InStreamPointers.Reserve(NumInStreams); @@ -20,62 +15,38 @@ CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): OutStreamPointers.Reserve(NumOutStreams); } -class CCoderInfoFlusher2 +void CCoder2::Execute() { Code(NULL); } + +void CCoder2::Code(ICompressProgressInfo *progress) { - CThreadCoderInfo *m_CoderInfo; -public: - CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {} - ~CCoderInfoFlusher2() + InStreamPointers.Clear(); + OutStreamPointers.Clear(); + UInt32 i; + for (i = 0; i < NumInStreams; i++) { - int i; - for (i = 0; i < m_CoderInfo->InStreams.Size(); i++) - m_CoderInfo->InStreams[i].Release(); - for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++) - m_CoderInfo->OutStreams[i].Release(); - m_CoderInfo->CompressionCompletedEvent.Set(); + if (InSizePointers[i] != NULL) + InSizePointers[i] = &InSizes[i]; + InStreamPointers.Add(InStreams[i]); } -}; - -bool CThreadCoderInfo::WaitAndCode() -{ - HANDLE events[2] = { ExitEvent, CompressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - + for (i = 0; i < NumOutStreams; i++) { - InStreamPointers.Clear(); - OutStreamPointers.Clear(); - UInt32 i; - for (i = 0; i < NumInStreams; i++) - { - if (InSizePointers[i] != NULL) - InSizePointers[i] = &InSizes[i]; - InStreamPointers.Add(InStreams[i]); - } - for (i = 0; i < NumOutStreams; i++) - { - if (OutSizePointers[i] != NULL) - OutSizePointers[i] = &OutSizes[i]; - OutStreamPointers.Add(OutStreams[i]); - } - CCoderInfoFlusher2 coderInfoFlusher(this); - if (Coder) - Result = Coder->Code(InStreamPointers[0], - OutStreamPointers[0], - InSizePointers[0], - OutSizePointers[0], - Progress); - else - Result = Coder2->Code(&InStreamPointers.Front(), - &InSizePointers.Front(), - NumInStreams, - &OutStreamPointers.Front(), - &OutSizePointers.Front(), - NumOutStreams, - Progress); + if (OutSizePointers[i] != NULL) + OutSizePointers[i] = &OutSizes[i]; + OutStreamPointers.Add(OutStreams[i]); + } + if (Coder) + Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], + InSizePointers[0], OutSizePointers[0], progress); + else + Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams, + &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress); + { + int i; + for (i = 0; i < InStreams.Size(); i++) + InStreams[i].Release(); + for (i = 0; i < OutStreams.Size(); i++) + OutStreams[i].Release(); } - return true; } static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, @@ -99,54 +70,15 @@ static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, } -void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes, - const UInt64 **outSizes, ICompressProgressInfo *progress) +void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) { - Progress = progress; SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); } -static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo) -{ - for (;;) - { - if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode()) - return 0; - } -} - ////////////////////////////////////// // CCoderMixer2MT -static THREAD_FUNC_DECL MainCoderThread(void *threadCoderInfo) -{ - for (;;) - { - if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode()) - return 0; - } -} - -CCoderMixer2MT::CCoderMixer2MT() -{ - if (CreateEvents() != S_OK) - throw 271824; - if (_mainThread.Create(MainCoderThread, this) != S_OK) - throw 271825; -} - -CCoderMixer2MT::~CCoderMixer2MT() -{ - _exitEvent.Set(); - _mainThread.Wait(); - for(int i = 0; i < _threads.Size(); i++) - { - _threads[i].Wait(); - _threads[i].Close(); - } -} - HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) { _bindInfo = bindInfo; @@ -161,48 +93,23 @@ HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) void CCoderMixer2MT::AddCoderCommon() { - int index = _coderInfoVector.Size(); - const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index]; - - CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams, - CoderStreamsInfo.NumOutStreams); - _coderInfoVector.Add(threadCoderInfo); - CThreadCoderInfo *tci = &_coderInfoVector.Back(); - tci->CreateEvents(); - tci->ExitEvent = _exitEvent; - - NWindows::CThread newThread; - _threads.Add(newThread); - if (_threads.Back().Create(CoderThread, tci) != S_OK) - throw 271824; + const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()]; + CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams); + _coders.Add(threadCoderInfo); } void CCoderMixer2MT::AddCoder(ICompressCoder *coder) { AddCoderCommon(); - _coderInfoVector.Back().Coder = coder; + _coders.Back().Coder = coder; } void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) { AddCoderCommon(); - _coderInfoVector.Back().Coder2 = coder; + _coders.Back().Coder2 = coder; } -/* -void CCoderMixer2MT::FinishAddingCoders() -{ - for(int i = 0; i < _coderInfoVector.Size(); i++) - { - DWORD id; - HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, - &_coderInfoVector[i], 0, &id); - if (newThread == 0) - throw 271824; - _threads.Add(newThread); - } -} -*/ void CCoderMixer2MT::ReInit() { @@ -211,17 +118,16 @@ void CCoderMixer2MT::ReInit() } -STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams, - ISequentialOutStream **outStreams) +HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) { /* - if (_coderInfoVector.Size() != _bindInfo.Coders.Size()) + if (_coders.Size() != _bindInfo.Coders.Size()) throw 0; */ int i; - for(i = 0; i < _coderInfoVector.Size(); i++) + for(i = 0; i < _coders.Size(); i++) { - CThreadCoderInfo &coderInfo = _coderInfoVector[i]; + CCoder2 &coderInfo = _coders[i]; const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; coderInfo.InStreams.Clear(); UInt32 j; @@ -241,45 +147,26 @@ STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams, _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex); _streamBinders[i].CreateStreams( - &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex], - &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]); + &_coders[inCoderIndex].InStreams[inCoderStreamIndex], + &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); } for(i = 0; i < _bindInfo.InStreams.Size(); i++) { UInt32 inCoderIndex, inCoderStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); - _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; + _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; } for(i = 0; i < _bindInfo.OutStreams.Size(); i++) { UInt32 outCoderIndex, outCoderStreamIndex; _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); - _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; + _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; } return S_OK; } - -bool CCoderMixer2MT::MyCode() -{ - HANDLE events[2] = { _exitEvent, _startCompressingEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - - int i; - for(i = 0; i < _coderInfoVector.Size(); i++) - _coderInfoVector[i].CompressEvent.Set(); - for (i = 0; i < _coderInfoVector.Size(); i++) - _coderInfoVector[i].CompressionCompletedEvent.Lock(); - - _compressingFinishedEvent.Set(); - return true; -} - - STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams, @@ -294,56 +181,48 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, Init(inStreams, outStreams); - _compressingFinishedEvent.Reset(); // ? - - CCrossThreadProgress *progressSpec = new CCrossThreadProgress; - CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec; - RINOK(progressSpec->Create()); - progressSpec->Init(); - _coderInfoVector[_progressCoderIndex].Progress = crossProgress; + int i; + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + { + RINOK(_coders[i].Create()); + } + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].Start(); - _startCompressingEvent.Set(); + _coders[_progressCoderIndex].Code(progress); + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].WaitFinish(); - for (;;) + for (i = 0; i < _coders.Size(); i++) { - HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - break; - if (progress != NULL) - progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize, - progressSpec->OutSize); - else - progressSpec->Result = S_OK; - progressSpec->WaitEvent.Set(); + HRESULT result = _coders[i].Result; + if (result == E_ABORT) + return result; } - - int i; - for(i = 0; i < _coderInfoVector.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { - HRESULT result = _coderInfoVector[i].Result; + HRESULT result = _coders[i].Result; if (result == S_FALSE) return result; } - for(i = 0; i < _coderInfoVector.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { - HRESULT result = _coderInfoVector[i].Result; + HRESULT result = _coders[i].Result; if (result != S_OK && result != E_FAIL) return result; } - for(i = 0; i < _coderInfoVector.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { - HRESULT result = _coderInfoVector[i].Result; + HRESULT result = _coders[i].Result; if (result != S_OK) return result; } return S_OK; } -UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const -{ - return _streamBinders[binderIndex].ProcessedSize; -} - } diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h index 67c0c8a5..3cd3282b 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.h +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h @@ -5,73 +5,55 @@ #include "CoderMixer2.h" #include "../../../Common/MyCom.h" -#include "../../../Windows/Thread.h" #include "../../Common/StreamBinder.h" +#include "../../Common/VirtThread.h" -namespace NCoderMixer2 { +namespace NCoderMixer { -// CreateEvents(); -// { -// SetCoderInfo() -// Init Streams -// set CompressEvent() -// wait CompressionCompletedEvent -// } - -struct CThreadCoderInfo: public CCoderInfo +struct CCoder2: public CCoderInfo2, public CVirtThread { - NWindows::NSynchronization::CAutoResetEvent CompressEvent; - HANDLE ExitEvent; - NWindows::NSynchronization::CAutoResetEvent CompressionCompletedEvent; - + HRESULT Result; CObjectVector< CMyComPtr<ISequentialInStream> > InStreams; CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams; - CRecordVector<ISequentialInStream *> InStreamPointers; - CRecordVector<ISequentialOutStream *> OutStreamPointers; - - CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr - HRESULT Result; + CRecordVector<ISequentialInStream*> InStreamPointers; + CRecordVector<ISequentialOutStream*> OutStreamPointers; - CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); - void SetCoderInfo(const UInt64 **inSizes, - const UInt64 **outSizes, ICompressProgressInfo *progress); - bool WaitAndCode(); - HRes CreateEvents() - { - RINOK(CompressEvent.CreateIfNotCreated()); - return CompressionCompletedEvent.CreateIfNotCreated(); - } + CCoder2(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); + virtual void Execute(); + void Code(ICompressProgressInfo *progress); }; -// SetBindInfo() -// for each coder -// { -// AddCoder[2]() -// } -// -// for each file -// { -// ReInit() -// for each coder -// { -// SetCoderInfo -// } -// SetProgressIndex(UInt32 coderIndex); -// Code -// } - +/* + SetBindInfo() + for each coder + AddCoder[2]() + SetProgressIndex(UInt32 coderIndex); + + for each file + { + ReInit() + for each coder + SetCoderInfo + Code + } +*/ class CCoderMixer2MT: public ICompressCoder2, public CCoderMixer2, public CMyUnknownImp { - MY_UNKNOWN_IMP + CBindInfo _bindInfo; + CObjectVector<CStreamBinder> _streamBinders; + int _progressCoderIndex; + void AddCoderCommon(); + HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams); public: - STDMETHOD(Init)(ISequentialInStream **inStreams, - ISequentialOutStream **outStreams); + CObjectVector<CCoder2> _coders; + MY_UNKNOWN_IMP STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, @@ -81,50 +63,17 @@ public: UInt32 numOutStreams, ICompressProgressInfo *progress); - - CCoderMixer2MT(); - ~CCoderMixer2MT(); - void AddCoderCommon(); + HRESULT SetBindInfo(const CBindInfo &bindInfo); void AddCoder(ICompressCoder *coder); void AddCoder2(ICompressCoder2 *coder); + void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; } void ReInit(); void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) - { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); } - void SetProgressCoderIndex(UInt32 coderIndex) - { _progressCoderIndex = coderIndex; } - - - UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; - - - bool MyCode(); - -private: - CBindInfo _bindInfo; - CObjectVector<CStreamBinder> _streamBinders; - CObjectVector<CThreadCoderInfo> _coderInfoVector; - CRecordVector<NWindows::CThread> _threads; - NWindows::CThread _mainThread; - - NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent; - NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent; - - NWindows::NSynchronization::CManualResetEvent _exitEvent; - UInt32 _progressCoderIndex; - - HRes CreateEvents() - { - RINOK(_startCompressingEvent.CreateIfNotCreated()); - RINOK(_compressingFinishedEvent.CreateIfNotCreated()); - return _exitEvent.CreateIfNotCreated(); - } - -public: - HRESULT SetBindInfo(const CBindInfo &bindInfo); - + { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); } + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const + { return _streamBinders[binderIndex].ProcessedSize; } }; } #endif - diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.cpp b/CPP/7zip/Archive/Common/CoderMixerMT.cpp new file mode 100755 index 00000000..ad6e12d8 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixerMT.cpp @@ -0,0 +1,97 @@ +// CoderMixerMT.cpp + +#include "StdAfx.h" + +#include "CoderMixerMT.h" + +namespace NCoderMixer { + +void CCoder::Execute() { Code(NULL); } + +void CCoder::Code(ICompressProgressInfo *progress) +{ + Result = Coder->Code(InStream, OutStream, + InSizeAssigned ? &InSizeValue : NULL, + OutSizeAssigned ? &OutSizeValue : NULL, + progress); + InStream.Release(); + OutStream.Release(); +} + +void CCoderMixerMT::AddCoder(ICompressCoder *coder) +{ + _coders.Add(CCoder()); + _coders.Back().Coder = coder; +} + +void CCoderMixerMT::ReInit() +{ + for(int i = 0; i < _coders.Size(); i++) + _coders[i].ReInit(); +} + +STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + _coders.Front().InStream = inStream; + int i; + _coders.Back().OutStream = outStream; + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + { + RINOK(_coders[i].Create()); + } + + while (_streamBinders.Size() + 1 < _coders.Size()) + { + _streamBinders.Add(CStreamBinder()); + int i = _streamBinders.Size() - 1; + CStreamBinder &sb = _streamBinders.Back(); + RINOK(sb.CreateEvents()); + sb.CreateStreams(&_coders[i + 1].InStream, &_coders[i].OutStream); + } + + for(i = 0; i < _streamBinders.Size(); i++) + _streamBinders[i].ReInit(); + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].Start(); + + _coders[_progressCoderIndex].Code(progress); + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].WaitFinish(); + + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result == E_ABORT) + return result; + } + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result == S_FALSE) + return result; + } + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK && result != E_FAIL) + return result; + } + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK) + return result; + } + return S_OK; +} + +} diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.h b/CPP/7zip/Archive/Common/CoderMixerMT.h new file mode 100755 index 00000000..a2250e8a --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixerMT.h @@ -0,0 +1,68 @@ +// CoderMixerMT.h + +#ifndef __CODER_MIXER_MT_H +#define __CODER_MIXER_MT_H + +#include "../../../Common/Vector.h" +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../Common/StreamBinder.h" +#include "../../Common/VirtThread.h" +#include "CoderMixer.h" + +namespace NCoderMixer { + +struct CCoder: public CCoderInfo, public CVirtThread +{ + HRESULT Result; + + virtual void Execute(); + void Code(ICompressProgressInfo *progress); +}; + +/* + for each coder + AddCoder() + SetProgressIndex(UInt32 coderIndex); + + for each file + { + ReInit() + for each coder + SetCoderInfo + Code + } +*/ + + +class CCoderMixerMT: + public ICompressCoder, + public CMyUnknownImp +{ + CObjectVector<CStreamBinder> _streamBinders; + int _progressCoderIndex; + +public: + CObjectVector<CCoder> _coders; + MY_UNKNOWN_IMP + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + void AddCoder(ICompressCoder *coder); + void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; } + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 *inSize, const UInt64 *outSize) + { _coders[coderIndex].SetCoderInfo(inSize, outSize); } + + /* + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const + { return _streamBinders[binderIndex].ProcessedSize; } + */ +}; + +} +#endif diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp new file mode 100755 index 00000000..7c214c3c --- /dev/null +++ b/CPP/7zip/Archive/Common/HandlerOut.cpp @@ -0,0 +1,609 @@ +// HandlerOutCommon.cpp + +#include "StdAfx.h" + +#include "HandlerOut.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Common/StringToInt.h" +#include "../../ICoder.h" +#include "../Common/ParseProperties.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +using namespace NWindows; + +namespace NArchive { + +static const wchar_t *kCopyMethod = L"Copy"; +static const wchar_t *kLZMAMethodName = L"LZMA"; +static const wchar_t *kLZMA2MethodName = L"LZMA2"; +static const wchar_t *kBZip2MethodName = L"BZip2"; +static const wchar_t *kPpmdMethodName = L"PPMd"; +static const wchar_t *kDeflateMethodName = L"Deflate"; +static const wchar_t *kDeflate64MethodName = L"Deflate64"; + +static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; +static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; + +static const UInt32 kLzmaAlgoX1 = 0; +static const UInt32 kLzmaAlgoX5 = 1; + +static const UInt32 kLzmaDicSizeX1 = 1 << 16; +static const UInt32 kLzmaDicSizeX3 = 1 << 20; +static const UInt32 kLzmaDicSizeX5 = 1 << 24; +static const UInt32 kLzmaDicSizeX7 = 1 << 25; +static const UInt32 kLzmaDicSizeX9 = 1 << 26; + +static const UInt32 kLzmaFastBytesX1 = 32; +static const UInt32 kLzmaFastBytesX7 = 64; + +static const UInt32 kPpmdMemSizeX1 = (1 << 22); +static const UInt32 kPpmdMemSizeX5 = (1 << 24); +static const UInt32 kPpmdMemSizeX7 = (1 << 26); +static const UInt32 kPpmdMemSizeX9 = (192 << 20); + +static const UInt32 kPpmdOrderX1 = 4; +static const UInt32 kPpmdOrderX5 = 6; +static const UInt32 kPpmdOrderX7 = 16; +static const UInt32 kPpmdOrderX9 = 32; + +static const UInt32 kDeflateAlgoX1 = 0; +static const UInt32 kDeflateAlgoX5 = 1; + +static const UInt32 kDeflateFastBytesX1 = 32; +static const UInt32 kDeflateFastBytesX7 = 64; +static const UInt32 kDeflateFastBytesX9 = 128; + +static const UInt32 kDeflatePassesX1 = 1; +static const UInt32 kDeflatePassesX7 = 3; +static const UInt32 kDeflatePassesX9 = 10; + +static const UInt32 kBZip2NumPassesX1 = 1; +static const UInt32 kBZip2NumPassesX7 = 2; +static const UInt32 kBZip2NumPassesX9 = 7; + +static const UInt32 kBZip2DicSizeX1 = 100000; +static const UInt32 kBZip2DicSizeX3 = 500000; +static const UInt32 kBZip2DicSizeX5 = 900000; + +static const wchar_t *kDefaultMethodName = kLZMAMethodName; + +static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; +static const UInt32 kDictionaryForHeaders = 1 << 20; +static const UInt32 kNumFastBytesForHeaders = 273; +static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5; + +static bool AreEqual(const UString &methodName, const wchar_t *s) + { return (methodName.CompareNoCase(s) == 0); } + +static inline bool IsLZMAMethod(const UString &methodName) +{ + return + AreEqual(methodName, kLZMAMethodName) || + AreEqual(methodName, kLZMA2MethodName); +} + +static inline bool IsBZip2Method(const UString &methodName) + { return AreEqual(methodName, kBZip2MethodName); } + +static inline bool IsPpmdMethod(const UString &methodName) + { return AreEqual(methodName, kPpmdMethodName); } + +static inline bool IsDeflateMethod(const UString &methodName) +{ + return + AreEqual(methodName, kDeflateMethodName) || + AreEqual(methodName, kDeflate64MethodName); +} + +struct CNameToPropID +{ + PROPID PropID; + VARTYPE VarType; + const wchar_t *Name; +}; + +CNameToPropID g_NameToPropID[] = +{ + { NCoderPropID::kOrder, VT_UI4, L"O" }, + { NCoderPropID::kPosStateBits, VT_UI4, L"PB" }, + { NCoderPropID::kLitContextBits, VT_UI4, L"LC" }, + { NCoderPropID::kLitPosBits, VT_UI4, L"LP" }, + { NCoderPropID::kEndMarker, VT_BOOL, L"eos" }, + + { NCoderPropID::kNumPasses, VT_UI4, L"Pass" }, + { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" }, + { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" }, + { NCoderPropID::kAlgorithm, VT_UI4, L"a" }, + { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, + { NCoderPropID::kNumThreads, VT_UI4, L"mt" } +}; + +static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp) +{ + if (varType == srcProp.vt) + { + destProp = srcProp; + return true; + } + if (varType == VT_UI1) + { + if (srcProp.vt == VT_UI4) + { + UInt32 value = srcProp.ulVal; + if (value > 0xFF) + return false; + destProp = (Byte)value; + return true; + } + } + else if (varType == VT_BOOL) + { + bool res; + if (SetBoolProperty(res, srcProp) != S_OK) + return false; + destProp = res; + return true; + } + return false; +} + +static int FindPropIdFromStringName(const UString &name) +{ + for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++) + if (name.CompareNoCase(g_NameToPropID[i].Name) == 0) + return i; + return -1; +} + +static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, + const NWindows::NCOM::CPropVariant &value) +{ + for (int j = 0; j < oneMethodInfo.Properties.Size(); j++) + if (oneMethodInfo.Properties[j].Id == propID) + return; + CProp property; + property.Id = propID; + property.Value = value; + oneMethodInfo.Properties.Add(property); +} + +void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ) +{ + UInt32 level = _level; + if (oneMethodInfo.MethodName.IsEmpty()) + oneMethodInfo.MethodName = kDefaultMethodName; + + if (IsLZMAMethod(oneMethodInfo.MethodName)) + { + UInt32 dicSize = + (level >= 9 ? kLzmaDicSizeX9 : + (level >= 7 ? kLzmaDicSizeX7 : + (level >= 5 ? kLzmaDicSizeX5 : + (level >= 3 ? kLzmaDicSizeX3 : + kLzmaDicSizeX1)))); + + UInt32 algo = + (level >= 5 ? kLzmaAlgoX5 : + kLzmaAlgoX1); + + UInt32 fastBytes = + (level >= 7 ? kLzmaFastBytesX7 : + kLzmaFastBytesX1); + + const wchar_t *matchFinder = + (level >= 5 ? kLzmaMatchFinderX5 : + kLzmaMatchFinderX1); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder); + #ifdef COMPRESS_MT + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + #endif + } + else if (IsDeflateMethod(oneMethodInfo.MethodName)) + { + UInt32 fastBytes = + (level >= 9 ? kDeflateFastBytesX9 : + (level >= 7 ? kDeflateFastBytesX7 : + kDeflateFastBytesX1)); + + UInt32 numPasses = + (level >= 9 ? kDeflatePassesX9 : + (level >= 7 ? kDeflatePassesX7 : + kDeflatePassesX1)); + + UInt32 algo = + (level >= 5 ? kDeflateAlgoX5 : + kDeflateAlgoX1); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); + } + else if (IsBZip2Method(oneMethodInfo.MethodName)) + { + UInt32 numPasses = + (level >= 9 ? kBZip2NumPassesX9 : + (level >= 7 ? kBZip2NumPassesX7 : + kBZip2NumPassesX1)); + + UInt32 dicSize = + (level >= 5 ? kBZip2DicSizeX5 : + (level >= 3 ? kBZip2DicSizeX3 : + kBZip2DicSizeX1)); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + #ifdef COMPRESS_MT + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + #endif + } + else if (IsPpmdMethod(oneMethodInfo.MethodName)) + { + UInt32 useMemSize = + (level >= 9 ? kPpmdMemSizeX9 : + (level >= 7 ? kPpmdMemSizeX7 : + (level >= 5 ? kPpmdMemSizeX5 : + kPpmdMemSizeX1))); + + UInt32 order = + (level >= 9 ? kPpmdOrderX9 : + (level >= 7 ? kPpmdOrderX7 : + (level >= 5 ? kPpmdOrderX5 : + kPpmdOrderX1))); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order); + } +} + +static void SplitParams(const UString &srcString, UStringVector &subStrings) +{ + subStrings.Clear(); + UString name; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L':') + { + subStrings.Add(name); + name.Empty(); + } + else + name += c; + } + subStrings.Add(name); +} + +static void SplitParam(const UString ¶m, UString &name, UString &value) +{ + int eqPos = param.Find(L'='); + if (eqPos >= 0) + { + name = param.Left(eqPos); + value = param.Mid(eqPos + 1); + return; + } + for(int i = 0; i < param.Length(); i++) + { + wchar_t c = param[i]; + if (c >= L'0' && c <= L'9') + { + name = param.Left(i); + value = param.Mid(i); + return; + } + } + name = param; +} + +HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value) +{ + CProp property; + if ( + name.CompareNoCase(L"D") == 0 || + name.CompareNoCase(L"MEM") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(value, dicSize)); + if (name.CompareNoCase(L"D") == 0) + property.Id = NCoderPropID::kDictionarySize; + else + property.Id = NCoderPropID::kUsedMemorySize; + property.Value = dicSize; + oneMethodInfo.Properties.Add(property); + } + else + { + int index = FindPropIdFromStringName(name); + if (index < 0) + return E_INVALIDARG; + + const CNameToPropID &nameToPropID = g_NameToPropID[index]; + property.Id = nameToPropID.PropID; + + NCOM::CPropVariant propValue; + + if (nameToPropID.VarType == VT_BSTR) + propValue = value; + else if (nameToPropID.VarType == VT_BOOL) + { + bool res; + if (!StringToBool(value, res)) + return E_INVALIDARG; + propValue = res; + } + else + { + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Length()) + propValue = number; + else + propValue = value; + } + + if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value)) + return E_INVALIDARG; + + oneMethodInfo.Properties.Add(property); + } + return S_OK; +} + +HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString) +{ + UStringVector params; + SplitParams(srcString, params); + if (params.Size() > 0) + oneMethodInfo.MethodName = params[0]; + for (int i = 1; i < params.Size(); i++) + { + const UString ¶m = params[i]; + UString name, value; + SplitParam(param, name, value); + RINOK(SetParam(oneMethodInfo, name, value)); + } + return S_OK; +} + +HRESULT COutHandler::SetSolidSettings(const UString &s) +{ + bool res; + if (StringToBool(s, res)) + { + if (res) + InitSolid(); + else + _numSolidFiles = 1; + return S_OK; + } + UString s2 = s; + s2.MakeUpper(); + for (int i = 0; i < s2.Length();) + { + const wchar_t *start = ((const wchar_t *)s2) + i; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (start == end) + { + if (s2[i++] != 'E') + return E_INVALIDARG; + _solidExtension = true; + continue; + } + i += (int)(end - start); + if (i == s2.Length()) + return E_INVALIDARG; + wchar_t c = s2[i++]; + switch(c) + { + case 'F': + if (v < 1) + v = 1; + _numSolidFiles = v; + break; + case 'B': + _numSolidBytes = v; + _numSolidBytesDefined = true; + break; + case 'K': + _numSolidBytes = (v << 10); + _numSolidBytesDefined = true; + break; + case 'M': + _numSolidBytes = (v << 20); + _numSolidBytesDefined = true; + break; + case 'G': + _numSolidBytes = (v << 30); + _numSolidBytesDefined = true; + break; + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value) +{ + switch(value.vt) + { + case VT_EMPTY: + InitSolid(); + return S_OK; + case VT_BSTR: + return SetSolidSettings(value.bstrVal); + default: + return E_INVALIDARG; + } +} + +void COutHandler::Init() +{ + _removeSfxBlock = false; + _compressHeaders = true; + _encryptHeaders = false; + + WriteModified = true; + WriteCreated = false; + WriteAccessed = false; + + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors(); + #endif + + _level = 5; + _autoFilter = true; + _volumeMode = false; + InitSolid(); +} + +void COutHandler::BeforeSetProperty() +{ + Init(); + #ifdef COMPRESS_MT + numProcessors = NSystem::GetNumberOfProcessors(); + #endif + + mainDicSize = 0xFFFFFFFF; + mainDicMethodIndex = 0xFFFFFFFF; + minNumber = 0; +} + +HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name[0] == 'X') + { + name.Delete(0); + _level = 9; + return ParsePropValue(name, value, _level); + } + + if (name[0] == L'S') + { + name.Delete(0); + if (name.IsEmpty()) + return SetSolidSettings(value); + if (value.vt != VT_EMPTY) + return E_INVALIDARG; + return SetSolidSettings(name); + } + + UInt32 number; + int index = ParseStringToUInt32(name, number); + UString realName = name.Mid(index); + if (index == 0) + { + if(name.Left(2).CompareNoCase(L"MT") == 0) + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); + #endif + return S_OK; + } + if (name.CompareNoCase(L"RSFX") == 0) + return SetBoolProperty(_removeSfxBlock, value); + if (name.CompareNoCase(L"F") == 0) + return SetBoolProperty(_autoFilter, value); + if (name.CompareNoCase(L"HC") == 0) + return SetBoolProperty(_compressHeaders, value); + if (name.CompareNoCase(L"HCF") == 0) + { + bool compressHeadersFull = true; + RINOK(SetBoolProperty(compressHeadersFull, value)); + if (!compressHeadersFull) + return E_INVALIDARG; + return S_OK; + } + if (name.CompareNoCase(L"HE") == 0) + return SetBoolProperty(_encryptHeaders, value); + if (name.CompareNoCase(L"TM") == 0) + return SetBoolProperty(WriteModified, value); + if (name.CompareNoCase(L"TC") == 0) + return SetBoolProperty(WriteCreated, value); + if (name.CompareNoCase(L"TA") == 0) + return SetBoolProperty(WriteAccessed, value); + if (name.CompareNoCase(L"V") == 0) + return SetBoolProperty(_volumeMode, value); + number = 0; + } + if (number > 10000) + return E_FAIL; + if (number < minNumber) + return E_INVALIDARG; + number -= minNumber; + for(int j = _methods.Size(); j <= (int)number; j++) + { + COneMethodInfo oneMethodInfo; + _methods.Add(oneMethodInfo); + } + + COneMethodInfo &oneMethodInfo = _methods[number]; + + if (realName.Length() == 0) + { + if (value.vt != VT_BSTR) + return E_INVALIDARG; + + RINOK(SetParams(oneMethodInfo, value.bstrVal)); + } + else + { + CProp property; + if (realName.Left(1).CompareNoCase(L"D") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize)); + property.Id = NCoderPropID::kDictionarySize; + property.Value = dicSize; + oneMethodInfo.Properties.Add(property); + if (number <= mainDicMethodIndex) + mainDicSize = dicSize; + } + else if (realName.Left(3).CompareNoCase(L"MEM") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize)); + property.Id = NCoderPropID::kUsedMemorySize; + property.Value = dicSize; + oneMethodInfo.Properties.Add(property); + if (number <= mainDicMethodIndex) + mainDicSize = dicSize; + } + else + { + int index = FindPropIdFromStringName(realName); + if (index < 0) + return E_INVALIDARG; + + const CNameToPropID &nameToPropID = g_NameToPropID[index]; + property.Id = nameToPropID.PropID; + + if (!ConvertProperty(value, nameToPropID.VarType, property.Value)) + return E_INVALIDARG; + + oneMethodInfo.Properties.Add(property); + } + } + return S_OK; +} + +} diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h new file mode 100755 index 00000000..eded0786 --- /dev/null +++ b/CPP/7zip/Archive/Common/HandlerOut.h @@ -0,0 +1,84 @@ +// HandlerOut.h + +#ifndef __HANDLER_OUT_H +#define __HANDLER_OUT_H + +#include "../../Common/MethodProps.h" +#include "../../Common/CreateCoder.h" + +namespace NArchive { + +struct COneMethodInfo +{ + CObjectVector<CProp> Properties; + UString MethodName; +}; + +class COutHandler +{ +public: + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); + + HRESULT SetSolidSettings(const UString &s); + HRESULT SetSolidSettings(const PROPVARIANT &value); + + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + CObjectVector<COneMethodInfo> _methods; + bool _removeSfxBlock; + + UInt64 _numSolidFiles; + UInt64 _numSolidBytes; + bool _numSolidBytesDefined; + bool _solidExtension; + + bool _compressHeaders; + bool _encryptHeaders; + + bool WriteModified; + bool WriteCreated; + bool WriteAccessed; + + bool _autoFilter; + UInt32 _level; + + bool _volumeMode; + + HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value); + HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString); + + void SetCompressionMethod2(COneMethodInfo &oneMethodInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ); + + void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } + void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); } + void InitSolid() + { + InitSolidFiles(); + InitSolidSize(); + _solidExtension = false; + _numSolidBytesDefined = false; + } + + void Init(); + + COutHandler() { Init(); } + + void BeforeSetProperty(); + + UInt32 minNumber; + UInt32 numProcessors; + UInt32 mainDicSize; + UInt32 mainDicMethodIndex; + + DECL_EXTERNAL_CODECS_VARS +}; + +} + +#endif diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h index 63a01563..5eafacb1 100755 --- a/CPP/7zip/Archive/Common/ItemNameUtils.h +++ b/CPP/7zip/Archive/Common/ItemNameUtils.h @@ -3,7 +3,7 @@ #ifndef __ARCHIVE_ITEMNAMEUTILS_H #define __ARCHIVE_ITEMNAMEUTILS_H -#include "../../../Common/String.h" +#include "../../../Common/MyString.h" namespace NArchive { namespace NItemName { diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h index 5a7cc687..b0fe41d6 100755 --- a/CPP/7zip/Archive/Common/MultiStream.h +++ b/CPP/7zip/Archive/Common/MultiStream.h @@ -4,7 +4,7 @@ #define __MULTISTREAM_H #include "../../../Common/MyCom.h" -#include "../../../Common/Vector.h" +#include "../../../Common/MyVector.h" #include "../../Archive/IArchive.h" class CMultiStream: diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp index 9866d900..f0d4e29c 100755 --- a/CPP/7zip/Archive/Common/ParseProperties.cpp +++ b/CPP/7zip/Archive/Common/ParseProperties.cpp @@ -97,34 +97,37 @@ HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, U return ParsePropDictionaryValue(name, resValue); } +bool StringToBool(const UString &s, bool &res) +{ + if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0) + { + res = true; + return true; + } + if (s.CompareNoCase(L"OFF") == 0) + { + res = false; + return true; + } + return false; +} + HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) { switch(value.vt) { case VT_EMPTY: dest = true; - break; + return S_OK; /* case VT_UI4: dest = (value.ulVal != 0); break; */ case VT_BSTR: - { - UString valueString = value.bstrVal; - valueString.MakeUpper(); - if (valueString.Compare(L"ON") == 0) - dest = true; - else if (valueString.Compare(L"OFF") == 0) - dest = false; - else - return E_INVALIDARG; - break; - } - default: - return E_INVALIDARG; + return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG; } - return S_OK; + return E_INVALIDARG; } int ParseStringToUInt32(const UString &srcString, UInt32 &number) diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h index e6db316b..6f80f634 100755 --- a/CPP/7zip/Archive/Common/ParseProperties.h +++ b/CPP/7zip/Archive/Common/ParseProperties.h @@ -3,13 +3,14 @@ #ifndef __PARSEPROPERTIES_H #define __PARSEPROPERTIES_H -#include "Common/String.h" +#include "Common/MyString.h" #include "Common/Types.h" HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize); HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); +bool StringToBool(const UString &s, bool &res); HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value); int ParseStringToUInt32(const UString &srcString, UInt32 &number); HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); |