~zooko/cryptopp/trunk

1 by weidai
Initial revision
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 = (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, unsigned int length)
24
{
25
	m_crc.Update(inString, length);
26
	m_totalLen += length;
27
}
28
29
void Gzip::WritePoststreamTail()
30
{
31
	SecByteBlock crc(4);
32
	m_crc.Final(crc);
33
	AttachedTransformation()->Put(crc, 4);
34
	AttachedTransformation()->PutWord32(m_totalLen, LITTLE_ENDIAN_ORDER);
35
}
36
37
// *************************************************************
38
39
Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation)
40
	: Inflator(attachment, repeat, propagation)
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, unsigned int length)
78
{
79
	AttachedTransformation()->Put(inString, length);
80
	m_crc.Update(inString, length);
81
	m_length += 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