Source code

Revision control

Copy as Markdown

Other Tools

// CoderMixer2.h↩
#ifndef __CODER_MIXER2_H↩
#define __CODER_MIXER2_H↩
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../ICoder.h"
#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 CBond↩
{↩
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 NumStreams;↩
};↩
struct CBindInfo↩
{↩
CRecordVector<CCoderStreamsInfo> Coders;↩
CRecordVector<CBond> Bonds;↩
CRecordVector<UInt32> PackStreams;↩
unsigned UnpackCoder;↩
unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); }↩
int FindBond_for_PackStream(UInt32 packStream) const
{↩
FOR_VECTOR (i, Bonds)↩
if (Bonds[i].PackIndex == packStream)↩
return i;↩
return -1;↩
}↩
int FindBond_for_UnpackStream(UInt32 unpackStream) const
{↩
FOR_VECTOR (i, Bonds)↩
if (Bonds[i].UnpackIndex == unpackStream)↩
return i;↩
return -1;↩
}↩
bool SetUnpackCoder()↩
{↩
bool isOk = false;↩
FOR_VECTOR(i, Coders)↩
{↩
if (FindBond_for_UnpackStream(i) < 0)↩
{↩
if (isOk)↩
return false;↩
UnpackCoder = i;↩
isOk = true;↩
}↩
}↩
return isOk;↩
}↩
bool IsStream_in_PackStreams(UInt32 streamIndex) const
{↩
return FindStream_in_PackStreams(streamIndex) >= 0;↩
}↩
int FindStream_in_PackStreams(UInt32 streamIndex) const
{↩
FOR_VECTOR(i, PackStreams)↩
if (PackStreams[i] == streamIndex)↩
return i;↩
return -1;↩
}↩
// 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].NumStreams;↩
return streamIndex;↩
}↩
// ---------- Maps Section ----------↩
CRecordVector<UInt32> Coder_to_Stream;↩
CRecordVector<UInt32> Stream_to_Coder;↩
void ClearMaps();↩
bool CalcMapsAndCheck();↩
// ---------- End of Maps Section ----------↩
void Clear()↩
{↩
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];↩
}↩
};↩
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;↩
bool Finish;↩
CCoder(): Finish(false) {}↩
void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);↩
HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;↩
IUnknown *GetUnknown() const
{↩
return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;↩
}↩
HRESULT QueryInterface(REFGUID iid, void** pp) const
{↩
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;↩
// bool InternalPackSizeError;↩
CMixer(bool encodeMode):↩
EncodeMode(encodeMode),↩
MainCoderIndex(0)↩
// , InternalPackSizeError(false)↩
{}↩
/*↩
Sequence of calling:↩
SetBindInfo();↩
for each coder↩
AddCoder();↩
SelectMainCoder();↩
for each file↩
{↩
ReInit()↩
for each coder↩
SetCoderInfo();↩
Code();↩
}↩
*/
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, bool finish) = 0;↩
virtual HRESULT Code(↩
ISequentialInStream * const *inStreams,↩
ISequentialOutStream * const *outStreams,↩
ICompressProgressInfo *progress,↩
bool &dataAfterEnd_Error) = 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);↩
};↩
#ifdef USE_MIXER_ST↩
struct CCoderST: public CCoder↩
{↩
bool CanRead;↩
bool CanWrite;↩
CCoderST(): CanRead(false), CanWrite(false) {}↩
};↩
struct CStBinderStream↩
{↩
CSequentialInStreamCalcSize *InStreamSpec;↩
COutStreamCalcSize *OutStreamSpec;↩
CMyComPtr<IUnknown> StreamRef;↩
CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}↩
};↩
class CMixerST:↩
public IUnknown,↩
public CMixer,↩
public CMyUnknownImp↩
{↩
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);↩
HRESULT FinishStream(UInt32 streamIndex);↩
HRESULT FinishCoder(UInt32 coderIndex);↩
public:↩
CObjectVector<CCoderST> _coders;↩
CObjectVector<CStBinderStream> _binderStreams;↩
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, bool finish)↩
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }↩
virtual HRESULT Code(↩
ISequentialInStream * const *inStreams,↩
ISequentialOutStream * const *outStreams,↩
ICompressProgressInfo *progress,↩
bool &dataAfterEnd_Error);↩
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()↩
{↩
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 CMixerMT:↩
public IUnknown,↩
public CMixer,↩
public CMyUnknownImp↩
{↩
CObjectVector<CStreamBinder> _streamBinders;↩
HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);↩
HRESULT ReturnIfError(HRESULT code);↩
public:↩
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, bool finish)↩
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }↩
virtual HRESULT Code(↩
ISequentialInStream * const *inStreams,↩
ISequentialOutStream * const *outStreams,↩
ICompressProgressInfo *progress,↩
bool &dataAfterEnd_Error);↩
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;↩
CMixerMT(bool encodeMode): CMixer(encodeMode) {}↩
};↩
#endif
}↩
#endif