diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h | 465 |
1 files changed, 364 insertions, 101 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h index a03722d61f1..e63f2ff0efa 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h @@ -3,172 +3,435 @@ #ifndef __CODER_MIXER2_H #define __CODER_MIXER2_H -#include "../../../Common/MyVector.h" -#include "../../../Common/Types.h" #include "../../../Common/MyCom.h" +#include "../../../Common/MyVector.h" + #include "../../ICoder.h" -namespace NCoderMixer { +#include "../../Common/CreateCoder.h" + +#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 CBindPair +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 (int i = 0; i < Coders.Size(); i++) + 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 (int i = 0; i < BindPairs.Size(); i++) - 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 (int i = 0; i < BindPairs.Size(); i++) - 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) {} }; -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); - 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 |