/src/serenity/Userland/Libraries/LibCompress/Zlib.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2020, the SerenityOS developers. |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/ByteBuffer.h> |
10 | | #include <AK/Endian.h> |
11 | | #include <AK/MaybeOwned.h> |
12 | | #include <AK/Optional.h> |
13 | | #include <AK/OwnPtr.h> |
14 | | #include <AK/Span.h> |
15 | | #include <AK/Stream.h> |
16 | | #include <AK/Types.h> |
17 | | #include <LibCrypto/Checksum/Adler32.h> |
18 | | |
19 | | namespace Compress { |
20 | | |
21 | | enum class ZlibCompressionMethod : u8 { |
22 | | Deflate = 8, |
23 | | }; |
24 | | |
25 | | enum class ZlibCompressionLevel : u8 { |
26 | | Fastest, |
27 | | Fast, |
28 | | Default, |
29 | | Best, |
30 | | }; |
31 | | |
32 | | struct ZlibHeader { |
33 | | union { |
34 | | struct { |
35 | | ZlibCompressionMethod compression_method : 4; |
36 | | u8 compression_info : 4; |
37 | | |
38 | | u8 check_bits : 5; |
39 | | bool present_dictionary : 1; |
40 | | ZlibCompressionLevel compression_level : 2; |
41 | | }; |
42 | | NetworkOrdered<u16> as_u16; |
43 | | }; |
44 | | }; |
45 | | static_assert(sizeof(ZlibHeader) == sizeof(u16)); |
46 | | |
47 | | class ZlibDecompressor : public Stream { |
48 | | public: |
49 | | static ErrorOr<NonnullOwnPtr<ZlibDecompressor>> create(MaybeOwned<Stream>); |
50 | | |
51 | | virtual ErrorOr<Bytes> read_some(Bytes) override; |
52 | | virtual ErrorOr<size_t> write_some(ReadonlyBytes) override; |
53 | | virtual bool is_eof() const override; |
54 | | virtual bool is_open() const override; |
55 | | virtual void close() override; |
56 | | |
57 | | private: |
58 | | ZlibDecompressor(ZlibHeader, NonnullOwnPtr<Stream>); |
59 | | |
60 | | ZlibHeader m_header; |
61 | | NonnullOwnPtr<Stream> m_stream; |
62 | | }; |
63 | | |
64 | | class ZlibCompressor : public Stream { |
65 | | public: |
66 | | static ErrorOr<NonnullOwnPtr<ZlibCompressor>> construct(MaybeOwned<Stream>, ZlibCompressionLevel = ZlibCompressionLevel::Default); |
67 | | ~ZlibCompressor(); |
68 | | |
69 | | virtual ErrorOr<Bytes> read_some(Bytes) override; |
70 | | virtual ErrorOr<size_t> write_some(ReadonlyBytes) override; |
71 | | virtual bool is_eof() const override; |
72 | | virtual bool is_open() const override; |
73 | | virtual void close() override; |
74 | | ErrorOr<void> finish(); |
75 | | |
76 | | static ErrorOr<ByteBuffer> compress_all(ReadonlyBytes bytes, ZlibCompressionLevel = ZlibCompressionLevel::Default); |
77 | | |
78 | | private: |
79 | | ZlibCompressor(MaybeOwned<Stream> stream, NonnullOwnPtr<Stream> compressor_stream); |
80 | | ErrorOr<void> write_header(ZlibCompressionMethod, ZlibCompressionLevel); |
81 | | |
82 | | bool m_finished { false }; |
83 | | MaybeOwned<Stream> m_output_stream; |
84 | | NonnullOwnPtr<Stream> m_compressor; |
85 | | Crypto::Checksum::Adler32 m_adler32_checksum; |
86 | | }; |
87 | | |
88 | | } |
89 | | |
90 | | template<> |
91 | | struct AK::Traits<Compress::ZlibHeader> : public AK::DefaultTraits<Compress::ZlibHeader> { |
92 | 0 | static constexpr bool is_trivially_serializable() { return true; } |
93 | | }; |