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