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, 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();       // 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, 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

Generated on Sat Dec 23 02:07:07 2006 for Crypto++ by  doxygen 1.5.1-p1