RESTinio
Loading...
Searching...
No Matches
zlib.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
11#pragma once
12
14
16
21
22#include <zlib.h>
23
24#include <string>
25#include <cstring>
26
27namespace restinio
28{
29
30namespace transforms
31{
32
33namespace zlib
34{
35
38constexpr std::size_t default_output_reserve_buffer_size = 256 * 1024;
39
50
51//
52// params_t
53//
54
56/*
57 @since v.0.4.4
58
59 \note There is a special case for compression format: format_t::identity.
60 If this format is set that zlib transformator is transparently copies
61 input to output and so all other params are ignored.
62*/
64{
65 public:
67 enum class operation_t
68 {
73 };
74
76 enum class format_t
77 {
79 deflate,
81 gzip,
83 /*
84 Means that no compression will be used and no header/trailer will be applied.
85 */
87 };
88
90
98 operation_t op,
100 format_t f,
102 int l = -1 )
103 : m_operation{ op }
104 , m_format{ f }
105 {
106 level( l );
107 }
108
113 {
114 level( -1 );
115 }
116
119
121 format_t format() const { return m_format; }
122
124
127 int level() const { return m_level; }
128
130
135 params_t &
137 {
139 {
140 throw exception_t{
141 fmt::format(
142 "invalid compression level: {}, must be "
143 "an integer value in the range of -1 to 9",
144 level_value ) };
145 }
146
148
149 return reference_to_self();
150 }
151
153 params_t &&
155 {
156 return std::move( this->level( level_value ) );
157 }
158
160 int window_bits() const { return m_window_bits; }
161
163
170 params_t &
172 {
173 // From https://zlib.net/manual.html:
174 // For the current implementation of deflate(),
175 // a windowBits value of 8 (a window size of 256 bytes)
176 // is not supported. As a result, a request for 8 will result in 9
177 // (a 512-byte window). In that case, providing 8 to inflateInit2()
178 // will result in an error when the zlib header with 9 is
179 // checked against the initialization of inflate().
180 // The remedy is to not use 8 with deflateInit2()
181 // with this initialization, or at least in that case use 9
182 // with inflateInit2().
183 // ...
184 // windowBits can also be zero to request that inflate
185 // use the window size in the zlib header of the compressed
186 // stream.
187
190 {
191 throw exception_t{
192 fmt::format(
193 "invalid window_bits: {}, must be "
194 "an integer value in the range of 8 to {} or "
195 "0 for decompress operation",
197 MAX_WBITS ) };
198 }
199
200 if( 8 == window_bits_value )
202
204
205 return reference_to_self();
206 }
207
209 params_t &&
211 {
212 return std::move( this->window_bits( window_bits_value ) );
213 }
214
216
219 int mem_level() const { return m_mem_level; }
220
222
231 params_t &
233 {
235 {
236 throw exception_t{
237 fmt::format(
238 "invalid compression mem_level: {}, must be "
239 "an integer value in the range of 1 to {}",
241 MAX_MEM_LEVEL ) };
242 }
243
245
246 return reference_to_self();
247 }
248
250 params_t &&
252 {
253 return std::move( this->mem_level( mem_level_value ) );
254 }
255
257
260 int strategy() const { return m_strategy; }
261
263
270 params_t &
272 {
277 {
278 throw exception_t{
279 fmt::format(
280 "invalid compression strategy: {}, must be "
281 "one of: "
282 "Z_DEFAULT_STRATEGY({}), ",
283 "Z_FILTERED({}), ",
284 "Z_HUFFMAN_ONLY({}), ",
285 "Z_RLE({})",
290 Z_RLE ) };
291 }
292
294
295 return reference_to_self();
296 }
297
299 params_t &&
301 {
302 return std::move( this->strategy( strategy_value ) );
303 }
304
306
313 std::size_t reserve_buffer_size() const { return m_reserve_buffer_size; }
314
316 params_t &
317 reserve_buffer_size( std::size_t size ) &
318 {
319 if( size < 10UL )
320 {
321 throw exception_t{ "too small reserve buffer size" };
322 }
323
325
326 return reference_to_self();
327 }
328
330 params_t &&
331 reserve_buffer_size( std::size_t size ) &&
332 {
333 return std::move( this->reserve_buffer_size( size ) );
334 }
335
336 private:
338 params_t & reference_to_self() { return *this; }
339
342
345
347
351
355
358};
359
379inline params_t
387
388inline params_t
395
396inline params_t
404
405inline params_t
412
413inline params_t
415{
416 return params_t{};
417}
419
420//
421// zlib_t
422//
423
425
475{
476 public:
479 {
480 if( !is_identity() )
481 {
482 // Setting allocator stuff before initializing
483 // TODO: allocation can be done with user defined allocator.
487
488 // Track initialization result.
489 int init_result;
490
491 // Compression.
493
495 {
497 }
498
500 {
501 // zlib format.
505 m_params.level(),
509 m_params.strategy() );
510 }
511 else
512 {
517 }
518
519 if( Z_OK != init_result )
520 {
521 throw exception_t{
522 fmt::format(
523 "Failed to initialize zlib stream: {}, {}",
525 get_error_msg() ) };
526 }
527
529
530 // Reserve initial buffer.
531 inc_buffer();
532 }
533 // else => Nothing to initialize and to reserve.
534 }
535
536 zlib_t( const zlib_t & ) = delete;
537 zlib_t( zlib_t && ) = delete;
538 zlib_t & operator = ( const zlib_t & ) = delete;
539 zlib_t & operator = ( zlib_t && ) = delete;
540
542 {
544 {
546 {
548 }
549 else
550 {
552 }
553 }
554 }
555
557 const params_t & params() const { return m_params; }
558
560
564 void
566 {
568
569 if( is_identity() )
570 {
571 m_out_buffer.append( input.data(), input.size() );
572 m_write_pos = m_out_buffer.size();
573 }
574 else
575 {
576 if( std::numeric_limits< decltype( m_zlib_stream.avail_in ) >::max() < input.size() )
577 {
578 throw exception_t{
579 fmt::format(
580 "input data is too large: {} (max possible: {}), "
581 "try to break large data into pieces",
582 input.size(),
583 std::numeric_limits< decltype( m_zlib_stream.avail_in ) >::max() ) };
584 }
585
586 if( 0 < input.size() )
587 {
589 reinterpret_cast< Bytef* >( const_cast< char* >( input.data() ) );
590
591 m_zlib_stream.avail_in = static_cast< uInt >( input.size() );
592
594 {
596 }
597 else
598 {
600 }
601 }
602 }
603 }
604
606
610 void
612 {
614
615 if( !is_identity() )
616 {
617 m_zlib_stream.next_in = nullptr;
618 m_zlib_stream.avail_in = static_cast< uInt >( 0 );
619
621 {
623 }
624 else
625 {
627 }
628 }
629 }
630
632 void
634 {
636
637 if( !is_identity() )
638 {
639 m_zlib_stream.next_in = nullptr;
640 m_zlib_stream.avail_in = static_cast< uInt >( 0 );
641
643 {
645 }
646 else
647 {
649 }
650 }
651
653 }
654
656
677 std::string
679 {
680 std::string result;
681 const auto data_size = m_write_pos;
682 std::swap( result, m_out_buffer );
683 m_write_pos = 0;
684 result.resize( data_size ); // Shrink output data.
685 return result;
686 }
687
689 auto output_size() const { return m_write_pos; }
690
692 bool is_completed() const { return m_operation_is_complete; }
693
694 private:
695 bool is_identity() const
696 {
698 }
699
701 const char *
703 {
704 const char * err_msg = "<no zlib error description>";
705 if( m_zlib_stream.msg )
707
708 return err_msg;
709 }
710
712 void
714 {
715 if( is_completed() )
716 throw exception_t{ "zlib operation is already completed" };
717 }
718
720 void
722 {
723 m_out_buffer.resize(
725 }
726
728 auto
730 {
732 reinterpret_cast< Bytef* >(
733 const_cast< char* >( m_out_buffer.data() + m_write_pos ) );
734
735 const auto provided_out_buffer_size =
736 m_out_buffer.size() - m_write_pos;
738 static_cast<uInt>( provided_out_buffer_size );
739
741 }
742
744 /*
745 Data and its size must be already in
746 `m_zlib_stream.next_in`, `m_zlib_stream.avail_in`.
747 */
748 void
750 {
751 while( true )
752 {
754
756
757 if( !( Z_OK == operation_result ||
760 {
761 const char * err_msg = "<no error desc>";
762 if( m_zlib_stream.msg )
764
765 throw exception_t{
766 fmt::format(
767 "unexpected result of deflate() (zlib): {}, {}",
769 err_msg ) };
770 }
771
773
775 {
776 // Looks like not all the output was obtained.
777 // There is a minor chance that it just happened to
778 // occupy exactly the same space that was available,
779 // in that case it would go for a one redundant call to deflate.
780 inc_buffer();
781 continue;
782 }
783
784 if( 0 == m_zlib_stream.avail_in )
785 {
786 // All the input was consumed.
787 break;
788 }
789 }
790 }
791
793 /*
794 Data and its size must be already in
795 `m_zlib_stream.next_in`, `m_zlib_stream.avail_in`.
796 */
797 void
799 {
800 while( true )
801 {
803
805 if( !( Z_OK == operation_result ||
808 {
809 throw exception_t{
810 fmt::format(
811 "unexpected result of inflate() (zlib): {}, {}",
813 get_error_msg() ) };
814 }
815
817
819 {
820 // Looks like not all the output was obtained.
821 // There is a minor chance that it just happened to
822 // occupy exactly the same space that was available,
823 // in that case it would go for a one redundant call to deflate.
824 inc_buffer();
825 continue;
826 }
827
828 if( 0 == m_zlib_stream.avail_in )
829 {
830 // All the input was consumed.
831 break;
832 }
833 }
834 }
835
838
840
845
848
850 std::string m_out_buffer;
852 std::size_t m_write_pos{ 0 };
853
855};
856
875
877inline std::string
879{
880 zlib_t z{ params };
881 z.write( input );
882 z.complete();
883
884 return z.giveaway_output();
885}
886
887inline std::string
892
893inline std::string
898
899inline std::string
904
905inline std::string
911
912//
913// body_appender_t
914//
915
916template < typename Response_Output_Strategy >
918{
919 body_appender_t() = delete;
920};
921
922namespace impl
923{
924
927{
929 {
930 throw exception_t{ "operation is not copress" };
931 }
932}
933
936{
937 if( nullptr == ztransformator )
938 {
939 throw exception_t{ "invalid body appender" };
940 }
941}
942
945{
946 std::string result{ "identity" };
947
949 {
950 result.assign( "deflate" );
951 }
953 {
954 result.assign( "gzip" );
955 }
956
957 return result;
958}
959
960} /* namespace impl */
961
962//
963// body_appender_base_t
964//
965
967template < typename Response_Output_Strategy, typename Descendant >
969{
970 public:
972
974 : m_ztransformator{ std::make_unique< zlib_t >( params ) }
975 , m_resp{ resp }
976 {
978 m_ztransformator->params().operation() );
979
980 m_resp.append_header(
981 restinio::http_field::content_encoding,
983 m_ztransformator->params().format() ) );
984 }
985
989
991 : m_ztransformator{ std::move( ba.m_ztransformator ) }
992 , m_resp{ ba.m_resp }
993 {}
994
996
997 protected:
998 std::unique_ptr< zlib_t > m_ztransformator;
1000};
1001
1003template < typename X_Controlled_Output, typename Descendant >
1005 : public body_appender_base_t< X_Controlled_Output, Descendant >
1006{
1007 public:
1009
1010 using base_type_t::base_type_t;
1011
1013 Descendant &
1015 {
1017 this->m_ztransformator->write( input );
1018 return static_cast< Descendant & >( *this );
1019 }
1020
1022 void
1024 {
1026
1027 this->m_ztransformator->complete();
1028
1029 this->m_resp.append_body( this->m_ztransformator->giveaway_output() );
1030 }
1031};
1032
1055template <>
1058 restinio_controlled_output_t,
1059 body_appender_t< restinio_controlled_output_t > >
1060{
1061 public:
1066
1068 auto
1069 size() const
1070 {
1071 impl::ensure_valid_transforator( m_ztransformator.get() );
1072
1073 return m_ztransformator->output_size();
1074 }
1075
1076 using base_type_t::base_type_t;
1077};
1078
1102template <>
1105 user_controlled_output_t,
1106 body_appender_t< user_controlled_output_t > >
1107{
1108 public:
1113
1115
1116 auto &
1118 {
1119 impl::ensure_valid_transforator( m_ztransformator.get() );
1120 m_ztransformator->flush();
1121 m_resp
1122 .append_body( m_ztransformator->giveaway_output() )
1123 .flush();
1124
1125 return *this;
1126 }
1127};
1128
1129
1162template <>
1164 : public body_appender_base_t<
1165 chunked_output_t,
1166 body_appender_t< chunked_output_t > >
1167{
1168 public:
1173
1174 using base_type_t::base_type_t;
1175
1177
1181 auto &
1183 {
1184 impl::ensure_valid_transforator( m_ztransformator.get() );
1185
1186 m_ztransformator->write( input );
1187 return *this;
1188 }
1189
1192
1197 auto &
1199 {
1200 append( input ); // m_ztransformator is checked here.
1201
1202 m_ztransformator->flush(); // Flush already compressed data.
1203
1204 // Create a chunk with current output.
1205 m_resp.append_chunk( m_ztransformator->giveaway_output() );
1206
1207 return *this;
1208 }
1209
1212 void
1214 {
1215 impl::ensure_valid_transforator( m_ztransformator.get() );
1216
1217 if( !m_ztransformator->is_completed() )
1218 {
1219 m_ztransformator->flush();
1220 m_resp.append_chunk( m_ztransformator->giveaway_output() );
1221 }
1222
1223 m_resp.flush();
1224 }
1225
1227 void
1229 {
1230 impl::ensure_valid_transforator( m_ztransformator.get() );
1231 m_ztransformator->complete();
1232 m_resp.append_chunk( m_ztransformator->giveaway_output() );
1233 }
1234};
1235
1238template < typename Response_Output_Strategy >
1246
1249template < typename Response_Output_Strategy >
1257
1260template < typename Response_Output_Strategy >
1268
1271template < typename Response_Output_Strategy >
1279
1281
1315template < typename Extra_Data, typename Handler >
1316decltype(auto)
1319 Handler && handler )
1320{
1322
1323 const auto content_encoding =
1324 req.header().get_field_or( restinio::http_field::content_encoding, "identity" );
1325
1326 if( is_equal_caseless( content_encoding, "deflate" ) )
1327 {
1328 return handler( deflate_decompress( req.body() ) );
1329 }
1330 else if( is_equal_caseless( content_encoding, "gzip" ) )
1331 {
1332 return handler( gzip_decompress( req.body() ) );
1333 }
1334 else if( !is_equal_caseless( content_encoding, "identity" ) )
1335 {
1336 throw exception_t{
1337 fmt::format( "content-encoding '{}' not supported", content_encoding ) };
1338 }
1339
1340 return handler( req.body() );
1341}
1342
1343} /* namespace zlib */
1344
1345} /* namespace transforms */
1346
1347} /* namespace restinio */
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
Forbid arbitrary response_builder_t instantiations.
Base class for body appenders.
Definition zlib.hpp:969
std::unique_ptr< zlib_t > m_ztransformator
Definition zlib.hpp:998
body_appender_base_t(body_appender_base_t &&ba) noexcept
Definition zlib.hpp:990
body_appender_base_t(const body_appender_base_t &)=delete
body_appender_base_t(const params_t &params, resp_t &resp)
Definition zlib.hpp:973
body_appender_base_t & operator=(const body_appender_base_t &)=delete
void flush()
Flushes currently available compressed data with possibly creating new chunk and then flushes target ...
Definition zlib.hpp:1213
auto & append(string_view_t input)
Append data to be compressed.
Definition zlib.hpp:1182
auto & make_chunk(string_view_t input=string_view_t{})
Append data to be compressed and adds current zlib transformator output as a new chunk.
Definition zlib.hpp:1198
void complete()
Complete zlib transformation operation.
Definition zlib.hpp:1228
Parameters of performing data transformation with zlib.
Definition zlib.hpp:64
params_t && strategy(int strategy_value) &&
Set compression strategy.
Definition zlib.hpp:300
params_t && window_bits(int window_bits_value) &&
Set window_bits.
Definition zlib.hpp:210
params_t & window_bits(int window_bits_value) &
Set window_bits.
Definition zlib.hpp:171
format_t format() const
Get format.
Definition zlib.hpp:121
params_t()
Default constructor for identiry transformator.
Definition zlib.hpp:110
params_t && level(int level_value) &&
Set compression level.
Definition zlib.hpp:154
int window_bits() const
Get window_bits.
Definition zlib.hpp:160
format_t
Formats of compressed data.
Definition zlib.hpp:77
@ identity
Identity. With semantics descrobed here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ac...
params_t & mem_level(int mem_level_value) &
Set compression mem_level.
Definition zlib.hpp:232
operation_t m_operation
Transformation type.
Definition zlib.hpp:341
int mem_level() const
Get compression mem_level.
Definition zlib.hpp:219
int m_level
Compression level.
Definition zlib.hpp:350
std::size_t m_reserve_buffer_size
Size initially reserved for buffer.
Definition zlib.hpp:357
format_t m_format
Format to be used for compressed data.
Definition zlib.hpp:344
params_t & reserve_buffer_size(std::size_t size) &
Set the size initially reserved for buffer.
Definition zlib.hpp:317
int level() const
Get compression level.
Definition zlib.hpp:127
std::size_t reserve_buffer_size() const
Get the size initially reserved for buffer.
Definition zlib.hpp:313
params_t && reserve_buffer_size(std::size_t size) &&
Set the size initially reserved for buffer.
Definition zlib.hpp:331
params_t(operation_t op, format_t f, int l=-1)
Init constructor.
Definition zlib.hpp:96
params_t & level(int level_value) &
Set compression level.
Definition zlib.hpp:136
params_t & reference_to_self()
Get the reference to self.
Definition zlib.hpp:338
params_t && mem_level(int mem_level_value) &&
Set compression mem_level.
Definition zlib.hpp:251
int strategy() const
Get compression strategy.
Definition zlib.hpp:260
operation_t
Types of transformation.
Definition zlib.hpp:68
operation_t operation() const
Get operation.
Definition zlib.hpp:118
params_t & strategy(int strategy_value) &
Set compression strategy.
Definition zlib.hpp:271
Base class for body appenders with restinio or user controlled output.
Definition zlib.hpp:1006
Descendant & append(string_view_t input)
Append a piece of data to response.
Definition zlib.hpp:1014
void complete()
Complete zlib transformation operation.
Definition zlib.hpp:1023
zlib_t(const zlib_t &)=delete
auto output_size() const
Get current output size.
Definition zlib.hpp:689
bool m_zlib_stream_initialized
Flag: was m_zlib_stream initialized properly.
Definition zlib.hpp:844
void inc_buffer()
Increment internal buffer for receiving output.
Definition zlib.hpp:721
std::size_t m_write_pos
Next write pos in out buffer.
Definition zlib.hpp:852
bool is_completed() const
Is operation complete?
Definition zlib.hpp:692
void write(string_view_t input)
Append input data.
Definition zlib.hpp:565
void write_compress_impl(int flush)
Handle incoming data for compression operation.
Definition zlib.hpp:749
void flush()
Flush the zlib stream.
Definition zlib.hpp:611
const char * get_error_msg() const
Get zlib error message if it exists.
Definition zlib.hpp:702
void ensure_operation_in_not_completed() const
Checks completion flag and throws if operation is is already completed.
Definition zlib.hpp:713
auto prepare_out_buffer()
Prepare out buffer for receiving data.
Definition zlib.hpp:729
const params_t m_params
Parameters for zlib.
Definition zlib.hpp:837
std::string m_out_buffer
Output buffer.
Definition zlib.hpp:850
zlib_t(const params_t &transformation_params)
Definition zlib.hpp:477
std::string giveaway_output()
Get current accumulated output data.
Definition zlib.hpp:678
void write_decompress_impl(int flush)
Handle incoming data for decompression operation.
Definition zlib.hpp:798
void complete()
Complete the stream.
Definition zlib.hpp:633
zlib_t & operator=(const zlib_t &)=delete
const params_t & params() const
Get parameters of current transformation.
Definition zlib.hpp:557
z_stream m_zlib_stream
zlib stream.
Definition zlib.hpp:847
int ZEXPORT deflateEnd(z_streamp strm)
Definition deflate.c:1076
int ZEXPORT deflate(z_streamp strm, int flush)
Definition deflate.c:763
A special wrapper around fmtlib include files.
int ZEXPORT inflate(z_streamp strm, int flush)
Definition inflate.c:622
int ZEXPORT inflateEnd(z_streamp strm)
Definition inflate.c:1277
bool is_equal_caseless(const char *a, const char *b, std::size_t size) noexcept
Comparator for fields names.
std::string content_encoding_token(params_t::format_t f)
Get token for copression format.
Definition zlib.hpp:944
void ensure_is_compression_operation(params_t::operation_t op)
Check if operation is a copression, and throw if it is not.
Definition zlib.hpp:926
void ensure_valid_transforator(zlib_t *ztransformator)
Check if a pointer to zlib transformator is valid.
Definition zlib.hpp:935
params_t make_gzip_compress_params(int compression_level=-1)
Definition zlib.hpp:397
params_t make_gzip_decompress_params()
Definition zlib.hpp:406
std::string gzip_decompress(string_view_t input)
Definition zlib.hpp:906
constexpr int default_mem_level
Definition zlib.hpp:47
std::string transform(string_view_t input, const params_t &params)
Do a specified zlib transformation.
Definition zlib.hpp:878
params_t make_deflate_compress_params(int compression_level=-1)
Definition zlib.hpp:380
constexpr int default_strategy
Definition zlib.hpp:48
std::string deflate_decompress(string_view_t input)
Definition zlib.hpp:894
decltype(auto) handle_body(const generic_request_t< Extra_Data > &req, Handler &&handler)
Call a handler over a request body.
Definition zlib.hpp:1317
std::string deflate_compress(string_view_t input, int compression_level=-1)
Definition zlib.hpp:888
body_appender_t< Response_Output_Strategy > deflate_body_appender(response_builder_t< Response_Output_Strategy > &resp, int compression_level=-1)
Create body appender with deflate transformation and a given compression level.
Definition zlib.hpp:1251
body_appender_t< Response_Output_Strategy > gzip_body_appender(response_builder_t< Response_Output_Strategy > &resp, int compression_level=-1)
Create body appender with gzip transformation and a given compression level.
Definition zlib.hpp:1262
constexpr std::size_t default_output_reserve_buffer_size
Default reserve buffer size for zlib transformator.
Definition zlib.hpp:38
body_appender_t< Response_Output_Strategy > identity_body_appender(response_builder_t< Response_Output_Strategy > &resp, int=-1)
Create body appender with gzip transformation and a given compression level.
Definition zlib.hpp:1273
params_t make_identity_params()
Definition zlib.hpp:414
std::string gzip_compress(string_view_t input, int compression_level=-1)
Definition zlib.hpp:900
body_appender_t< Response_Output_Strategy > body_appender(response_builder_t< Response_Output_Strategy > &resp, const params_t &params)
Create body appender with given zlib transformation parameters.
Definition zlib.hpp:1240
params_t make_deflate_decompress_params()
Definition zlib.hpp:389
constexpr int default_window_bits
Definition zlib.hpp:46
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
nonstd::string_view string_view_t
STL namespace.
Helpers for caseless comparison of strings.
Tag type for chunked output response builder.
Tag type for RESTinio controlled output response builder.
Tag type for user controlled output response builder.
uInt avail_in
Definition zlib.h:88
alloc_func zalloc
Definition zlib.h:98
uInt avail_out
Definition zlib.h:92
z_const Bytef * next_in
Definition zlib.h:87
free_func zfree
Definition zlib.h:99
voidpf opaque
Definition zlib.h:100
Bytef * next_out
Definition zlib.h:91
z_const char * msg
Definition zlib.h:95
unsigned int uInt
Definition zconf.h:393
#define MAX_MEM_LEVEL
Definition zconf.h:260
#define MAX_WBITS
Definition zconf.h:270
Byte FAR Bytef
Definition zconf.h:400
#define Z_HUFFMAN_ONLY
Definition zlib.h:197
#define Z_DEFLATED
Definition zlib.h:209
#define Z_BUF_ERROR
Definition zlib.h:184
#define Z_DEFAULT_STRATEGY
Definition zlib.h:200
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition zlib.h:1797
#define inflateInit2(strm, windowBits)
Definition zlib.h:1800
#define Z_STREAM_END
Definition zlib.h:178
#define Z_FINISH
Definition zlib.h:172
#define Z_OK
Definition zlib.h:177
#define Z_SYNC_FLUSH
Definition zlib.h:170
#define Z_NO_FLUSH
Definition zlib.h:168
#define Z_NULL
Definition zlib.h:212
#define Z_FILTERED
Definition zlib.h:196
#define Z_RLE
Definition zlib.h:198