Crypto++  5.6.4
Free C++ class library of cryptographic schemes
gzip.cpp
1 // gzip.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "gzip.h"
5 
6 NAMESPACE_BEGIN(CryptoPP)
7 
8 void Gzip::WritePrestreamHeader()
9 {
10  m_totalLen = 0;
11  m_crc.Restart();
12 
13  AttachedTransformation()->Put(MAGIC1);
14  AttachedTransformation()->Put(MAGIC2);
15  AttachedTransformation()->Put(DEFLATED);
16  AttachedTransformation()->Put(0); // general flag
17  AttachedTransformation()->PutWord32(0); // time stamp
18  byte extra = byte((GetDeflateLevel() == 1) ? FAST : ((GetDeflateLevel() == 9) ? SLOW : 0));
19  AttachedTransformation()->Put(extra);
20  AttachedTransformation()->Put(GZIP_OS_CODE);
21 }
22 
23 void Gzip::ProcessUncompressedData(const byte *inString, size_t length)
24 {
25  m_crc.Update(inString, length);
26  m_totalLen += (word32)length;
27 }
28 
29 void Gzip::WritePoststreamTail()
30 {
31  SecByteBlock crc(4);
32  m_crc.Final(crc);
33  AttachedTransformation()->Put(crc, 4);
35 }
36 
37 // *************************************************************
38 
39 Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation)
40  : Inflator(attachment, repeat, propagation), m_length(0)
41 {
42 }
43 
44 void Gunzip::ProcessPrestreamHeader()
45 {
46  m_length = 0;
47  m_crc.Restart();
48 
49  byte buf[6];
50  byte b, flags;
51 
52  if (m_inQueue.Get(buf, 2)!=2) throw HeaderErr();
53  if (buf[0] != MAGIC1 || buf[1] != MAGIC2) throw HeaderErr();
54  if (!m_inQueue.Skip(1)) throw HeaderErr(); // skip extra flags
55  if (!m_inQueue.Get(flags)) throw HeaderErr();
56  if (flags & (ENCRYPTED | CONTINUED)) throw HeaderErr();
57  if (m_inQueue.Skip(6)!=6) throw HeaderErr(); // Skip file time, extra flags and OS type
58 
59  if (flags & EXTRA_FIELDS) // skip extra fields
60  {
61  word16 length;
62  if (m_inQueue.GetWord16(length, LITTLE_ENDIAN_ORDER) != 2) throw HeaderErr();
63  if (m_inQueue.Skip(length)!=length) throw HeaderErr();
64  }
65 
66  if (flags & FILENAME) // skip filename
67  do
68  if(!m_inQueue.Get(b)) throw HeaderErr();
69  while (b);
70 
71  if (flags & COMMENTS) // skip comments
72  do
73  if(!m_inQueue.Get(b)) throw HeaderErr();
74  while (b);
75 }
76 
77 void Gunzip::ProcessDecompressedData(const byte *inString, size_t length)
78 {
79  AttachedTransformation()->Put(inString, length);
80  m_crc.Update(inString, length);
81  m_length += (word32)length;
82 }
83 
84 void Gunzip::ProcessPoststreamTail()
85 {
86  SecByteBlock crc(4);
87  if (m_inQueue.Get(crc, 4) != 4)
88  throw TailErr();
89  if (!m_crc.Verify(crc))
90  throw CrcErr();
91 
92  word32 lengthCheck;
93  if (m_inQueue.GetWord32(lengthCheck, LITTLE_ENDIAN_ORDER) != 4)
94  throw TailErr();
95  if (lengthCheck != m_length)
96  throw LengthErr();
97 }
98 
99 NAMESPACE_END
SecBlock typedef.
Definition: secblock.h:731
Interface for buffered transformations.
Definition: cryptlib.h:1359
byte order is little-endian
Definition: cryptlib.h:130
Gunzip(BufferedTransformation *attachment=NULL, bool repeat=false, int autoSignalPropagation=-1)
Construct a Gunzip decompressor.
Definition: gzip.cpp:39
GZIP compression and decompression (RFC 1952)
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1385
virtual void Restart()
Restart the hash.
Definition: cryptlib.h:968
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
Definition: filters.cpp:36
virtual bool Verify(const byte *digest)
Verifies the hash of the current message.
Definition: cryptlib.h:1018
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: crc.cpp:132
size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true)
Input a 32-bit word for processing.
Definition: cryptlib.cpp:719
DEFLATE (RFC 1951) decompressor.
Definition: zinflate.h:88
Crypto++ library namespace.
GZIP Compression (RFC 1952)
Definition: gzip.h:18
virtual void Final(byte *digest)
Computes the hash of the current message.
Definition: cryptlib.h:963