00001
00002
00003 #include "pch.h"
00004 #include "zlib.h"
00005 #include "zdeflate.h"
00006 #include "zinflate.h"
00007
00008 NAMESPACE_BEGIN(CryptoPP)
00009
00010 static const byte DEFLATE_METHOD = 8;
00011 static const byte FDICT_FLAG = 1 << 5;
00012
00013
00014
00015 ZlibCompressor::ZlibCompressor(BufferedTransformation *outQ, unsigned int deflateLevel, unsigned int log2WindowSize)
00016 : Deflator(outQ, deflateLevel, log2WindowSize)
00017 {
00018 }
00019
00020 void ZlibCompressor::WritePrestreamHeader()
00021 {
00022 byte cmf = DEFLATE_METHOD | ((GetLog2WindowSize()-8) << 4);
00023 byte flags = GetCompressionLevel() << 6;
00024 AttachedTransformation()->PutWord16(RoundUpToMultipleOf(cmf*256+flags, 31));
00025 }
00026
00027 void ZlibCompressor::ProcessUncompressedData(const byte *inString, unsigned int length)
00028 {
00029 m_adler32.Update(inString, length);
00030 }
00031
00032 void ZlibCompressor::WritePoststreamTail()
00033 {
00034 SecByteBlock adler32(4);
00035 m_adler32.Final(adler32);
00036 AttachedTransformation()->Put(adler32, 4);
00037 }
00038
00039 unsigned int ZlibCompressor::GetCompressionLevel() const
00040 {
00041 static const unsigned int deflateToCompressionLevel[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3};
00042 return deflateToCompressionLevel[GetDeflateLevel()];
00043 }
00044
00045
00046
00047 ZlibDecompressor::ZlibDecompressor(BufferedTransformation *outQueue, bool repeat)
00048 : Inflator(outQueue, repeat)
00049 {
00050 }
00051
00052 void ZlibDecompressor::ProcessPrestreamHeader()
00053 {
00054 byte cmf;
00055 byte flags;
00056
00057 if (!m_inQueue.Get(cmf) || !m_inQueue.Get(flags))
00058 throw HeaderErr();
00059
00060 if ((cmf*256+flags) % 31 != 0)
00061 throw HeaderErr();
00062
00063 if ((cmf & 0xf) != DEFLATE_METHOD)
00064 throw UnsupportedAlgorithm();
00065
00066 if (flags & FDICT_FLAG)
00067 throw UnsupportedPresetDictionary();
00068
00069 m_log2WindowSize = 8 + (cmf >> 4);
00070 }
00071
00072 void ZlibDecompressor::ProcessDecompressedData(const byte *inString, unsigned int length)
00073 {
00074 AttachedTransformation()->Put(inString, length);
00075 m_adler32.Update(inString, length);
00076 }
00077
00078 void ZlibDecompressor::ProcessPoststreamTail()
00079 {
00080 SecByteBlock adler32(4);
00081 if (m_inQueue.Get(adler32, 4) != 4)
00082 throw Adler32Err();
00083 if (!m_adler32.Verify(adler32))
00084 throw Adler32Err();
00085 }
00086
00087 NAMESPACE_END