Crypto++  8.8
Free C++ class library of cryptographic schemes
zinflate.cpp
1 // zinflate.cpp - originally written and placed in the public domain by Wei Dai
2 
3 // This is a complete reimplementation of the DEFLATE decompression algorithm.
4 // It should not be affected by any security vulnerabilities in the zlib
5 // compression library. In particular it is not affected by the double free bug
6 // (http://www.kb.cert.org/vuls/id/368819).
7 
8 #include "pch.h"
9 
10 #include "zinflate.h"
11 #include "secblock.h"
12 #include "smartptr.h"
13 
14 NAMESPACE_BEGIN(CryptoPP)
15 
17 {
18  inline bool operator()(CryptoPP::HuffmanDecoder::code_t lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs)
19  {return lhs < rhs.code;}
20  // needed for MSVC .NET 2005
21  inline bool operator()(const CryptoPP::HuffmanDecoder::CodeInfo &lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs)
22  {return lhs.code < rhs.code;}
23 };
24 
25 inline bool LowFirstBitReader::FillBuffer(unsigned int length)
26 {
27  while (m_bitsBuffered < length)
28  {
29  byte b;
30  if (!m_store.Get(b))
31  return false;
32  m_buffer |= (unsigned long)b << m_bitsBuffered;
33  m_bitsBuffered += 8;
34  }
35  CRYPTOPP_ASSERT(m_bitsBuffered <= sizeof(unsigned long)*8);
36  return true;
37 }
38 
39 inline unsigned long LowFirstBitReader::PeekBits(unsigned int length)
40 {
41  bool result = FillBuffer(length);
42  CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result);
43  return m_buffer & (((unsigned long)1 << length) - 1);
44 }
45 
46 inline void LowFirstBitReader::SkipBits(unsigned int length)
47 {
48  CRYPTOPP_ASSERT(m_bitsBuffered >= length);
49  m_buffer >>= length;
50  m_bitsBuffered -= length;
51 }
52 
53 inline unsigned long LowFirstBitReader::GetBits(unsigned int length)
54 {
55  unsigned long result = PeekBits(length);
56  SkipBits(length);
57  return result;
58 }
59 
60 inline HuffmanDecoder::code_t HuffmanDecoder::NormalizeCode(HuffmanDecoder::code_t code, unsigned int codeBits)
61 {
62  return code << (MAX_CODE_BITS - codeBits);
63 }
64 
65 void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes)
66 {
67  // the Huffman codes are represented in 3 ways in this code:
68  //
69  // 1. most significant code bit (i.e. top of code tree) in the least significant bit position
70  // 2. most significant code bit (i.e. top of code tree) in the most significant bit position
71  // 3. most significant code bit (i.e. top of code tree) in n-th least significant bit position,
72  // where n is the maximum code length for this code tree
73  //
74  // (1) is the way the codes come in from the deflate stream
75  // (2) is used to sort codes so they can be binary searched
76  // (3) is used in this function to compute codes from code lengths
77  //
78  // a code in representation (2) is called "normalized" here
79  // The BitReverse() function is used to convert between (1) and (2)
80  // The NormalizeCode() function is used to convert from (3) to (2)
81 
82  if (nCodes == 0)
83  throw Err("null code");
84 
85  m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);
86 
87  if (m_maxCodeBits > MAX_CODE_BITS)
88  throw Err("code length exceeds maximum");
89 
90  if (m_maxCodeBits == 0)
91  throw Err("null code");
92 
93  // count number of codes of each length
94  SecBlockWithHint<unsigned int, 15+1> blCount(m_maxCodeBits+1);
95  std::fill(blCount.begin(), blCount.end(), 0);
96  unsigned int i;
97  for (i=0; i<nCodes; i++)
98  blCount[codeBits[i]]++;
99 
100  // compute the starting code of each length
101  code_t code = 0;
102  SecBlockWithHint<code_t, 15+1> nextCode(m_maxCodeBits+1);
103  nextCode[1] = 0;
104  for (i=2; i<=m_maxCodeBits; i++)
105  {
106  // compute this while checking for overflow: code = (code + blCount[i-1]) << 1
107  if (code > code + blCount[i-1])
108  throw Err("codes oversubscribed");
109  code += blCount[i-1];
110  if (code > (code << 1))
111  throw Err("codes oversubscribed");
112  code <<= 1;
113  nextCode[i] = code;
114  }
115 
116  // MAX_CODE_BITS is 32, m_maxCodeBits may be smaller.
117  const word64 shiftedMaxCode = ((word64)1 << m_maxCodeBits);
118  if (code > shiftedMaxCode - blCount[m_maxCodeBits])
119  throw Err("codes oversubscribed");
120  else if (m_maxCodeBits != 1 && code < shiftedMaxCode - blCount[m_maxCodeBits])
121  throw Err("codes incomplete");
122 
123  // compute a vector of <code, length, value> triples sorted by code
124  m_codeToValue.resize(nCodes - blCount[0]);
125  unsigned int j=0;
126  for (i=0; i<nCodes; i++)
127  {
128  unsigned int len = codeBits[i];
129  if (len != 0)
130  {
131  CRYPTOPP_ASSERT(j < m_codeToValue.size());
132  code = NormalizeCode(nextCode[len]++, len);
133  m_codeToValue[j].code = code;
134  m_codeToValue[j].len = len;
135  m_codeToValue[j].value = i;
136  j++;
137  }
138  }
139  std::sort(m_codeToValue.begin(), m_codeToValue.end());
140 
141  // initialize the decoding cache
142  m_cacheBits = STDMIN(9U, m_maxCodeBits);
143  m_cacheMask = (1 << m_cacheBits) - 1;
144  m_normalizedCacheMask = NormalizeCode(m_cacheMask, m_cacheBits);
145  CRYPTOPP_ASSERT(m_normalizedCacheMask == BitReverse(m_cacheMask));
146 
147  const word64 shiftedCache = ((word64)1 << m_cacheBits);
148  CRYPTOPP_ASSERT(shiftedCache <= SIZE_MAX);
149  if (m_cache.size() != shiftedCache)
150  m_cache.resize((size_t)shiftedCache);
151 
152  for (i=0; i<m_cache.size(); i++)
153  m_cache[i].type = 0;
154 }
155 
156 void HuffmanDecoder::FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const
157 {
158  normalizedCode &= m_normalizedCacheMask;
159  const CodeInfo &codeInfo = *(std::upper_bound(m_codeToValue.begin(), m_codeToValue.end(), normalizedCode, CodeLessThan())-1);
160  if (codeInfo.len <= m_cacheBits)
161  {
162  entry.type = 1;
163  entry.value = codeInfo.value;
164  entry.len = codeInfo.len;
165  }
166  else
167  {
168  entry.begin = &codeInfo;
169  const CodeInfo *last = & *(std::upper_bound(m_codeToValue.begin(), m_codeToValue.end(), normalizedCode + ~m_normalizedCacheMask, CodeLessThan())-1);
170  if (codeInfo.len == last->len)
171  {
172  entry.type = 2;
173  entry.len = codeInfo.len;
174  }
175  else
176  {
177  entry.type = 3;
178  entry.end = last+1;
179  }
180  }
181 }
182 
183 inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value) const
184 {
185  CRYPTOPP_ASSERT(((int)(code & m_cacheMask)) < (int)m_cache.size());
186  LookupEntry &entry = m_cache[code & m_cacheMask];
187 
188  code_t normalizedCode = 0;
189  if (entry.type != 1)
190  normalizedCode = BitReverse(code);
191 
192  if (entry.type == 0)
193  FillCacheEntry(entry, normalizedCode);
194 
195  if (entry.type == 1)
196  {
197  value = entry.value;
198  return entry.len;
199  }
200  else
201  {
202  const CodeInfo &codeInfo = (entry.type == 2)
203  ? entry.begin[(normalizedCode << m_cacheBits) >> (MAX_CODE_BITS - (entry.len - m_cacheBits))]
204  : *(std::upper_bound(entry.begin, entry.end, normalizedCode, CodeLessThan())-1);
205  value = codeInfo.value;
206  return codeInfo.len;
207  }
208 }
209 
210 bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const
211 {
212  bool result = reader.FillBuffer(m_maxCodeBits);
213  CRYPTOPP_UNUSED(result); // CRYPTOPP_ASSERT(result);
214 
215  unsigned int codeBits = Decode(reader.PeekBuffer(), value);
216  if (codeBits > reader.BitsBuffered())
217  return false;
218  reader.SkipBits(codeBits);
219  return true;
220 }
221 
222 // *************************************************************
223 
224 Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation)
225  : AutoSignaling<Filter>(propagation)
226  , m_state(PRE_STREAM), m_repeat(repeat), m_eof(0), m_wrappedAround(0)
227  , m_blockType(0xff), m_storedLen(0xffff), m_nextDecode(), m_literal(0)
228  , m_distance(0), m_reader(m_inQueue), m_current(0), m_lastFlush(0)
229 {
230  Detach(attachment);
231 }
232 
234 {
235  m_state = PRE_STREAM;
236  parameters.GetValue("Repeat", m_repeat);
237  m_inQueue.Clear();
238  m_reader.SkipBits(m_reader.BitsBuffered());
239 }
240 
241 void Inflator::OutputByte(byte b)
242 {
243  m_window[m_current++] = b;
244  if (m_current == m_window.size())
245  {
246  ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
247  m_lastFlush = 0;
248  m_current = 0;
249  m_wrappedAround = true;
250  }
251 }
252 
253 void Inflator::OutputString(const byte *string, size_t length)
254 {
255  while (length)
256  {
257  size_t len = UnsignedMin(length, m_window.size() - m_current);
258  std::memcpy(m_window + m_current, string, len);
259  m_current += len;
260  if (m_current == m_window.size())
261  {
262  ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
263  m_lastFlush = 0;
264  m_current = 0;
265  m_wrappedAround = true;
266  }
267  string += len;
268  length -= len;
269  }
270 }
271 
272 void Inflator::OutputPast(unsigned int length, unsigned int distance)
273 {
274  size_t start;
275  if (distance <= m_current)
276  start = m_current - distance;
277  else if (m_wrappedAround && distance <= m_window.size())
278  start = m_current + m_window.size() - distance;
279  else
280  throw BadBlockErr();
281 
282  if (start + length > m_window.size())
283  {
284  for (; start < m_window.size(); start++, length--)
285  OutputByte(m_window[start]);
286  start = 0;
287  }
288 
289  if (start + length > m_current || m_current + length >= m_window.size())
290  {
291  while (length--)
292  OutputByte(m_window[start++]);
293  }
294  else
295  {
296  std::memcpy(m_window + m_current, m_window + start, length);
297  m_current += length;
298  }
299 }
300 
301 size_t Inflator::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
302 {
303  if (!blocking)
304  throw BlockingInputOnly("Inflator");
305 
306  LazyPutter lp(m_inQueue, inString, length);
307  ProcessInput(messageEnd != 0);
308 
309  if (messageEnd)
310  if (!(m_state == PRE_STREAM || m_state == AFTER_END))
311  throw UnexpectedEndErr();
312 
313  Output(0, NULLPTR, 0, messageEnd, blocking);
314  return 0;
315 }
316 
317 bool Inflator::IsolatedFlush(bool hardFlush, bool blocking)
318 {
319  if (!blocking)
320  throw BlockingInputOnly("Inflator");
321 
322  if (hardFlush)
323  ProcessInput(true);
324  FlushOutput();
325 
326  return false;
327 }
328 
329 void Inflator::ProcessInput(bool flush)
330 {
331  while (true)
332  {
333  switch (m_state)
334  {
335  case PRE_STREAM:
336  if (!flush && m_inQueue.CurrentSize() < MaxPrestreamHeaderSize())
337  return;
338  ProcessPrestreamHeader();
339  m_state = WAIT_HEADER;
340  m_wrappedAround = false;
341  m_current = 0;
342  m_lastFlush = 0;
343  m_window.New(((size_t) 1) << GetLog2WindowSize());
344  break;
345  case WAIT_HEADER:
346  {
347  // maximum number of bytes before actual compressed data starts
348  const size_t MAX_HEADER_SIZE = BitsToBytes(3+5+5+4+19*7+286*15+19*15);
349  if (m_inQueue.CurrentSize() < (flush ? 1 : MAX_HEADER_SIZE))
350  return;
351  DecodeHeader();
352  break;
353  }
354  case DECODING_BODY:
355  if (!DecodeBody())
356  return;
357  break;
358  case POST_STREAM:
359  if (!flush && m_inQueue.CurrentSize() < MaxPoststreamTailSize())
360  return;
361  ProcessPoststreamTail();
362  m_state = m_repeat ? PRE_STREAM : AFTER_END;
363  Output(0, NULLPTR, 0, GetAutoSignalPropagation(), true); // TODO: non-blocking
364  if (m_inQueue.IsEmpty())
365  return;
366  break;
367  case AFTER_END:
368  m_inQueue.TransferTo(*AttachedTransformation());
369  return;
370  }
371  }
372 }
373 
374 void Inflator::DecodeHeader()
375 {
376  if (!m_reader.FillBuffer(3))
377  throw UnexpectedEndErr();
378  m_eof = m_reader.GetBits(1) != 0;
379  m_blockType = (byte)m_reader.GetBits(2);
380 
381  switch (m_blockType)
382  {
383  case 0: // stored
384  {
385  m_reader.SkipBits(m_reader.BitsBuffered() % 8);
386  if (!m_reader.FillBuffer(32))
387  throw UnexpectedEndErr();
388  m_storedLen = (word16)m_reader.GetBits(16);
389  word16 nlen = (word16)m_reader.GetBits(16);
390  if (nlen != (word16)~m_storedLen)
391  throw BadBlockErr();
392  break;
393  }
394  case 1: // fixed codes
395  m_nextDecode = LITERAL;
396  break;
397  case 2: // dynamic codes
398  {
399  if (!m_reader.FillBuffer(5+5+4))
400  throw UnexpectedEndErr();
401  unsigned int hlit = m_reader.GetBits(5);
402  unsigned int hdist = m_reader.GetBits(5);
403  unsigned int hclen = m_reader.GetBits(4);
404  unsigned int i = 0;
405 
407  static const unsigned int border[] = { // Order of the bit length code lengths
408  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
409  std::fill(codeLengths.begin(), codeLengths+19, 0);
410  for (i=0; i<hclen+4; ++i)
411  {
412  CRYPTOPP_ASSERT(border[i] < codeLengths.size());
413  codeLengths[border[i]] = m_reader.GetBits(3);
414  }
415 
416  try
417  {
418  bool result = false;
419  unsigned int k=0, count=0, repeater=0;
420  HuffmanDecoder codeLengthDecoder(codeLengths, 19);
421  for (i=0; i < hlit+257+hdist+1; )
422  {
423  k = 0, count = 0, repeater = 0;
424  result = codeLengthDecoder.Decode(m_reader, k);
425  if (!result)
426  throw UnexpectedEndErr();
427  if (k <= 15)
428  {
429  count = 1;
430  repeater = k;
431  }
432  else switch (k)
433  {
434  case 16:
435  if (!m_reader.FillBuffer(2))
436  throw UnexpectedEndErr();
437  count = 3 + m_reader.GetBits(2);
438  if (i == 0)
439  throw BadBlockErr();
440  repeater = codeLengths[i-1];
441  break;
442  case 17:
443  if (!m_reader.FillBuffer(3))
444  throw UnexpectedEndErr();
445  count = 3 + m_reader.GetBits(3);
446  repeater = 0;
447  break;
448  case 18:
449  if (!m_reader.FillBuffer(7))
450  throw UnexpectedEndErr();
451  count = 11 + m_reader.GetBits(7);
452  repeater = 0;
453  break;
454  }
455  if (i + count > hlit+257+hdist+1)
456  throw BadBlockErr();
457  std::fill(codeLengths + i, codeLengths + i + count, repeater);
458  i += count;
459  }
460  m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257);
461  if (hdist == 0 && codeLengths[hlit+257] == 0)
462  {
463  if (hlit != 0) // a single zero distance code length means all literals
464  throw BadBlockErr();
465  }
466  else
467  m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1);
468  m_nextDecode = LITERAL;
469  }
470  catch (HuffmanDecoder::Err &)
471  {
472  throw BadBlockErr();
473  }
474  break;
475  }
476  default:
477  throw BadBlockErr(); // reserved block type
478  }
479  m_state = DECODING_BODY;
480 }
481 
482 bool Inflator::DecodeBody()
483 {
484  bool blockEnd = false;
485  switch (m_blockType)
486  {
487  case 0: // stored
488  CRYPTOPP_ASSERT(m_reader.BitsBuffered() == 0);
489  while (!m_inQueue.IsEmpty() && !blockEnd)
490  {
491  size_t size;
492  const byte *block = m_inQueue.Spy(size);
493  size = UnsignedMin(m_storedLen, size);
494  CRYPTOPP_ASSERT(size <= 0xffff);
495 
496  OutputString(block, size);
497  m_inQueue.Skip(size);
498  m_storedLen = m_storedLen - (word16)size;
499  if (m_storedLen == 0)
500  blockEnd = true;
501  }
502  break;
503  case 1: // fixed codes
504  case 2: // dynamic codes
505  static const unsigned int lengthStarts[] = {
506  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
507  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
508  static const unsigned int lengthExtraBits[] = {
509  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
510  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
511  static const unsigned int distanceStarts[] = {
512  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
513  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
514  8193, 12289, 16385, 24577};
515  static const unsigned int distanceExtraBits[] = {
516  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
517  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
518  12, 12, 13, 13};
519 
520  const HuffmanDecoder& literalDecoder = GetLiteralDecoder();
521  const HuffmanDecoder& distanceDecoder = GetDistanceDecoder();
522 
523  switch (m_nextDecode)
524  {
525  case LITERAL:
526  while (true)
527  {
528  if (!literalDecoder.Decode(m_reader, m_literal))
529  {
530  m_nextDecode = LITERAL;
531  break;
532  }
533  if (m_literal < 256)
534  OutputByte((byte)m_literal);
535  else if (m_literal == 256) // end of block
536  {
537  blockEnd = true;
538  break;
539  }
540  else
541  {
542  if (m_literal > 285)
543  throw BadBlockErr();
544  unsigned int bits;
545  case LENGTH_BITS:
546  CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthExtraBits));
547  bits = lengthExtraBits[m_literal-257];
548  if (!m_reader.FillBuffer(bits))
549  {
550  m_nextDecode = LENGTH_BITS;
551  break;
552  }
553  CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthStarts));
554  m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257];
555  case DISTANCE:
556  if (!distanceDecoder.Decode(m_reader, m_distance))
557  {
558  m_nextDecode = DISTANCE;
559  break;
560  }
561  case DISTANCE_BITS:
562  CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits));
563  if (m_distance >= COUNTOF(distanceExtraBits))
564  throw BadDistanceErr();
565  bits = distanceExtraBits[m_distance];
566  if (!m_reader.FillBuffer(bits))
567  {
568  m_nextDecode = DISTANCE_BITS;
569  break;
570  }
571  CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceStarts));
572  if (m_distance >= COUNTOF(distanceStarts))
573  throw BadDistanceErr();
574  m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance];
575  OutputPast(m_literal, m_distance);
576  }
577  }
578  break;
579  default:
580  CRYPTOPP_ASSERT(0);
581  }
582  }
583  if (blockEnd)
584  {
585  if (m_eof)
586  {
587  FlushOutput();
588  m_reader.SkipBits(m_reader.BitsBuffered()%8);
589  if (m_reader.BitsBuffered())
590  {
591  // undo too much lookahead
592  SecBlockWithHint<byte, 4> buffer(m_reader.BitsBuffered() / 8);
593  for (unsigned int i=0; i<buffer.size(); i++)
594  buffer[i] = (byte)m_reader.GetBits(8);
595  m_inQueue.Unget(buffer, buffer.size());
596  }
597  m_state = POST_STREAM;
598  }
599  else
600  m_state = WAIT_HEADER;
601  }
602  return blockEnd;
603 }
604 
605 void Inflator::FlushOutput()
606 {
607  if (m_state != PRE_STREAM)
608  {
609  CRYPTOPP_ASSERT(m_current >= m_lastFlush);
610  ProcessDecompressedData(m_window + m_lastFlush, m_current - m_lastFlush);
611  m_lastFlush = m_current;
612  }
613 }
614 
615 void Inflator::CreateFixedLiteralDecoder()
616 {
617  unsigned int codeLengths[288];
618  std::fill(codeLengths + 0, codeLengths + 144, 8);
619  std::fill(codeLengths + 144, codeLengths + 256, 9);
620  std::fill(codeLengths + 256, codeLengths + 280, 7);
621  std::fill(codeLengths + 280, codeLengths + 288, 8);
622  m_fixedLiteralDecoder.reset(new HuffmanDecoder);
623  m_fixedLiteralDecoder->Initialize(codeLengths, 288);
624 }
625 
626 void Inflator::CreateFixedDistanceDecoder()
627 {
628  unsigned int codeLengths[32];
629  std::fill(codeLengths + 0, codeLengths + 32, 5);
630  m_fixedDistanceDecoder.reset(new HuffmanDecoder);
631  m_fixedDistanceDecoder->Initialize(codeLengths, 32);
632 }
633 
634 const HuffmanDecoder& Inflator::GetLiteralDecoder()
635 {
636  if (m_blockType == 1)
637  {
638  if (m_fixedLiteralDecoder.get() == NULLPTR)
639  CreateFixedLiteralDecoder();
640  return *m_fixedLiteralDecoder;
641  }
642  else
643  {
644  return m_dynamicLiteralDecoder;
645  }
646 }
647 
648 const HuffmanDecoder& Inflator::GetDistanceDecoder()
649 {
650  if (m_blockType == 1)
651  {
652  if (m_fixedDistanceDecoder.get() == NULLPTR)
653  CreateFixedDistanceDecoder();
654  return *m_fixedDistanceDecoder;
655  }
656  else
657  {
658  return m_dynamicDistanceDecoder;
659  }
660 }
661 
662 NAMESPACE_END
Provides auto signaling support.
Definition: simple.h:423
int GetAutoSignalPropagation() const
Retrieve automatic signal propagation value.
Definition: simple.h:439
Interface for buffered transformations.
Definition: cryptlib.h:1657
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
move transferMax bytes of the buffered output to target as input
Definition: cryptlib.h:1996
virtual lword Skip(lword skipMax=LWORD_MAX)
Discard skipMax bytes from the output buffer.
lword CurrentSize() const
Determine data size.
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
void Clear()
Empty the queue.
void Unget(byte inByte)
Insert data in the queue.
bool IsEmpty() const
Determine data availability.
Implementation of BufferedTransformation's attachment interface.
Definition: filters.h:36
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
void Detach(BufferedTransformation *newAttachment=NULL)
Replace an attached transformation.
Fixed size stack-based SecBlock.
Definition: secblock.h:1246
Huffman Decoder.
Definition: zinflate.h:40
Exception thrown when a truncated stream is encountered.
Definition: zinflate.h:104
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition: zinflate.cpp:233
Inflator(BufferedTransformation *attachment=NULL, bool repeat=false, int autoSignalPropagation=-1)
RFC 1951 Decompressor.
Definition: zinflate.cpp:224
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: zinflate.cpp:301
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
Definition: zinflate.cpp:317
Helper class to finalize Puts on ByteQueue.
Definition: queue.h:219
Interface for retrieving values given their names.
Definition: cryptlib.h:327
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:384
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:1126
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
Stack-based SecBlock that grows into the heap.
Definition: secblock.h:1268
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
unsigned short word16
16-bit unsigned datatype
Definition: config_int.h:69
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:101
byte BitReverse(byte value)
Reverses bits in a 8-bit value.
Definition: misc.h:2319
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:193
#define SIZE_MAX
The maximum value of a machine word.
Definition: misc.h:120
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Definition: misc.h:1143
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:657
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Definition: misc.h:695
Crypto++ library namespace.
Precompiled header file.
Classes and functions for secure memory allocations.
Classes for automatic resource management.
Exception thrown by objects that have not implemented nonblocking input processing.
Definition: cryptlib.h:1789
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
DEFLATE compression and decompression (RFC 1951)