diff options
Diffstat (limited to 'CPP/7zip/Compress/BZip2/BZip2Decoder.h')
-rwxr-xr-x | CPP/7zip/Compress/BZip2/BZip2Decoder.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/CPP/7zip/Compress/BZip2/BZip2Decoder.h b/CPP/7zip/Compress/BZip2/BZip2Decoder.h new file mode 100755 index 00000000..2375b755 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2Decoder.h @@ -0,0 +1,164 @@ +// Compress/BZip2/Decoder.h + +#ifndef __COMPRESS_BZIP2_DECODER_H +#define __COMPRESS_BZIP2_DECODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../Huffman/HuffmanDecoder.h" +#include "BZip2Const.h" +#include "BZip2CRC.h" + +#ifdef COMPRESS_BZIP2_MT +#include "../../../Windows/Thread.h" +#include "../../../Windows/Synchronization.h" +#endif + +#if _MSC_VER >= 1300 +#define NO_INLINE __declspec(noinline) __fastcall +#else +#ifdef _MSC_VER +#define NO_INLINE __fastcall +#endif +#endif + +namespace NCompress { +namespace NBZip2 { + +typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder; + +class CDecoder; + +struct CState +{ + UInt32 *Counters; + + #ifdef COMPRESS_BZIP2_MT + + CDecoder *Decoder; + NWindows::CThread Thread; + bool m_OptimizeNumTables; + + NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; + NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; + + // it's not member of this thread. We just need one event per thread + NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; + + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + + void FinishStream(); + void ThreadFunc(); + + #endif + + CState(): Counters(0) {} + ~CState() { Free(); } + bool Alloc(); + void Free(); +}; + +class CDecoder : + public ICompressCoder, + #ifdef COMPRESS_BZIP2_MT + public ICompressSetCoderMt, + #endif + public ICompressGetInStreamProcessedSize, + public CMyUnknownImp +{ +public: + COutBuffer m_OutStream; + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + NStream::NMSBF::CDecoder<CInBuffer> m_InStream; + Byte m_Selectors[kNumSelectorsMax]; + CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; +private: + + UInt32 m_NumThreadsPrev; + + UInt32 ReadBits(int numBits); + Byte ReadByte(); + bool ReadBit(); + UInt32 ReadCRC(); + HRESULT PrepareBlock(CState &state); + HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + +public: + CBZip2CombinedCRC CombinedCRC; + + #ifdef COMPRESS_BZIP2_MT + ICompressProgressInfo *Progress; + CState *m_States; + + NWindows::NSynchronization::CCriticalSection CS; + UInt32 NumThreads; + bool MtMode; + UInt32 NextBlockIndex; + bool CloseThreads; + bool StreamWasFinished1; + bool StreamWasFinished2; + NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; + + HRESULT Result1; + HRESULT Result2; + + UInt32 BlockSizeMax; + CDecoder(); + ~CDecoder(); + bool Create(); + void Free(); + + #else + CState m_States[1]; + #endif + + HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc); + + + HRESULT Flush() { return m_OutStream.Flush(); } + void ReleaseStreams() + { + m_InStream.ReleaseStream(); + m_OutStream.ReleaseStream(); + } + + #ifdef COMPRESS_BZIP2_MT + MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize) + #else + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + #endif + + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + #ifdef COMPRESS_BZIP2_MT + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); + #endif +}; + +}} + +#endif |