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:
Diffstat (limited to 'CPP/7zip/Archive/Common/CoderMixer2.h')
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.h462
1 files changed, 360 insertions, 102 deletions
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
index 50e7077a..e63f2ff0 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -8,172 +8,430 @@
#include "../../ICoder.h"
-namespace NCoderMixer {
+#include "../../Common/CreateCoder.h"
-struct CBindPair
+#ifdef _7ZIP_ST
+ #define USE_MIXER_ST
+#else
+ #define USE_MIXER_MT
+ #ifndef _SFX
+ #define USE_MIXER_ST
+ #endif
+#endif
+
+#ifdef USE_MIXER_MT
+#include "../../Common/StreamBinder.h"
+#include "../../Common/VirtThread.h"
+#endif
+
+
+
+#ifdef USE_MIXER_ST
+
+class CSequentialInStreamCalcSize:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ISequentialInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+ bool _wasFinished;
+public:
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void Init()
+ {
+ _size = 0;
+ _wasFinished = false;
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt64 GetSize() const { return _size; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+
+class COutStreamCalcSize:
+ public ISequentialOutStream,
+ public IOutStreamFinish,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(OutStreamFinish)();
+
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
+ void Init() { _size = 0; }
+ UInt64 GetSize() const { return _size; }
+};
+
+#endif
+
+
+
+namespace NCoderMixer2 {
+
+struct CBond
{
- UInt32 InIndex;
- UInt32 OutIndex;
+ UInt32 PackIndex;
+ UInt32 UnpackIndex;
+
+ UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; }
+ UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; }
};
+
struct CCoderStreamsInfo
{
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
+ UInt32 NumStreams;
};
+
struct CBindInfo
{
CRecordVector<CCoderStreamsInfo> Coders;
- CRecordVector<CBindPair> BindPairs;
- CRecordVector<UInt32> InStreams;
- CRecordVector<UInt32> OutStreams;
+ CRecordVector<CBond> Bonds;
+ CRecordVector<UInt32> PackStreams;
+ unsigned UnpackCoder;
- void Clear()
+ unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); }
+
+ int FindBond_for_PackStream(UInt32 packStream) const
{
- Coders.Clear();
- BindPairs.Clear();
- InStreams.Clear();
- OutStreams.Clear();
+ FOR_VECTOR (i, Bonds)
+ if (Bonds[i].PackIndex == packStream)
+ return i;
+ return -1;
}
- /*
- UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+ int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
- UInt32 numOutStreams = 0;
- for (UInt32 i = 0; i < coderIndex; i++)
- numOutStreams += Coders[i].NumOutStreams;
- return numOutStreams;
+ FOR_VECTOR (i, Bonds)
+ if (Bonds[i].UnpackIndex == unpackStream)
+ return i;
+ return -1;
}
- */
-
- void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+ bool SetUnpackCoder()
{
- numInStreams = 0;
- numOutStreams = 0;
- FOR_VECTOR (i, Coders)
+ bool isOk = false;
+ FOR_VECTOR(i, Coders)
{
- const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
- numInStreams += coderStreamsInfo.NumInStreams;
- numOutStreams += coderStreamsInfo.NumOutStreams;
+ if (FindBond_for_UnpackStream(i) < 0)
+ {
+ if (isOk)
+ return false;
+ UnpackCoder = i;
+ isOk = true;
+ }
}
+ return isOk;
}
-
- int FindBinderForInStream(UInt32 inStream) const
+
+ bool IsStream_in_PackStreams(UInt32 streamIndex) const
{
- FOR_VECTOR (i, BindPairs)
- if (BindPairs[i].InIndex == inStream)
- return i;
- return -1;
+ return FindStream_in_PackStreams(streamIndex) >= 0;
}
- int FindBinderForOutStream(UInt32 outStream) const
+
+ int FindStream_in_PackStreams(UInt32 streamIndex) const
{
- FOR_VECTOR (i, BindPairs)
- if (BindPairs[i].OutIndex == outStream)
+ FOR_VECTOR(i, PackStreams)
+ if (PackStreams[i] == streamIndex)
return i;
return -1;
}
- UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+
+ // that function is used before Maps is calculated
+
+ UInt32 GetStream_for_Coder(UInt32 coderIndex) const
{
UInt32 streamIndex = 0;
for (UInt32 i = 0; i < coderIndex; i++)
- streamIndex += Coders[i].NumInStreams;
+ streamIndex += Coders[i].NumStreams;
return streamIndex;
}
+
+ // ---------- Maps Section ----------
+
+ CRecordVector<UInt32> Coder_to_Stream;
+ CRecordVector<UInt32> Stream_to_Coder;
+
+ void ClearMaps();
+ bool CalcMapsAndCheck();
+
+ // ---------- End of Maps Section ----------
- UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+ void Clear()
{
- UInt32 streamIndex = 0;
- for (UInt32 i = 0; i < coderIndex; i++)
- streamIndex += Coders[i].NumOutStreams;
- return streamIndex;
+ Coders.Clear();
+ Bonds.Clear();
+ PackStreams.Clear();
+
+ ClearMaps();
}
+
+ void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const
+ {
+ coderIndex = Stream_to_Coder[streamIndex];
+ coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex];
+ }
+};
- void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
- UInt32 &coderStreamIndex) const
+
+class CCoder
+{
+ CLASS_NO_COPY(CCoder);
+public:
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UInt32 NumStreams;
+
+ UInt64 UnpackSize;
+ const UInt64 *UnpackSizePointer;
+
+ CRecordVector<UInt64> PackSizes;
+ CRecordVector<const UInt64 *> PackSizePointers;
+
+ CCoder() {}
+
+ void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes);
+
+ IUnknown *GetUnknown() const
{
- for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
- {
- UInt32 curSize = Coders[coderIndex].NumInStreams;
- if (streamIndex < curSize)
- {
- coderStreamIndex = streamIndex;
- return;
- }
- streamIndex -= curSize;
- }
- throw 1;
+ return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
}
- void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
- UInt32 &coderStreamIndex) const
+
+ HRESULT QueryInterface(REFGUID iid, void** pp) const
{
- for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
- {
- UInt32 curSize = Coders[coderIndex].NumOutStreams;
- if (streamIndex < curSize)
+ return GetUnknown()->QueryInterface(iid, pp);
+ }
+};
+
+
+
+class CMixer
+{
+ bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex);
+
+protected:
+ CBindInfo _bi;
+
+ int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const
+ {
+ if (EncodeMode == forInputStream)
+ return _bi.FindBond_for_UnpackStream(streamIndex);
+ else
+ return _bi.FindBond_for_PackStream(streamIndex);
+ }
+
+ CBoolVector IsFilter_Vector;
+ CBoolVector IsExternal_Vector;
+ bool EncodeMode;
+public:
+ unsigned MainCoderIndex;
+
+ CMixer(bool encodeMode):
+ EncodeMode(encodeMode),
+ MainCoderIndex(0)
+ {}
+
+ /*
+ Sequence of calling:
+
+ SetBindInfo();
+ for each coder
+ AddCoder();
+ SelectMainCoder();
+
+ for each file
{
- coderStreamIndex = streamIndex;
- return;
+ ReInit()
+ for each coder
+ SetCoderInfo();
+ Code();
}
- streamIndex -= curSize;
- }
- throw 1;
+ */
+
+ virtual HRESULT SetBindInfo(const CBindInfo &bindInfo)
+ {
+ _bi = bindInfo;
+ IsFilter_Vector.Clear();
+ MainCoderIndex = 0;
+ return S_OK;
}
+
+ virtual void AddCoder(const CCreatedCoder &cod) = 0;
+ virtual CCoder &GetCoder(unsigned index) = 0;
+ virtual void SelectMainCoder(bool useFirst) = 0;
+ virtual void ReInit() = 0;
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) = 0;
+ virtual HRESULT Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress) = 0;
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
+
+ bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
+ bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex);
+ bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex);
};
-class CBindReverseConverter
+
+
+
+#ifdef USE_MIXER_ST
+
+struct CCoderST: public CCoder
{
- UInt32 _numSrcOutStreams;
- NCoderMixer::CBindInfo _srcBindInfo;
- CRecordVector<UInt32> _srcInToDestOutMap;
- CRecordVector<UInt32> _srcOutToDestInMap;
- CRecordVector<UInt32> _destInToSrcOutMap;
-public:
- UInt32 NumSrcInStreams;
- CRecordVector<UInt32> DestOutToSrcInMap;
+ bool CanRead;
+ bool CanWrite;
+
+ CCoderST(): CanRead(false), CanWrite(false) {}
+};
- CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
- void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
+
+struct CStBinderStream
+{
+ CSequentialInStreamCalcSize *InStreamSpec;
+ COutStreamCalcSize *OutStreamSpec;
+ CMyComPtr<IUnknown> StreamRef;
+
+ CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}
};
-void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
- CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems);
-struct CCoderInfo2
+class CMixerST:
+ public IUnknown,
+ public CMixer,
+ public CMyUnknownImp
{
- CMyComPtr<ICompressCoder> Coder;
- CMyComPtr<ICompressCoder2> Coder2;
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
+ HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
+ UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
+ HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
+ UInt32 inStreamIndex, ISequentialInStream **inStreamRes);
+ HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
+ UInt32 outStreamIndex, ISequentialOutStream **outStreamRes);
- CRecordVector<UInt64> InSizes;
- CRecordVector<UInt64> OutSizes;
- CRecordVector<const UInt64 *> InSizePointers;
- CRecordVector<const UInt64 *> OutSizePointers;
+ HRESULT FinishStream(UInt32 streamIndex);
+ HRESULT FinishCoder(UInt32 coderIndex);
- CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
- NumInStreams(numInStreams),
- NumOutStreams(numOutStreams) {}
- void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+public:
+ CObjectVector<CCoderST> _coders;
+
+ CObjectVector<CStBinderStream> _binderStreams;
- HRESULT QueryInterface(REFGUID iid, void** pp) const
+ MY_UNKNOWN_IMP
+
+ CMixerST(bool encodeMode);
+ ~CMixerST();
+
+ virtual void AddCoder(const CCreatedCoder &cod);
+ virtual CCoder &GetCoder(unsigned index);
+ virtual void SelectMainCoder(bool useFirst);
+ virtual void ReInit();
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual HRESULT Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress);
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
+
+ HRESULT GetMainUnpackStream(
+ ISequentialInStream * const *inStreams,
+ ISequentialInStream **inStreamRes);
+};
+
+#endif
+
+
+
+
+#ifdef USE_MIXER_MT
+
+class CCoderMT: public CCoder, public CVirtThread
+{
+ CLASS_NO_COPY(CCoderMT)
+ CRecordVector<ISequentialInStream*> InStreamPointers;
+ CRecordVector<ISequentialOutStream*> OutStreamPointers;
+
+private:
+ void Execute();
+public:
+ bool EncodeMode;
+ HRESULT Result;
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+
+ void Release()
{
- IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
- return p->QueryInterface(iid, pp);
+ InStreamPointers.Clear();
+ OutStreamPointers.Clear();
+ unsigned i;
+ for (i = 0; i < InStreams.Size(); i++)
+ InStreams[i].Release();
+ for (i = 0; i < OutStreams.Size(); i++)
+ OutStreams[i].Release();
}
+
+ class CReleaser
+ {
+ CLASS_NO_COPY(CReleaser)
+ CCoderMT &_c;
+ public:
+ CReleaser(CCoderMT &c): _c(c) {}
+ ~CReleaser() { _c.Release(); }
+ };
+
+ CCoderMT(): EncodeMode(false) {}
+ ~CCoderMT() { CVirtThread::WaitThreadFinish(); }
+
+ void Code(ICompressProgressInfo *progress);
};
-class CCoderMixer2
+
+class CMixerMT:
+ public IUnknown,
+ public CMixer,
+ public CMyUnknownImp
{
+ CObjectVector<CStreamBinder> _streamBinders;
+
+ HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
+ HRESULT ReturnIfError(HRESULT code);
+
public:
- virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
- virtual void ReInit() = 0;
- virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+ CObjectVector<CCoderMT> _coders;
+
+ MY_UNKNOWN_IMP
+
+ virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
+ virtual void AddCoder(const CCreatedCoder &cod);
+ virtual CCoder &GetCoder(unsigned index);
+ virtual void SelectMainCoder(bool useFirst);
+ virtual void ReInit();
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual HRESULT Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress);
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
+
+ CMixerMT(bool encodeMode): CMixer(encodeMode) {}
};
+#endif
+
}
#endif