00001
00002
00003 #include "pch.h"
00004 #include "gzip.h"
00005
00006 NAMESPACE_BEGIN(CryptoPP)
00007
00008 void Gzip::WritePrestreamHeader()
00009 {
00010 m_totalLen = 0;
00011 m_crc.Restart();
00012
00013 AttachedTransformation()->Put(MAGIC1);
00014 AttachedTransformation()->Put(MAGIC2);
00015 AttachedTransformation()->Put(DEFLATED);
00016 AttachedTransformation()->Put(0);
00017 AttachedTransformation()->PutWord32(0);
00018 byte extra = (GetDeflateLevel() == 1) ? FAST : ((GetDeflateLevel() == 9) ? SLOW : 0);
00019 AttachedTransformation()->Put(extra);
00020 AttachedTransformation()->Put(GZIP_OS_CODE);
00021 }
00022
00023 void Gzip::ProcessUncompressedData(const byte *inString, size_t length)
00024 {
00025 m_crc.Update(inString, length);
00026 m_totalLen += (word32)length;
00027 }
00028
00029 void Gzip::WritePoststreamTail()
00030 {
00031 SecByteBlock crc(4);
00032 m_crc.Final(crc);
00033 AttachedTransformation()->Put(crc, 4);
00034 AttachedTransformation()->PutWord32(m_totalLen, LITTLE_ENDIAN_ORDER);
00035 }
00036
00037
00038
00039 Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation)
00040 : Inflator(attachment, repeat, propagation)
00041 {
00042 }
00043
00044 void Gunzip::ProcessPrestreamHeader()
00045 {
00046 m_length = 0;
00047 m_crc.Restart();
00048
00049 byte buf[6];
00050 byte b, flags;
00051
00052 if (m_inQueue.Get(buf, 2)!=2) throw HeaderErr();
00053 if (buf[0] != MAGIC1 || buf[1] != MAGIC2) throw HeaderErr();
00054 if (!m_inQueue.Skip(1)) throw HeaderErr();
00055 if (!m_inQueue.Get(flags)) throw HeaderErr();
00056 if (flags & (ENCRYPTED | CONTINUED)) throw HeaderErr();
00057 if (m_inQueue.Skip(6)!=6) throw HeaderErr();
00058
00059 if (flags & EXTRA_FIELDS)
00060 {
00061 word16 length;
00062 if (m_inQueue.GetWord16(length, LITTLE_ENDIAN_ORDER) != 2) throw HeaderErr();
00063 if (m_inQueue.Skip(length)!=length) throw HeaderErr();
00064 }
00065
00066 if (flags & FILENAME)
00067 do
00068 if(!m_inQueue.Get(b)) throw HeaderErr();
00069 while (b);
00070
00071 if (flags & COMMENTS)
00072 do
00073 if(!m_inQueue.Get(b)) throw HeaderErr();
00074 while (b);
00075 }
00076
00077 void Gunzip::ProcessDecompressedData(const byte *inString, size_t length)
00078 {
00079 AttachedTransformation()->Put(inString, length);
00080 m_crc.Update(inString, length);
00081 m_length += (word32)length;
00082 }
00083
00084 void Gunzip::ProcessPoststreamTail()
00085 {
00086 SecByteBlock crc(4);
00087 if (m_inQueue.Get(crc, 4) != 4)
00088 throw TailErr();
00089 if (!m_crc.Verify(crc))
00090 throw CrcErr();
00091
00092 word32 lengthCheck;
00093 if (m_inQueue.GetWord32(lengthCheck, LITTLE_ENDIAN_ORDER) != 4)
00094 throw TailErr();
00095 if (lengthCheck != m_length)
00096 throw LengthErr();
00097 }
00098
00099 NAMESPACE_END