Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2007-06-26 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:52 +0300
commitfd8b1d78b496fe38193bf8c5e86af3b43f0b022d (patch)
tree5b1e3812ed4d8b6037e5035faf3b638849f618e2 /CPP/7zip/Archive/Common
parent0b33f700a66fcf7f55f92b92e0b3e5c7014d769a (diff)
4.48 beta
Diffstat (limited to 'CPP/7zip/Archive/Common')
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer.cpp19
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer.h32
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2.cpp6
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2.h20
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2MT.cpp257
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2MT.h123
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixerMT.cpp97
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixerMT.h68
-rwxr-xr-xCPP/7zip/Archive/Common/HandlerOut.cpp609
-rwxr-xr-xCPP/7zip/Archive/Common/HandlerOut.h84
-rwxr-xr-xCPP/7zip/Archive/Common/ItemNameUtils.h2
-rwxr-xr-xCPP/7zip/Archive/Common/MultiStream.h2
-rwxr-xr-xCPP/7zip/Archive/Common/ParseProperties.cpp33
-rwxr-xr-xCPP/7zip/Archive/Common/ParseProperties.h3
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 &param, 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 &param = 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);