Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

# gzip.cpp

    00001 // gzip.cpp - written and placed in the public domain by Wei Dai
    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);               // general flag
    00017         AttachedTransformation()->PutWord32(0); // time stamp
    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, unsigned int length)
    00024 {
    00025         m_crc.Update(inString, length);
    00026         m_totalLen += 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();       // skip extra flags
    00055         if (!m_inQueue.Get(flags)) throw HeaderErr();
    00056         if (flags & (ENCRYPTED | CONTINUED)) throw HeaderErr();
    00057         if (m_inQueue.Skip(6)!=6) throw HeaderErr();    // Skip file time, extra flags and OS type
    00058
    00059         if (flags & EXTRA_FIELDS)       // skip 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)   // skip filename
    00067                 do
    00068                         if(!m_inQueue.Get(b)) throw HeaderErr();
    00069                 while (b);
    00070
    00071         if (flags & COMMENTS)   // skip comments
    00072                 do
    00073                         if(!m_inQueue.Get(b)) throw HeaderErr();
    00074                 while (b);
    00075 }
    00076
    00077 void Gunzip::ProcessDecompressedData(const byte *inString, unsigned int length)
    00078 {
    00079         AttachedTransformation()->Put(inString, length);
    00080         m_crc.Update(inString, length);
    00081         m_length += 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