summaryrefslogtreecommitdiff
path: root/gzip.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
committerweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
commita3b6ece7ab341b5b14135baeccea7d5e4c086771 (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /gzip.cpp
downloadcryptopp-git-a3b6ece7ab341b5b14135baeccea7d5e4c086771.tar.gz
Initial revision
Diffstat (limited to 'gzip.cpp')
-rw-r--r--gzip.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/gzip.cpp b/gzip.cpp
new file mode 100644
index 00000000..2cfee9c5
--- /dev/null
+++ b/gzip.cpp
@@ -0,0 +1,99 @@
+// gzip.cpp - written and placed in the public domain by Wei Dai
+
+#include "pch.h"
+#include "gzip.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+void Gzip::WritePrestreamHeader()
+{
+ m_totalLen = 0;
+ m_crc.Restart();
+
+ AttachedTransformation()->Put(MAGIC1);
+ AttachedTransformation()->Put(MAGIC2);
+ AttachedTransformation()->Put(DEFLATED);
+ AttachedTransformation()->Put(0); // general flag
+ AttachedTransformation()->PutWord32(0); // time stamp
+ byte extra = (GetDeflateLevel() == 1) ? FAST : ((GetDeflateLevel() == 9) ? SLOW : 0);
+ AttachedTransformation()->Put(extra);
+ AttachedTransformation()->Put(GZIP_OS_CODE);
+}
+
+void Gzip::ProcessUncompressedData(const byte *inString, unsigned int length)
+{
+ m_crc.Update(inString, length);
+ m_totalLen += length;
+}
+
+void Gzip::WritePoststreamTail()
+{
+ SecByteBlock crc(4);
+ m_crc.Final(crc);
+ AttachedTransformation()->Put(crc, 4);
+ AttachedTransformation()->PutWord32(m_totalLen, LITTLE_ENDIAN_ORDER);
+}
+
+// *************************************************************
+
+Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation)
+ : Inflator(attachment, repeat, propagation)
+{
+}
+
+void Gunzip::ProcessPrestreamHeader()
+{
+ m_length = 0;
+ m_crc.Restart();
+
+ byte buf[6];
+ byte b, flags;
+
+ if (m_inQueue.Get(buf, 2)!=2) throw HeaderErr();
+ if (buf[0] != MAGIC1 || buf[1] != MAGIC2) throw HeaderErr();
+ if (!m_inQueue.Skip(1)) throw HeaderErr(); // skip extra flags
+ if (!m_inQueue.Get(flags)) throw HeaderErr();
+ if (flags & (ENCRYPTED | CONTINUED)) throw HeaderErr();
+ if (m_inQueue.Skip(6)!=6) throw HeaderErr(); // Skip file time, extra flags and OS type
+
+ if (flags & EXTRA_FIELDS) // skip extra fields
+ {
+ word16 length;
+ if (m_inQueue.GetWord16(length, LITTLE_ENDIAN_ORDER) != 2) throw HeaderErr();
+ if (m_inQueue.Skip(length)!=length) throw HeaderErr();
+ }
+
+ if (flags & FILENAME) // skip filename
+ do
+ if(!m_inQueue.Get(b)) throw HeaderErr();
+ while (b);
+
+ if (flags & COMMENTS) // skip comments
+ do
+ if(!m_inQueue.Get(b)) throw HeaderErr();
+ while (b);
+}
+
+void Gunzip::ProcessDecompressedData(const byte *inString, unsigned int length)
+{
+ AttachedTransformation()->Put(inString, length);
+ m_crc.Update(inString, length);
+ m_length += length;
+}
+
+void Gunzip::ProcessPoststreamTail()
+{
+ SecByteBlock crc(4);
+ if (m_inQueue.Get(crc, 4) != 4)
+ throw TailErr();
+ if (!m_crc.Verify(crc))
+ throw CrcErr();
+
+ word32 lengthCheck;
+ if (m_inQueue.GetWord32(lengthCheck, LITTLE_ENDIAN_ORDER) != 4)
+ throw TailErr();
+ if (lengthCheck != m_length)
+ throw LengthErr();
+}
+
+NAMESPACE_END