00001
00002
00003
00004
00005
00006
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();
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