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_INFLATE_HPP
11  
#ifndef BOOST_HTTP_ZLIB_INFLATE_HPP
12  
#define BOOST_HTTP_ZLIB_INFLATE_HPP
12  
#define BOOST_HTTP_ZLIB_INFLATE_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  
namespace boost {
20  
namespace boost {
21  
namespace http {
21  
namespace http {
22  
namespace zlib {
22  
namespace zlib {
23  

23  

24  
/** Provides the ZLib decompression API.
24  
/** Provides the ZLib decompression API.
25  

25  

26  
    This service interface exposes the ZLib inflate (decompression)
26  
    This service interface exposes the ZLib inflate (decompression)
27  
    functionality through a set of virtual functions. The inflate
27  
    functionality through a set of virtual functions. The inflate
28  
    algorithm reverses the deflate compression, restoring the
28  
    algorithm reverses the deflate compression, restoring the
29  
    original uncompressed data.
29  
    original uncompressed data.
30  

30  

31  
    The windowBits parameter in init2() controls format detection:
31  
    The windowBits parameter in init2() controls format detection:
32  
    - 8..15: zlib format with specified window size
32  
    - 8..15: zlib format with specified window size
33  
    - -8..-15: raw deflate format (no header/trailer)
33  
    - -8..-15: raw deflate format (no header/trailer)
34  
    - 16+windowBits: gzip format only
34  
    - 16+windowBits: gzip format only
35  
    - 32+windowBits: auto-detect zlib or gzip format
35  
    - 32+windowBits: auto-detect zlib or gzip format
36  

36  

37  
    @code
37  
    @code
38  
    // Example: Basic decompression
38  
    // Example: Basic decompression
39  
    boost::http::datastore ctx;
39  
    boost::http::datastore ctx;
40  
    auto& inflate_svc = boost::http::zlib::install_inflate_service(ctx);
40  
    auto& inflate_svc = boost::http::zlib::install_inflate_service(ctx);
41  

41  

42  
    boost::http::zlib::stream st = {};
42  
    boost::http::zlib::stream st = {};
43  
    std::vector<unsigned char> compressed_data = get_compressed();
43  
    std::vector<unsigned char> compressed_data = get_compressed();
44  
    std::vector<unsigned char> output(1024 * 1024); // 1MB buffer
44  
    std::vector<unsigned char> output(1024 * 1024); // 1MB buffer
45  

45  

46  
    st.zalloc = nullptr;
46  
    st.zalloc = nullptr;
47  
    st.zfree = nullptr;
47  
    st.zfree = nullptr;
48  
    st.opaque = nullptr;
48  
    st.opaque = nullptr;
49  

49  

50  
    inflate_svc.init(st);
50  
    inflate_svc.init(st);
51  

51  

52  
    st.avail_in = compressed_data.size();
52  
    st.avail_in = compressed_data.size();
53  
    st.next_in = compressed_data.data();
53  
    st.next_in = compressed_data.data();
54  
    st.avail_out = output.size();
54  
    st.avail_out = output.size();
55  
    st.next_out = output.data();
55  
    st.next_out = output.data();
56  

56  

57  
    inflate_svc.inflate(st, boost::http::zlib::finish);
57  
    inflate_svc.inflate(st, boost::http::zlib::finish);
58  
    output.resize(st.total_out);
58  
    output.resize(st.total_out);
59  

59  

60  
    inflate_svc.inflate_end(st);
60  
    inflate_svc.inflate_end(st);
61  
    @endcode
61  
    @endcode
62  

62  

63  
    @code
63  
    @code
64  
    // Example: Auto-detect gzip or zlib format
64  
    // Example: Auto-detect gzip or zlib format
65  
    boost::http::zlib::stream st = {};
65  
    boost::http::zlib::stream st = {};
66  
    st.zalloc = nullptr;
66  
    st.zalloc = nullptr;
67  
    st.zfree = nullptr;
67  
    st.zfree = nullptr;
68  

68  

69  
    // Auto-detect format (32 + 15 for max window)
69  
    // Auto-detect format (32 + 15 for max window)
70  
    inflate_svc.init2(st, 32 + 15);
70  
    inflate_svc.init2(st, 32 + 15);
71  

71  

72  
    st.avail_in = compressed_data.size();
72  
    st.avail_in = compressed_data.size();
73  
    st.next_in = compressed_data.data();
73  
    st.next_in = compressed_data.data();
74  
    st.avail_out = output.size();
74  
    st.avail_out = output.size();
75  
    st.next_out = output.data();
75  
    st.next_out = output.data();
76  

76  

77  
    int result = inflate_svc.inflate(st, boost::http::zlib::no_flush);
77  
    int result = inflate_svc.inflate(st, boost::http::zlib::no_flush);
78  
    // Handle result...
78  
    // Handle result...
79  

79  

80  
    inflate_svc.inflate_end(st);
80  
    inflate_svc.inflate_end(st);
81  
    @endcode
81  
    @endcode
82  
*/
82  
*/
83  
struct BOOST_SYMBOL_VISIBLE
83  
struct BOOST_SYMBOL_VISIBLE
84  
    inflate_service
84  
    inflate_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 inflate decompression.
90  
    /** Initialize inflate decompression.
91  
        @param st The stream to initialize.
91  
        @param st The stream to initialize.
92  
        @return Zero on success, or an error code.
92  
        @return Zero on success, or an error code.
93  
    */
93  
    */
94  
    virtual int init(stream& st) const = 0;
94  
    virtual int init(stream& st) const = 0;
95  

95  

96  
    /** Initialize inflate decompression with extended parameters.
96  
    /** Initialize inflate decompression with extended parameters.
97  
        @param st The stream to initialize.
97  
        @param st The stream to initialize.
98  
        @param windowBits The base-2 logarithm of the window size.
98  
        @param windowBits The base-2 logarithm of the window size.
99  
        @return Zero on success, or an error code.
99  
        @return Zero on success, or an error code.
100  
    */
100  
    */
101  
    virtual int init2(stream& st, int windowBits) const = 0;
101  
    virtual int init2(stream& st, int windowBits) const = 0;
102  

102  

103  
    /** Decompress data in the stream.
103  
    /** Decompress data in the stream.
104  
        @param st The stream containing data to decompress.
104  
        @param st The stream containing data to decompress.
105  
        @param flush The flush mode.
105  
        @param flush The flush mode.
106  
        @return Status code indicating decompression state.
106  
        @return Status code indicating decompression state.
107  
    */
107  
    */
108  
    virtual int inflate(stream& st, int flush) const = 0;
108  
    virtual int inflate(stream& st, int flush) const = 0;
109  

109  

110  
    /** Release all resources held by the inflate stream.
110  
    /** Release all resources held by the inflate stream.
111  
        @param st The stream to finalize.
111  
        @param st The stream to finalize.
112  
        @return Zero on success, or an error code.
112  
        @return Zero on success, or an error code.
113  
    */
113  
    */
114  
    virtual int inflate_end(stream& st) const = 0;
114  
    virtual int inflate_end(stream& st) const = 0;
115  

115  

116  
    /** Set the decompression dictionary.
116  
    /** Set the decompression dictionary.
117  
        @param st The stream.
117  
        @param st The stream.
118  
        @param dict Pointer to the dictionary data.
118  
        @param dict Pointer to the dictionary data.
119  
        @param len Length of the dictionary.
119  
        @param len Length of the dictionary.
120  
        @return Zero on success, or an error code.
120  
        @return Zero on success, or an error code.
121  
    */
121  
    */
122  
    virtual int set_dict(stream& st, unsigned char const* dict, unsigned len) const = 0;
122  
    virtual int set_dict(stream& st, unsigned char const* dict, unsigned len) const = 0;
123  

123  

124  
    /** Return the current decompression dictionary.
124  
    /** Return the current decompression dictionary.
125  
        @param st The stream.
125  
        @param st The stream.
126  
        @param dest Destination buffer for the dictionary.
126  
        @param dest Destination buffer for the dictionary.
127  
        @param len Pointer to variable receiving dictionary length.
127  
        @param len Pointer to variable receiving dictionary length.
128  
        @return Zero on success, or an error code.
128  
        @return Zero on success, or an error code.
129  
    */
129  
    */
130  
    virtual int get_dict(stream& st, unsigned char* dest, unsigned* len) const = 0;
130  
    virtual int get_dict(stream& st, unsigned char* dest, unsigned* len) const = 0;
131  

131  

132  
    /** Synchronize the decompression state.
132  
    /** Synchronize the decompression state.
133  
        @param st The stream to synchronize.
133  
        @param st The stream to synchronize.
134  
        @return Zero on success, or an error code.
134  
        @return Zero on success, or an error code.
135  
    */
135  
    */
136  
    virtual int sync(stream& st) const = 0;
136  
    virtual int sync(stream& st) const = 0;
137  

137  

138  
    /** Duplicate an inflate stream.
138  
    /** Duplicate an inflate stream.
139  
        @param dest The destination stream.
139  
        @param dest The destination stream.
140  
        @param src The source stream to duplicate.
140  
        @param src The source stream to duplicate.
141  
        @return Zero on success, or an error code.
141  
        @return Zero on success, or an error code.
142  
    */
142  
    */
143  
    virtual int dup(stream& dest, stream& src) const = 0;
143  
    virtual int dup(stream& dest, stream& src) const = 0;
144  

144  

145  
    /** Reset the inflate stream state.
145  
    /** Reset the inflate 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  
    /** Reset the inflate stream state with new window size.
151  
    /** Reset the inflate stream state with new window size.
152  
        @param st The stream to reset.
152  
        @param st The stream to reset.
153  
        @param windowBits The base-2 logarithm of the window size.
153  
        @param windowBits The base-2 logarithm of the window size.
154  
        @return Zero on success, or an error code.
154  
        @return Zero on success, or an error code.
155  
    */
155  
    */
156  
    virtual int reset2(stream& st, int windowBits) const = 0;
156  
    virtual int reset2(stream& st, int windowBits) const = 0;
157  

157  

158  
    /** Insert bits into the input stream.
158  
    /** Insert bits into the input stream.
159  
        @param st The stream.
159  
        @param st The stream.
160  
        @param bits Number of bits to insert.
160  
        @param bits Number of bits to insert.
161  
        @param value The bit pattern to insert.
161  
        @param value The bit pattern to insert.
162  
        @return Zero on success, or an error code.
162  
        @return Zero on success, or an error code.
163  
    */
163  
    */
164  
    virtual int prime(stream& st, int bits, int value) const = 0;
164  
    virtual int prime(stream& st, int bits, int value) const = 0;
165  

165  

166  
    /** Return the current inflate mark.
166  
    /** Return the current inflate mark.
167  
        @param st The stream.
167  
        @param st The stream.
168  
        @return The mark value, or -1 on error.
168  
        @return The mark value, or -1 on error.
169  
    */
169  
    */
170  
    virtual long mark(stream& st) const = 0;
170  
    virtual long mark(stream& st) const = 0;
171  

171  

172  
    /** Return the gzip header information.
172  
    /** Return the gzip header information.
173  
        @param st The stream.
173  
        @param st The stream.
174  
        @param header Pointer to gzip header structure.
174  
        @param header Pointer to gzip header structure.
175  
        @return Zero on success, or an error code.
175  
        @return Zero on success, or an error code.
176  
    */
176  
    */
177  
    virtual int get_header(stream& st, void* header) const = 0;
177  
    virtual int get_header(stream& st, void* header) const = 0;
178  

178  

179  
    /** Initialize backward inflate decompression.
179  
    /** Initialize backward inflate decompression.
180  
        @param st The stream to initialize.
180  
        @param st The stream to initialize.
181  
        @param windowBits The base-2 logarithm of the window size.
181  
        @param windowBits The base-2 logarithm of the window size.
182  
        @param window Pointer to the window buffer.
182  
        @param window Pointer to the window buffer.
183  
        @return Zero on success, or an error code.
183  
        @return Zero on success, or an error code.
184  
    */
184  
    */
185  
    virtual int back_init(stream& st, int windowBits, unsigned char* window) const = 0;
185  
    virtual int back_init(stream& st, int windowBits, unsigned char* window) const = 0;
186  

186  

187  
    /** Release resources held by backward inflate stream.
187  
    /** Release resources held by backward inflate stream.
188  
        @param st The stream to finalize.
188  
        @param st The stream to finalize.
189  
        @return Zero on success, or an error code.
189  
        @return Zero on success, or an error code.
190  
    */
190  
    */
191  
    virtual int back_end(stream& st) const = 0;
191  
    virtual int back_end(stream& st) const = 0;
192  

192  

193  
    /** Return ZLib compile-time flags.
193  
    /** Return ZLib compile-time flags.
194  
        @return Bit flags indicating compile-time options.
194  
        @return Bit flags indicating compile-time options.
195  
    */
195  
    */
196  
    virtual unsigned long compile_flags() const = 0;
196  
    virtual unsigned long compile_flags() const = 0;
197  

197  

198  
protected:
198  
protected:
199  
    void shutdown() override {}
199  
    void shutdown() override {}
200  
};
200  
};
201  

201  

202  
} // zlib
202  
} // zlib
203  
} // http
203  
} // http
204  
} // boost
204  
} // boost
205  

205  

206  
#endif
206  
#endif