summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2ST.cpp')
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2ST.cpp239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2ST.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
new file mode 100644
index 000000000..a59ce5fc0
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
@@ -0,0 +1,239 @@
+// CoderMixer2ST.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2ST.h"
+
+namespace NCoderMixer2 {
+
+CCoderMixer2ST::CCoderMixer2ST() {}
+
+CCoderMixer2ST::~CCoderMixer2ST(){ }
+
+HRESULT CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+ return S_OK;
+}
+
+void CCoderMixer2ST::AddCoderCommon(bool isMain)
+{
+ const CCoderStreamsInfo &csi = _bindInfo.Coders[_coders.Size()];
+ _coders.Add(CSTCoderInfo(csi.NumInStreams, csi.NumOutStreams, isMain));
+}
+
+void CCoderMixer2ST::AddCoder(ICompressCoder *coder, bool isMain)
+{
+ AddCoderCommon(isMain);
+ _coders.Back().Coder = coder;
+}
+
+void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain)
+{
+ AddCoderCommon(isMain);
+ _coders.Back().Coder2 = coder;
+}
+
+void CCoderMixer2ST::ReInit() { }
+
+HRESULT CCoderMixer2ST::GetInStream(
+ ISequentialInStream **inStreams, const UInt64 **inSizes,
+ UInt32 streamIndex, ISequentialInStream **inStreamRes)
+{
+ CMyComPtr<ISequentialInStream> seqInStream;
+ int i;
+ for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ if (_bindInfo.InStreams[i] == streamIndex)
+ {
+ seqInStream = inStreams[i];
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+ }
+ int binderIndex = _bindInfo.FindBinderForInStream(streamIndex);
+ if (binderIndex < 0)
+ return E_INVALIDARG;
+
+ UInt32 coderIndex, coderStreamIndex;
+ _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
+ coderIndex, coderStreamIndex);
+
+ CCoderInfo &coder = _coders[coderIndex];
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
+ if (!seqInStream)
+ return E_NOTIMPL;
+
+ UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex);
+
+ CMyComPtr<ICompressSetInStream> setInStream;
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream);
+ if (!setInStream)
+ return E_NOTIMPL;
+
+ if (coder.NumInStreams > 1)
+ return E_NOTIMPL;
+ for (i = 0; i < (int)coder.NumInStreams; i++)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream2;
+ RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2));
+ RINOK(setInStream->SetInStream(seqInStream2));
+ }
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+}
+
+HRESULT CCoderMixer2ST::GetOutStream(
+ ISequentialOutStream **outStreams, const UInt64 **outSizes,
+ UInt32 streamIndex, ISequentialOutStream **outStreamRes)
+{
+ CMyComPtr<ISequentialOutStream> seqOutStream;
+ int i;
+ for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ if (_bindInfo.OutStreams[i] == streamIndex)
+ {
+ seqOutStream = outStreams[i];
+ *outStreamRes = seqOutStream.Detach();
+ return S_OK;
+ }
+ int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex);
+ if (binderIndex < 0)
+ return E_INVALIDARG;
+
+ UInt32 coderIndex, coderStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
+ coderIndex, coderStreamIndex);
+
+ CCoderInfo &coder = _coders[coderIndex];
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
+ if (!seqOutStream)
+ return E_NOTIMPL;
+
+ UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
+
+ CMyComPtr<ICompressSetOutStream> setOutStream;
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
+ if (!setOutStream)
+ return E_NOTIMPL;
+
+ if (coder.NumOutStreams > 1)
+ return E_NOTIMPL;
+ for (i = 0; i < (int)coder.NumOutStreams; i++)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream2;
+ RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2));
+ RINOK(setOutStream->SetOutStream(seqOutStream2));
+ }
+ *outStreamRes = seqOutStream.Detach();
+ return S_OK;
+}
+
+
+STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+ numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+ return E_INVALIDARG;
+
+ // Find main coder
+ int _mainCoderIndex = -1;
+ int i;
+ for (i = 0; i < _coders.Size(); i++)
+ if (_coders[i].IsMain)
+ {
+ _mainCoderIndex = i;
+ break;
+ }
+ if (_mainCoderIndex < 0)
+ for (i = 0; i < _coders.Size(); i++)
+ if (_coders[i].NumInStreams > 1)
+ {
+ if (_mainCoderIndex >= 0)
+ return E_NOTIMPL;
+ _mainCoderIndex = i;
+ }
+ if (_mainCoderIndex < 0)
+ _mainCoderIndex = 0;
+
+ // _mainCoderIndex = 0;
+ // _mainCoderIndex = _coders.Size() - 1;
+ CCoderInfo &mainCoder = _coders[_mainCoderIndex];
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
+ UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex);
+ UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex);
+ for (i = 0; i < (int)mainCoder.NumInStreams; i++)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream;
+ RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream));
+ seqInStreams.Add(seqInStream);
+ }
+ for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream;
+ RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream));
+ seqOutStreams.Add(seqOutStream);
+ }
+ CRecordVector< ISequentialInStream * > seqInStreamsSpec;
+ CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
+ for (i = 0; i < (int)mainCoder.NumInStreams; i++)
+ seqInStreamsSpec.Add(seqInStreams[i]);
+ for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
+ seqOutStreamsSpec.Add(seqOutStreams[i]);
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ if (i == _mainCoderIndex)
+ continue;
+ CCoderInfo &coder = _coders[i];
+ CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
+ coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
+ if (setOutStreamSize)
+ {
+ RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0]));
+ }
+ }
+ if (mainCoder.Coder)
+ {
+ RINOK(mainCoder.Coder->Code(
+ seqInStreamsSpec[0], seqOutStreamsSpec[0],
+ mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0],
+ progress));
+ }
+ else
+ {
+ RINOK(mainCoder.Coder2->Code(
+ &seqInStreamsSpec.Front(),
+ &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams,
+ &seqOutStreamsSpec.Front(),
+ &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams,
+ progress));
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+/*
+UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const
+{
+ return _streamBinders[binderIndex].ProcessedSize;
+}
+*/
+
+}