1  
//
1  
//
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2025 Mohammad Nejati
3  
// Copyright (c) 2025 Mohammad Nejati
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/cppalliance/http
8  
// Official repository: https://github.com/cppalliance/http
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_HTTP_ZLIB_DEFLATE_HPP
11  
#ifndef BOOST_HTTP_ZLIB_DEFLATE_HPP
12  
#define BOOST_HTTP_ZLIB_DEFLATE_HPP
12  
#define BOOST_HTTP_ZLIB_DEFLATE_HPP
13  

13  

14  
#include <boost/http/detail/config.hpp>
14  
#include <boost/http/detail/config.hpp>
15  
#include <boost/http/zlib/service.hpp>
15  
#include <boost/http/zlib/service.hpp>
16  
#include <boost/http/zlib/stream.hpp>
16  
#include <boost/http/zlib/stream.hpp>
17  

17  

18  
#include <boost/capy/ex/execution_context.hpp>
18  
#include <boost/capy/ex/execution_context.hpp>
19  

19  

20  
#include <cstddef>
20  
#include <cstddef>
21  

21  

22  
namespace boost {
22  
namespace boost {
23  
namespace http {
23  
namespace http {
24  
namespace zlib {
24  
namespace zlib {
25  

25  

26  
/** Provides the ZLib compression API.
26  
/** Provides the ZLib compression API.
27  

27  

28  
    This service interface exposes the ZLib deflate (compression)
28  
    This service interface exposes the ZLib deflate (compression)
29  
    functionality through a set of virtual functions. The deflate
29  
    functionality through a set of virtual functions. The deflate
30  
    algorithm compresses data by finding repeated byte sequences
30  
    algorithm compresses data by finding repeated byte sequences
31  
    and encoding them efficiently using a combination of LZ77 and
31  
    and encoding them efficiently using a combination of LZ77 and
32  
    Huffman coding.
32  
    Huffman coding.
33  

33  

34  
    The windowBits parameter in init2() controls the format:
34  
    The windowBits parameter in init2() controls the format:
35  
    - 8..15: zlib format with specified window size
35  
    - 8..15: zlib format with specified window size
36  
    - -8..-15: raw deflate format (no header/trailer)
36  
    - -8..-15: raw deflate format (no header/trailer)
37  
    - 16+windowBits: gzip format
37  
    - 16+windowBits: gzip format
38  

38  

39  
    @code
39  
    @code
40  
    // Example: Basic compression
40  
    // Example: Basic compression
41  
    boost::http::datastore ctx;
41  
    boost::http::datastore ctx;
42  
    auto& deflate_svc = boost::http::zlib::install_deflate_service(ctx);
42  
    auto& deflate_svc = boost::http::zlib::install_deflate_service(ctx);
43  

43  

44  
    boost::http::zlib::stream st = {};
44  
    boost::http::zlib::stream st = {};
45  
    std::vector<unsigned char> input_data = get_data();
45  
    std::vector<unsigned char> input_data = get_data();
46  
    std::vector<unsigned char> output(input_data.size() * 2);
46  
    std::vector<unsigned char> output(input_data.size() * 2);
47  

47  

48  
    st.zalloc = nullptr;
48  
    st.zalloc = nullptr;
49  
    st.zfree = nullptr;
49  
    st.zfree = nullptr;
50  
    st.opaque = nullptr;
50  
    st.opaque = nullptr;
51  

51  

52  
    deflate_svc.init(st, boost::http::zlib::default_compression);
52  
    deflate_svc.init(st, boost::http::zlib::default_compression);
53  

53  

54  
    st.avail_in = input_data.size();
54  
    st.avail_in = input_data.size();
55  
    st.next_in = input_data.data();
55  
    st.next_in = input_data.data();
56  
    st.avail_out = output.size();
56  
    st.avail_out = output.size();
57  
    st.next_out = output.data();
57  
    st.next_out = output.data();
58  

58  

59  
    deflate_svc.deflate(st, boost::http::zlib::finish);
59  
    deflate_svc.deflate(st, boost::http::zlib::finish);
60  
    output.resize(st.total_out);
60  
    output.resize(st.total_out);
61  

61  

62  
    deflate_svc.deflate_end(st);
62  
    deflate_svc.deflate_end(st);
63  
    @endcode
63  
    @endcode
64  

64  

65  
    @code
65  
    @code
66  
    // Example: Gzip compression with custom window size
66  
    // Example: Gzip compression with custom window size
67  
    boost::http::zlib::stream st = {};
67  
    boost::http::zlib::stream st = {};
68  
    st.zalloc = nullptr;
68  
    st.zalloc = nullptr;
69  
    st.zfree = nullptr;
69  
    st.zfree = nullptr;
70  

70  

71  
    // Use gzip format (16 + 15 for max window)
71  
    // Use gzip format (16 + 15 for max window)
72  
    deflate_svc.init2(st,
72  
    deflate_svc.init2(st,
73  
        6,                                      // level
73  
        6,                                      // level
74  
        boost::http::zlib::deflated,           // method
74  
        boost::http::zlib::deflated,           // method
75  
        16 + 15,                                // gzip format
75  
        16 + 15,                                // gzip format
76  
        8,                                      // memLevel
76  
        8,                                      // memLevel
77  
        boost::http::zlib::default_strategy);   // strategy
77  
        boost::http::zlib::default_strategy);   // strategy
78  

78  

79  
    // Compress data...
79  
    // Compress data...
80  
    deflate_svc.deflate_end(st);
80  
    deflate_svc.deflate_end(st);
81  
    @endcode
81  
    @endcode
82  
*/
82  
*/
83  
struct BOOST_SYMBOL_VISIBLE
83  
struct BOOST_SYMBOL_VISIBLE
84  
    deflate_service
84  
    deflate_service
85  
    : capy::execution_context::service
85  
    : capy::execution_context::service
86  
{
86  
{
87  
    /** Return the ZLib version string. */
87  
    /** Return the ZLib version string. */
88  
    virtual char const* version() const noexcept = 0;
88  
    virtual char const* version() const noexcept = 0;
89  

89  

90  
    /** Initialize deflate compression.
90  
    /** Initialize deflate compression.
91  
        @param st The stream to initialize.
91  
        @param st The stream to initialize.
92  
        @param level The compression level.
92  
        @param level The compression level.
93  
        @return Zero on success, or an error code.
93  
        @return Zero on success, or an error code.
94  
    */
94  
    */
95  
    virtual int init(stream& st, int level) const = 0;
95  
    virtual int init(stream& st, int level) const = 0;
96  

96  

97  
    /** Initialize deflate compression with extended parameters.
97  
    /** Initialize deflate compression with extended parameters.
98  
        @param st The stream to initialize.
98  
        @param st The stream to initialize.
99  
        @param level The compression level.
99  
        @param level The compression level.
100  
        @param method The compression method.
100  
        @param method The compression method.
101  
        @param windowBits The base-2 logarithm of the window size.
101  
        @param windowBits The base-2 logarithm of the window size.
102  
        @param memLevel Memory usage level (1-9).
102  
        @param memLevel Memory usage level (1-9).
103  
        @param strategy The compression strategy.
103  
        @param strategy The compression strategy.
104  
        @return Zero on success, or an error code.
104  
        @return Zero on success, or an error code.
105  
    */
105  
    */
106  
    virtual int init2(stream& st, int level, int method,
106  
    virtual int init2(stream& st, int level, int method,
107  
        int windowBits, int memLevel, int strategy) const = 0;
107  
        int windowBits, int memLevel, int strategy) const = 0;
108  

108  

109  
    /** Set the compression dictionary.
109  
    /** Set the compression dictionary.
110  
        @param st The stream.
110  
        @param st The stream.
111  
        @param dict Pointer to the dictionary data.
111  
        @param dict Pointer to the dictionary data.
112  
        @param len Length of the dictionary.
112  
        @param len Length of the dictionary.
113  
        @return Zero on success, or an error code.
113  
        @return Zero on success, or an error code.
114  
    */
114  
    */
115  
    virtual int set_dict(stream& st, unsigned char const* dict, unsigned len) const = 0;
115  
    virtual int set_dict(stream& st, unsigned char const* dict, unsigned len) const = 0;
116  

116  

117  
    /** Return the current compression dictionary.
117  
    /** Return the current compression dictionary.
118  
        @param st The stream.
118  
        @param st The stream.
119  
        @param dest Destination buffer for the dictionary.
119  
        @param dest Destination buffer for the dictionary.
120  
        @param len Pointer to variable receiving dictionary length.
120  
        @param len Pointer to variable receiving dictionary length.
121  
        @return Zero on success, or an error code.
121  
        @return Zero on success, or an error code.
122  
    */
122  
    */
123  
    virtual int get_dict(stream& st, unsigned char* dest, unsigned* len) const = 0;
123  
    virtual int get_dict(stream& st, unsigned char* dest, unsigned* len) const = 0;
124  

124  

125  
    /** Duplicate a deflate stream.
125  
    /** Duplicate a deflate stream.
126  
        @param dest The destination stream.
126  
        @param dest The destination stream.
127  
        @param src The source stream to duplicate.
127  
        @param src The source stream to duplicate.
128  
        @return Zero on success, or an error code.
128  
        @return Zero on success, or an error code.
129  
    */
129  
    */
130  
    virtual int dup(stream& dest, stream& src) const = 0;
130  
    virtual int dup(stream& dest, stream& src) const = 0;
131  

131  

132  
    /** Compress data in the stream.
132  
    /** Compress data in the stream.
133  
        @param st The stream containing data to compress.
133  
        @param st The stream containing data to compress.
134  
        @param flush The flush mode.
134  
        @param flush The flush mode.
135  
        @return Status code indicating compression state.
135  
        @return Status code indicating compression state.
136  
    */
136  
    */
137  
    virtual int deflate(stream& st, int flush) const = 0;
137  
    virtual int deflate(stream& st, int flush) const = 0;
138  

138  

139  
    /** Release all resources held by the deflate stream.
139  
    /** Release all resources held by the deflate stream.
140  
        @param st The stream to finalize.
140  
        @param st The stream to finalize.
141  
        @return Zero on success, or an error code.
141  
        @return Zero on success, or an error code.
142  
    */
142  
    */
143  
    virtual int deflate_end(stream& st) const = 0;
143  
    virtual int deflate_end(stream& st) const = 0;
144  

144  

145  
    /** Reset the deflate stream state.
145  
    /** Reset the deflate stream state.
146  
        @param st The stream to reset.
146  
        @param st The stream to reset.
147  
        @return Zero on success, or an error code.
147  
        @return Zero on success, or an error code.
148  
    */
148  
    */
149  
    virtual int reset(stream& st) const = 0;
149  
    virtual int reset(stream& st) const = 0;
150  

150  

151  
    /** Dynamically update compression parameters.
151  
    /** Dynamically update compression parameters.
152  
        @param st The stream.
152  
        @param st The stream.
153  
        @param level The new compression level.
153  
        @param level The new compression level.
154  
        @param strategy The new compression strategy.
154  
        @param strategy The new compression strategy.
155  
        @return Zero on success, or an error code.
155  
        @return Zero on success, or an error code.
156  
    */
156  
    */
157  
    virtual int params(stream& st, int level, int strategy) const = 0;
157  
    virtual int params(stream& st, int level, int strategy) const = 0;
158  

158  

159  
    /** Return an upper bound on compressed size.
159  
    /** Return an upper bound on compressed size.
160  
        @param st The stream.
160  
        @param st The stream.
161  
        @param sourceLen The length of source data.
161  
        @param sourceLen The length of source data.
162  
        @return Maximum possible compressed size.
162  
        @return Maximum possible compressed size.
163  
    */
163  
    */
164  
    virtual std::size_t bound(stream& st, unsigned long sourceLen) const = 0;
164  
    virtual std::size_t bound(stream& st, unsigned long sourceLen) const = 0;
165  

165  

166  
    /** Return the number of pending output bytes.
166  
    /** Return the number of pending output bytes.
167  
        @param st The stream.
167  
        @param st The stream.
168  
        @param pending Pointer to variable receiving pending byte count.
168  
        @param pending Pointer to variable receiving pending byte count.
169  
        @param bits Pointer to variable receiving pending bit count.
169  
        @param bits Pointer to variable receiving pending bit count.
170  
        @return Zero on success, or an error code.
170  
        @return Zero on success, or an error code.
171  
    */
171  
    */
172  
    virtual int pending(stream& st, unsigned* pending, int* bits) const = 0;
172  
    virtual int pending(stream& st, unsigned* pending, int* bits) const = 0;
173  

173  

174  
    /** Insert bits into the compressed stream.
174  
    /** Insert bits into the compressed stream.
175  
        @param st The stream.
175  
        @param st The stream.
176  
        @param bits Number of bits to insert.
176  
        @param bits Number of bits to insert.
177  
        @param value The bit pattern to insert.
177  
        @param value The bit pattern to insert.
178  
        @return Zero on success, or an error code.
178  
        @return Zero on success, or an error code.
179  
    */
179  
    */
180  
    virtual int prime(stream& st, int bits, int value) const = 0;
180  
    virtual int prime(stream& st, int bits, int value) const = 0;
181  

181  

182  
    /** Set the gzip header information.
182  
    /** Set the gzip header information.
183  
        @param st The stream.
183  
        @param st The stream.
184  
        @param header Pointer to gzip header structure.
184  
        @param header Pointer to gzip header structure.
185  
        @return Zero on success, or an error code.
185  
        @return Zero on success, or an error code.
186  
    */
186  
    */
187  
    virtual int set_header(stream& st, void* header) const = 0;
187  
    virtual int set_header(stream& st, void* header) const = 0;
188  

188  

189  
protected:
189  
protected:
190  
    void shutdown() override {}
190  
    void shutdown() override {}
191  
};
191  
};
192  

192  

193  
} // zlib
193  
} // zlib
194  
} // http
194  
} // http
195  
} // boost
195  
} // boost
196  

196  

197  
#endif
197  
#endif