00001
#ifndef CRYPTOPP_ZINFLATE_H
00002
#define CRYPTOPP_ZINFLATE_H
00003
00004
#include "filters.h"
00005
#include <vector>
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009
00010 class
LowFirstBitReader
00011 {
00012
public:
00013 LowFirstBitReader(
BufferedTransformation &store)
00014 : m_store(store), m_buffer(0), m_bitsBuffered(0) {}
00015
unsigned long BitsLeft()
const {
return m_store.MaxRetrievable() * 8 + m_bitsBuffered;}
00016
unsigned int BitsBuffered()
const {
return m_bitsBuffered;}
00017
unsigned long PeekBuffer()
const {
return m_buffer;}
00018
bool FillBuffer(
unsigned int length);
00019
unsigned long PeekBits(
unsigned int length);
00020
void SkipBits(
unsigned int length);
00021
unsigned long GetBits(
unsigned int length);
00022
00023
private:
00024
BufferedTransformation &m_store;
00025
unsigned long m_buffer;
00026
unsigned int m_bitsBuffered;
00027 };
00028
00029
struct CodeLessThan;
00030
00031
00032 class HuffmanDecoder
00033 {
00034
public:
00035
typedef unsigned int code_t;
00036
typedef unsigned int value_t;
00037
enum {MAX_CODE_BITS =
sizeof(code_t)*8};
00038
00039
class Err :
public Exception {
public: Err(
const std::string &what) :
Exception(INVALID_DATA_FORMAT,
"HuffmanDecoder: " + what) {}};
00040
00041
HuffmanDecoder() {}
00042
HuffmanDecoder(
const unsigned int *codeBitLengths,
unsigned int nCodes) {Initialize(codeBitLengths, nCodes);}
00043
00044
void Initialize(
const unsigned int *codeBitLengths,
unsigned int nCodes);
00045
unsigned int Decode(code_t code, value_t &value)
const;
00046
bool Decode(
LowFirstBitReader &reader, value_t &value)
const;
00047
00048
private:
00049
friend struct CodeLessThan;
00050
00051
struct CodeInfo
00052 {
00053 CodeInfo(code_t code=0,
unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {}
00054
inline bool operator<(
const CodeInfo &rhs)
const {
return code < rhs.code;}
00055 code_t code;
00056
unsigned int len;
00057 value_t value;
00058 };
00059
00060
struct LookupEntry
00061 {
00062
unsigned int type;
00063
union
00064
{
00065 value_t value;
00066
const CodeInfo *begin;
00067 };
00068
union
00069
{
00070
unsigned int len;
00071
const CodeInfo *end;
00072 };
00073 };
00074
00075
static code_t NormalizeCode(code_t code,
unsigned int codeBits);
00076
void FillCacheEntry(LookupEntry &entry, code_t normalizedCode)
const;
00077
00078
unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask;
00079 std::vector<CodeInfo, AllocatorWithCleanup<CodeInfo> > m_codeToValue;
00080
mutable std::vector<LookupEntry, AllocatorWithCleanup<LookupEntry> > m_cache;
00081 };
00082
00083
00084
00085 class Inflator :
public AutoSignaling<Filter>
00086 {
00087
public:
00088
class Err :
public Exception
00089 {
00090
public:
00091 Err(ErrorType e,
const std::string &s)
00092 :
Exception(e, s) {}
00093 };
00094
class UnexpectedEndErr :
public Err {
public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT,
"Inflator: unexpected end of compressed block") {}};
00095
class BadBlockErr :
public Err {
public: BadBlockErr() : Err(INVALID_DATA_FORMAT,
"Inflator: error in compressed block") {}};
00096
00097
00098
00099
00100
Inflator(
BufferedTransformation *attachment = NULL,
bool repeat =
false,
int autoSignalPropagation = -1);
00101
00102
void IsolatedInitialize(
const NameValuePairs ¶meters);
00103
unsigned int Put2(
const byte *inString,
unsigned int length,
int messageEnd,
bool blocking);
00104
bool IsolatedFlush(
bool hardFlush,
bool blocking);
00105
00106
virtual unsigned int GetLog2WindowSize()
const {
return 15;}
00107
00108
protected:
00109
ByteQueue m_inQueue;
00110
00111
private:
00112
virtual unsigned int MaxPrestreamHeaderSize()
const {
return 0;}
00113
virtual void ProcessPrestreamHeader() {}
00114
virtual void ProcessDecompressedData(
const byte *string,
unsigned int length)
00115 {AttachedTransformation()->Put(string, length);}
00116
virtual unsigned int MaxPoststreamTailSize()
const {
return 0;}
00117
virtual void ProcessPoststreamTail() {}
00118
00119
void ProcessInput(
bool flush);
00120
void DecodeHeader();
00121
bool DecodeBody();
00122
void FlushOutput();
00123
void OutputByte(byte b);
00124
void OutputString(
const byte *string,
unsigned int length);
00125
void OutputPast(
unsigned int length,
unsigned int distance);
00126
00127
enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
00128 State m_state;
00129
bool m_repeat, m_eof, m_decodersInitializedWithFixedCodes;
00130 byte m_blockType;
00131 word16 m_storedLen;
00132
enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
00133 NextDecode m_nextDecode;
00134
unsigned int m_literal, m_distance;
00135
HuffmanDecoder m_literalDecoder, m_distanceDecoder;
00136
LowFirstBitReader m_reader;
00137
SecByteBlock m_window;
00138
unsigned int m_maxDistance, m_current, m_lastFlush;
00139 };
00140
00141 NAMESPACE_END
00142
00143
#endif