zlib.cpp

00001 // zlib.cpp - written and placed in the public domain by Wei Dai
00002 
00003 // "zlib" is the name of a well known C language compression library
00004 // (http://www.zlib.org) and also the name of a compression format
00005 // (RFC 1950) that the library implements. This file is part of a
00006 // complete reimplementation of the zlib compression format.
00007 
00008 #include "pch.h"
00009 #include "zlib.h"
00010 #include "zdeflate.h"
00011 #include "zinflate.h"
00012 
00013 NAMESPACE_BEGIN(CryptoPP)
00014 
00015 static const byte DEFLATE_METHOD = 8;
00016 static const byte FDICT_FLAG = 1 << 5;
00017 
00018 // *************************************************************
00019 
00020 void ZlibCompressor::WritePrestreamHeader()
00021 {
00022         m_adler32.Restart();
00023         byte cmf = DEFLATE_METHOD | ((GetLog2WindowSize()-8) << 4);
00024         byte flags = GetCompressionLevel() << 6;
00025         AttachedTransformation()->PutWord16(RoundUpToMultipleOf(cmf*256+flags, 31));
00026 }
00027 
00028 void ZlibCompressor::ProcessUncompressedData(const byte *inString, size_t length)
00029 {
00030         m_adler32.Update(inString, length);
00031 }
00032 
00033 void ZlibCompressor::WritePoststreamTail()
00034 {
00035         FixedSizeSecBlock<byte, 4> adler32;
00036         m_adler32.Final(adler32);
00037         AttachedTransformation()->Put(adler32, 4);
00038 }
00039 
00040 unsigned int ZlibCompressor::GetCompressionLevel() const
00041 {
00042         static const unsigned int deflateToCompressionLevel[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3};
00043         return deflateToCompressionLevel[GetDeflateLevel()];
00044 }
00045 
00046 // *************************************************************
00047 
00048 ZlibDecompressor::ZlibDecompressor(BufferedTransformation *attachment, bool repeat, int propagation)
00049         : Inflator(attachment, repeat, propagation)
00050 {
00051 }
00052 
00053 void ZlibDecompressor::ProcessPrestreamHeader()
00054 {
00055         m_adler32.Restart();
00056 
00057         byte cmf;
00058         byte flags;
00059 
00060         if (!m_inQueue.Get(cmf) || !m_inQueue.Get(flags))
00061                 throw HeaderErr();
00062 
00063         if ((cmf*256+flags) % 31 != 0)
00064                 throw HeaderErr();      // if you hit this exception, you're probably trying to decompress invalid data
00065 
00066         if ((cmf & 0xf) != DEFLATE_METHOD)
00067                 throw UnsupportedAlgorithm();
00068 
00069         if (flags & FDICT_FLAG)
00070                 throw UnsupportedPresetDictionary();
00071 
00072         m_log2WindowSize = 8 + (cmf >> 4);
00073 }
00074 
00075 void ZlibDecompressor::ProcessDecompressedData(const byte *inString, size_t length)
00076 {
00077         AttachedTransformation()->Put(inString, length);
00078         m_adler32.Update(inString, length);
00079 }
00080 
00081 void ZlibDecompressor::ProcessPoststreamTail()
00082 {
00083         FixedSizeSecBlock<byte, 4> adler32;
00084         if (m_inQueue.Get(adler32, 4) != 4)
00085                 throw Adler32Err();
00086         if (!m_adler32.Verify(adler32))
00087                 throw Adler32Err();
00088 }
00089 
00090 NAMESPACE_END

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