diff options
Diffstat (limited to 'src/segzip.h')
-rw-r--r-- | src/segzip.h | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/segzip.h b/src/segzip.h new file mode 100644 index 0000000..14b28e4 --- /dev/null +++ b/src/segzip.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017-2024 OARC, Inc. + * Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden + * All rights reserved. + * + * This file is part of PacketQ. + * + * PacketQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PacketQ. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __packetq_segzip_h +#define __packetq_segzip_h + +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +namespace packetq { + +class Buffer { +public: + Buffer() + { + m_buffer_len = 0; + m_buffer_pos = 0; + m_nextread = 1024; + } + int size() { return sizeof(m_buffer); } + unsigned char m_buffer[0x40000]; + int m_nextread; + int m_buffer_len; + int m_buffer_pos; +}; + +class Zip { +private: + Zip& operator=(const Zip& other); + Zip(Zip&& other) noexcept; + Zip const& operator=(Zip&& other); + +public: + Zip() + : m_stream() + { + m_init = true; + m_error = false; + m_run_end = false; + m_stream.next_out = 0; + m_stream.avail_out = 0; + } + ~Zip() + { + if (m_run_end) + ::inflateEnd(&m_stream); + } + bool inflate(Buffer& in, Buffer& out) + { + if (m_error) { + in.m_buffer_pos = in.m_buffer_len; + out.m_buffer_len = 0; + return false; + } + out.m_buffer_pos = 0; + out.m_buffer_len = sizeof(out.m_buffer); + m_stream.next_out = &out.m_buffer[out.m_buffer_pos]; + m_stream.avail_out = out.m_buffer_len - out.m_buffer_pos; + if (m_init) { + m_stream.next_in = 0; + m_stream.avail_in = 0; + m_stream.zalloc = 0; + m_stream.zfree = 0; + m_stream.opaque = 0; + m_init = false; + if (inflateInit2(&m_stream, 15 + 32) != Z_OK) { + m_error = true; + out.m_buffer_len = 0; + in.m_buffer_pos = in.m_buffer_len; + return false; + } + } + m_stream.next_in = &in.m_buffer[in.m_buffer_pos]; + m_stream.avail_in = in.m_buffer_len - in.m_buffer_pos; + + int ret = ::inflate(&m_stream, Z_NO_FLUSH); + + if (ret != Z_OK) + ::inflateEnd(&m_stream); + else + m_run_end = true; + if (ret != Z_OK && ret != Z_STREAM_END) { + m_error = true; + out.m_buffer_len = 0; + in.m_buffer_pos = in.m_buffer_len = 0; + return false; + } + + in.m_buffer_pos = in.m_buffer_len - m_stream.avail_in; + out.m_buffer_len = sizeof(out.m_buffer) - m_stream.avail_out; + out.m_buffer_pos = 0; + return true; + } + bool m_init; + bool m_run_end; + bool m_error; + z_stream m_stream; +}; + +} // namespace packetq + +#endif // __packetq_segzip_h |