zlib.hpp
Go to the documentation of this file.
/*
restinio
*/
#pragma once
#include <restinio/impl/include_fmtlib.hpp>
#include <restinio/impl/string_caseless_compare.hpp>
#include <restinio/exception.hpp>
#include <restinio/string_view.hpp>
#include <restinio/message_builders.hpp>
#include <restinio/request_handler.hpp>
#include <zlib.h>
#include <string>
#include <cstring>
namespace restinio
{
namespace transforms
{
namespace zlib
{
constexpr std::size_t default_output_reserve_buffer_size = 256 * 1024;
constexpr int default_window_bits = MAX_WBITS;
constexpr int default_mem_level = MAX_MEM_LEVEL;
constexpr int default_strategy = Z_DEFAULT_STRATEGY;
//
// params_t
//
/*
@since v.0.4.4
\note There is a special case for compression format: format_t::identity.
If this format is set that zlib transformator is transparently copies
input to output and so all other params are ignored.
*/
class params_t
{
public:
enum class operation_t
{
compress,
decompress
};
enum class format_t
{
deflate,
gzip,
/*
Means that no compression will be used and no header/trailer will be applied.
*/
identity
};
params_t(
operation_t op,
format_t f,
int l = -1 )
: m_operation{ op }
, m_format{ f }
{
level( l );
}
params_t()
: m_operation{ operation_t::compress }
, m_format{ format_t::identity }
{
level( -1 );
}
operation_t operation() const { return m_operation; }
format_t format() const { return m_format; }
int level() const { return m_level; }
params_t &
level( int level_value ) &
{
if( level_value < -1 || level_value > 9 )
{
throw exception_t{
fmt::format(
"invalid compression level: {}, must be "
"an integer value in the range of -1 to 9",
level_value ) };
}
m_level = level_value;
return reference_to_self();
}
params_t &&
level( int level_value ) &&
{
return std::move( this->level( level_value ) );
}
int window_bits() const { return m_window_bits; }
params_t &
window_bits( int window_bits_value ) &
{
// From https://zlib.net/manual.html:
// For the current implementation of deflate(),
// a windowBits value of 8 (a window size of 256 bytes)
// is not supported. As a result, a request for 8 will result in 9
// (a 512-byte window). In that case, providing 8 to inflateInit2()
// will result in an error when the zlib header with 9 is
// checked against the initialization of inflate().
// The remedy is to not use 8 with deflateInit2()
// with this initialization, or at least in that case use 9
// with inflateInit2().
// ...
// windowBits can also be zero to request that inflate
// use the window size in the zlib header of the compressed
// stream.
if( ( window_bits_value < 8 || window_bits_value > MAX_WBITS ) &&
( 0 != window_bits_value || operation_t::decompress != operation() ) )
{
throw exception_t{
fmt::format(
"invalid window_bits: {}, must be "
"an integer value in the range of 8 to {} or "
"0 for decompress operation",
window_bits_value,
MAX_WBITS ) };
}
if( 8 == window_bits_value )
window_bits_value = 9;
m_window_bits = window_bits_value;
return reference_to_self();
}
params_t &&
window_bits( int window_bits_value ) &&
{
return std::move( this->window_bits( window_bits_value ) );
}
int mem_level() const { return m_mem_level; }
params_t &
mem_level( int mem_level_value ) &
{
if( mem_level_value < 1 || mem_level_value > MAX_MEM_LEVEL )
{
throw exception_t{
fmt::format(
"invalid compression mem_level: {}, must be "
"an integer value in the range of 1 to {}",
mem_level_value,
MAX_MEM_LEVEL ) };
}
m_mem_level = mem_level_value;
return reference_to_self();
}
params_t &&
mem_level( int mem_level_value ) &&
{
return std::move( this->mem_level( mem_level_value ) );
}
int strategy() const { return m_strategy; }
params_t &
strategy( int strategy_value ) &
{
if( Z_DEFAULT_STRATEGY != strategy_value &&
Z_FILTERED != strategy_value &&
Z_HUFFMAN_ONLY != strategy_value &&
Z_RLE != strategy_value )
{
throw exception_t{
fmt::format(
"invalid compression strategy: {}, must be "
"one of: "
"Z_DEFAULT_STRATEGY({}), ",
"Z_FILTERED({}), ",
"Z_HUFFMAN_ONLY({}), ",
"Z_RLE({})",
strategy_value,
Z_DEFAULT_STRATEGY,
Z_FILTERED,
Z_HUFFMAN_ONLY,
Z_RLE ) };
}
m_strategy = strategy_value;
return reference_to_self();
}
params_t &&
strategy( int strategy_value ) &&
{
return std::move( this->strategy( strategy_value ) );
}
std::size_t reserve_buffer_size() const { return m_reserve_buffer_size; }
params_t &
reserve_buffer_size( std::size_t size ) &
{
if( size < 10UL )
{
throw exception_t{ "too small reserve buffer size" };
}
m_reserve_buffer_size = size;
return reference_to_self();
}
params_t &&
reserve_buffer_size( std::size_t size ) &&
{
return std::move( this->reserve_buffer_size( size ) );
}
private:
params_t & reference_to_self() { return *this; }
operation_t m_operation;
format_t m_format;
int m_level;
int m_window_bits{ default_window_bits };
int m_mem_level{ default_mem_level };
int m_strategy{ default_strategy };
std::size_t m_reserve_buffer_size{ default_output_reserve_buffer_size };
};
inline params_t
make_deflate_compress_params( int compression_level = -1 )
{
return params_t{
params_t::operation_t::compress,
params_t::format_t::deflate,
compression_level };
}
inline params_t
make_deflate_decompress_params()
{
return params_t{
params_t::operation_t::decompress,
params_t::format_t::deflate };
}
inline params_t
make_gzip_compress_params( int compression_level = -1 )
{
return params_t{
params_t::operation_t::compress,
params_t::format_t::gzip,
compression_level };
}
inline params_t
make_gzip_decompress_params()
{
return params_t{
params_t::operation_t::decompress,
params_t::format_t::gzip };
}
inline params_t
make_identity_params()
{
return params_t{};
}
//
// zlib_t
//
class zlib_t
{
public:
zlib_t( const params_t & transformation_params )
: m_params{ transformation_params }
{
if( !is_identity() )
{
// Setting allocator stuff before initializing
// TODO: allocation can be done with user defined allocator.
m_zlib_stream.zalloc = Z_NULL;
m_zlib_stream.zfree = Z_NULL;
m_zlib_stream.opaque = Z_NULL;
// Track initialization result.
int init_result;
// Compression.
auto current_window_bits = m_params.window_bits();
if( params_t::format_t::gzip == m_params.format() )
{
current_window_bits += 16;
}
if( params_t::operation_t::compress == m_params.operation() )
{
// zlib format.
init_result =
deflateInit2(
&m_zlib_stream,
m_params.level(),
Z_DEFLATED,
current_window_bits,
m_params.mem_level(),
m_params.strategy() );
}
else
{
init_result =
inflateInit2(
&m_zlib_stream,
current_window_bits );
}
if( Z_OK != init_result )
{
throw exception_t{
fmt::format(
"Failed to initialize zlib stream: {}, {}",
init_result,
get_error_msg() ) };
}
m_zlib_stream_initialized = true;
// Reserve initial buffer.
inc_buffer();
}
// else => Nothing to initialize and to reserve.
}
zlib_t( const zlib_t & ) = delete;
zlib_t( zlib_t && ) = delete;
zlib_t & operator = ( const zlib_t & ) = delete;
zlib_t & operator = ( zlib_t && ) = delete;
~zlib_t()
{
if( m_zlib_stream_initialized )
{
if( params_t::operation_t::compress == m_params.operation() )
{
deflateEnd( &m_zlib_stream );
}
else
{
inflateEnd( &m_zlib_stream );
}
}
}
const params_t & params() const { return m_params; }
void
write( string_view_t input )
{
ensure_operation_in_not_completed();
if( is_identity() )
{
m_out_buffer.append( input.data(), input.size() );
m_write_pos = m_out_buffer.size();
}
else
{
if( std::numeric_limits< decltype( m_zlib_stream.avail_in ) >::max() < input.size() )
{
throw exception_t{
fmt::format(
"input data is too large: {} (max possible: {}), "
"try to break large data into pieces",
input.size(),
std::numeric_limits< decltype( m_zlib_stream.avail_in ) >::max() ) };
}
if( 0 < input.size() )
{
m_zlib_stream.next_in =
reinterpret_cast< Bytef* >( const_cast< char* >( input.data() ) );
m_zlib_stream.avail_in = static_cast< uInt >( input.size() );
if( params_t::operation_t::compress == m_params.operation() )
{
write_compress_impl( Z_NO_FLUSH );
}
else
{
write_decompress_impl( Z_NO_FLUSH );
}
}
}
}
void
flush()
{
ensure_operation_in_not_completed();
if( !is_identity() )
{
m_zlib_stream.next_in = nullptr;
m_zlib_stream.avail_in = static_cast< uInt >( 0 );
if( params_t::operation_t::compress == m_params.operation() )
{
write_compress_impl( Z_SYNC_FLUSH );
}
else
{
write_decompress_impl( Z_SYNC_FLUSH );
}
}
}
void
complete()
{
ensure_operation_in_not_completed();
if( !is_identity() )
{
m_zlib_stream.next_in = nullptr;
m_zlib_stream.avail_in = static_cast< uInt >( 0 );
if( params_t::operation_t::compress == m_params.operation() )
{
write_compress_impl( Z_FINISH );
}
else
{
write_decompress_impl( Z_FINISH );
}
}
m_operation_is_complete = true;
}
std::string
giveaway_output()
{
std::string result;
const auto data_size = m_write_pos;
std::swap( result, m_out_buffer );
m_write_pos = 0;
result.resize( data_size ); // Shrink output data.
return result;
}
auto output_size() const { return m_write_pos; }
bool is_completed() const { return m_operation_is_complete; }
private:
bool is_identity() const
{
return params_t::format_t::identity == m_params.format();
}
const char *
get_error_msg() const
{
const char * err_msg = "<no zlib error description>";
if( m_zlib_stream.msg )
err_msg = m_zlib_stream.msg;
return err_msg;
}
void
ensure_operation_in_not_completed() const
{
if( is_completed() )
throw exception_t{ "zlib operation is already completed" };
}
void
inc_buffer()
{
m_out_buffer.resize(
m_out_buffer.size() + m_params.reserve_buffer_size() );
}
auto
prepare_out_buffer()
{
m_zlib_stream.next_out =
reinterpret_cast< Bytef* >(
const_cast< char* >( m_out_buffer.data() + m_write_pos ) );
const auto provided_out_buffer_size =
m_out_buffer.size() - m_write_pos;
m_zlib_stream.avail_out =
static_cast< uInt >( provided_out_buffer_size );
return provided_out_buffer_size;
}
/*
Data and its size must be already in
`m_zlib_stream.next_in`, `m_zlib_stream.avail_in`.
*/
void
write_compress_impl( int flush )
{
while( true )
{
const auto provided_out_buffer_size = prepare_out_buffer();
int operation_result = deflate( &m_zlib_stream, flush );
if( !( Z_OK == operation_result ||
Z_BUF_ERROR == operation_result ||
( Z_STREAM_END == operation_result && Z_FINISH == flush ) ) )
{
const char * err_msg = "<no error desc>";
if( m_zlib_stream.msg )
err_msg = m_zlib_stream.msg;
throw exception_t{
fmt::format(
"unexpected result of deflate() (zlib): {}, {}",
operation_result,
err_msg ) };
}
m_write_pos += provided_out_buffer_size - m_zlib_stream.avail_out;
if( 0 == m_zlib_stream.avail_out && Z_STREAM_END != operation_result )
{
// Looks like not all the output was obtained.
// There is a minor chance that it just happened to
// occupy exactly the same space that was available,
// in that case it would go for a one redundant call to deflate.
inc_buffer();
continue;
}
if( 0 == m_zlib_stream.avail_in )
{
// All the input was consumed.
break;
}
}
}
/*
Data and its size must be already in
`m_zlib_stream.next_in`, `m_zlib_stream.avail_in`.
*/
void
write_decompress_impl( int flush )
{
while( true )
{
const auto provided_out_buffer_size = prepare_out_buffer();
int operation_result = inflate( &m_zlib_stream, flush );
if( !( Z_OK == operation_result ||
Z_BUF_ERROR == operation_result ||
Z_STREAM_END == operation_result ) )
{
throw exception_t{
fmt::format(
"unexpected result of inflate() (zlib): {}, {}",
operation_result,
get_error_msg() ) };
}
m_write_pos += provided_out_buffer_size - m_zlib_stream.avail_out;
if( 0 == m_zlib_stream.avail_out && Z_STREAM_END != operation_result )
{
// Looks like not all the output was obtained.
// There is a minor chance that it just happened to
// occupy exactly the same space that was available,
// in that case it would go for a one redundant call to deflate.
inc_buffer();
continue;
}
if( 0 == m_zlib_stream.avail_in )
{
// All the input was consumed.
break;
}
}
}
const params_t m_params;
bool m_zlib_stream_initialized{ false };
z_stream m_zlib_stream;
std::string m_out_buffer;
std::size_t m_write_pos{ 0 };
bool m_operation_is_complete{ false };
};
inline std::string
transform( string_view_t input, const params_t & params )
{
zlib_t z{ params };
z.write( input );
z.complete();
return z.giveaway_output();
}
inline std::string
deflate_compress( string_view_t input, int compression_level = -1 )
{
return transform( input, make_deflate_compress_params( compression_level ) );
}
inline std::string
deflate_decompress( string_view_t input )
{
return transform( input, make_deflate_decompress_params() );
}
inline std::string
gzip_compress( string_view_t input, int compression_level = -1 )
{
return transform( input, make_gzip_compress_params( compression_level ) );
}
inline std::string
gzip_decompress( string_view_t input )
{
return transform( input, make_gzip_decompress_params() );
}
//
// body_appender_t
//
template < typename Response_Output_Strategy >
class body_appender_t
{
body_appender_t() = delete;
};
namespace impl
{
inline void ensure_is_compression_operation( params_t::operation_t op )
{
if( params_t::operation_t::compress != op )
{
throw exception_t{ "operation is not copress" };
}
}
inline void ensure_valid_transforator( zlib_t * ztransformator )
{
if( nullptr == ztransformator )
{
throw exception_t{ "invalid body appender" };
}
}
inline std::string content_encoding_token( params_t::format_t f )
{
std::string result{ "identity" };
if( params_t::format_t::deflate == f )
{
result.assign( "deflate" );
}
if( params_t::format_t::gzip == f )
{
result.assign( "gzip" );
}
return result;
}
} /* namespace impl */
//
// body_appender_base_t
//
template < typename Response_Output_Strategy, typename Descendant >
class body_appender_base_t
{
public:
using resp_t = response_builder_t< Response_Output_Strategy >;
body_appender_base_t( const params_t & params, resp_t & resp )
: m_ztransformator{ std::make_unique< zlib_t >( params ) }
, m_resp{ resp }
{
impl::ensure_is_compression_operation(
m_ztransformator->params().operation() );
m_resp.append_header(
restinio::http_field::content_encoding,
impl::content_encoding_token(
m_ztransformator->params().format() ) );
}
body_appender_base_t( const body_appender_base_t & ) = delete;
body_appender_base_t & operator = ( const body_appender_base_t & ) = delete;
body_appender_base_t & operator = ( body_appender_base_t && ) = delete;
body_appender_base_t( body_appender_base_t && ba ) noexcept
: m_ztransformator{ std::move( ba.m_ztransformator ) }
, m_resp{ ba.m_resp }
{}
virtual ~body_appender_base_t() {}
protected:
std::unique_ptr< zlib_t > m_ztransformator;
resp_t & m_resp;
};
template < typename X_Controlled_Output, typename Descendant >
class x_controlled_output_body_appender_base_t
: public body_appender_base_t< X_Controlled_Output, Descendant >
{
public:
using base_type_t = body_appender_base_t< X_Controlled_Output, Descendant >;
using base_type_t::base_type_t;
Descendant &
append( string_view_t input )
{
impl::ensure_valid_transforator( this->m_ztransformator.get() );
this->m_ztransformator->write( input );
return static_cast< Descendant & >( *this );
}
void
complete()
{
impl::ensure_valid_transforator( this->m_ztransformator.get() );
this->m_ztransformator->complete();
this->m_resp.append_body( this->m_ztransformator->giveaway_output() );
}
};
template <>
class body_appender_t< restinio_controlled_output_t >
: public x_controlled_output_body_appender_base_t<
restinio_controlled_output_t,
body_appender_t< restinio_controlled_output_t > >
{
public:
using base_type_t =
x_controlled_output_body_appender_base_t<
restinio_controlled_output_t,
body_appender_t< restinio_controlled_output_t > >;
auto
size() const
{
impl::ensure_valid_transforator( m_ztransformator.get() );
return m_ztransformator->output_size();
}
using base_type_t::base_type_t;
};
template <>
class body_appender_t< user_controlled_output_t > final
: public x_controlled_output_body_appender_base_t<
user_controlled_output_t,
body_appender_t< user_controlled_output_t > >
{
public:
using base_type_t =
x_controlled_output_body_appender_base_t<
user_controlled_output_t,
body_appender_t< user_controlled_output_t > >;
using base_type_t::base_type_t;
auto &
flush()
{
impl::ensure_valid_transforator( m_ztransformator.get() );
m_ztransformator->flush();
m_resp
.append_body( m_ztransformator->giveaway_output() )
.flush();
return *this;
}
};
template <>
class body_appender_t< chunked_output_t > final
: public body_appender_base_t<
chunked_output_t,
body_appender_t< chunked_output_t > >
{
public:
using base_type_t =
body_appender_base_t<
chunked_output_t,
body_appender_t< chunked_output_t > >;
using base_type_t::base_type_t;
auto &
append( string_view_t input )
{
impl::ensure_valid_transforator( m_ztransformator.get() );
m_ztransformator->write( input );
return *this;
}
auto &
make_chunk( string_view_t input = string_view_t{} )
{
append( input ); // m_ztransformator is checked here.
m_ztransformator->flush(); // Flush already compressed data.
// Create a chunk with current output.
m_resp.append_chunk( m_ztransformator->giveaway_output() );
return *this;
}
void
flush()
{
impl::ensure_valid_transforator( m_ztransformator.get() );
if( !m_ztransformator->is_completed() )
{
m_ztransformator->flush();
m_resp.append_chunk( m_ztransformator->giveaway_output() );
}
m_resp.flush();
}
void
complete()
{
impl::ensure_valid_transforator( m_ztransformator.get() );
m_ztransformator->complete();
m_resp.append_chunk( m_ztransformator->giveaway_output() );
}
};
template < typename Response_Output_Strategy >
body_appender_t< Response_Output_Strategy >
body_appender(
response_builder_t< Response_Output_Strategy > & resp,
const params_t & params )
{
return body_appender_t< Response_Output_Strategy >{ params, resp };
}
template < typename Response_Output_Strategy >
body_appender_t< Response_Output_Strategy >
deflate_body_appender(
response_builder_t< Response_Output_Strategy > & resp,
int compression_level = -1 )
{
return body_appender( resp, make_deflate_compress_params( compression_level ) );
}
template < typename Response_Output_Strategy >
inline body_appender_t< Response_Output_Strategy >
gzip_body_appender(
response_builder_t< Response_Output_Strategy > & resp,
int compression_level = -1 )
{
return body_appender( resp, make_gzip_compress_params( compression_level ) );
}
template < typename Response_Output_Strategy >
inline body_appender_t< Response_Output_Strategy >
identity_body_appender(
response_builder_t< Response_Output_Strategy > & resp,
int = -1 )
{
return body_appender( resp, make_identity_params() );
}
template < typename Extra_Data, typename Handler >
decltype(auto)
handle_body(
const generic_request_t<Extra_Data> & req,
Handler && handler )
{
using restinio::impl::is_equal_caseless;
const auto content_encoding =
req.header().get_field_or( restinio::http_field::content_encoding, "identity" );
if( is_equal_caseless( content_encoding, "deflate" ) )
{
return handler( deflate_decompress( req.body() ) );
}
else if( is_equal_caseless( content_encoding, "gzip" ) )
{
return handler( gzip_decompress( req.body() ) );
}
else if( !is_equal_caseless( content_encoding, "identity" ) )
{
throw exception_t{
fmt::format( "content-encoding '{}' not supported", content_encoding ) };
}
return handler( req.body() );
}
} /* namespace zlib */
} /* namespace transforms */
} /* namespace restinio */
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::generic_request_t
HTTP Request data.
Definition: request_handler.hpp:201
restinio::generic_request_t::header
const http_request_header_t & header() const noexcept
Get request header.
Definition: request_handler.hpp:256
restinio::generic_request_t::body
const std::string & body() const noexcept
Get request body.
Definition: request_handler.hpp:263
restinio::http_header_fields_t::get_field_or
std::string get_field_or(string_view_t field_name, string_view_t default_value) const
Get field value by field name or default value if the field not found.
Definition: http_headers.hpp:1040
restinio::response_builder_t
Forbid arbitrary response_builder_t instantiations.
Definition: message_builders.hpp:243
restinio::transforms::zlib::body_appender_base_t
Base class for body appenders.
Definition: zlib.hpp:969
restinio::transforms::zlib::body_appender_base_t::m_ztransformator
std::unique_ptr< zlib_t > m_ztransformator
Definition: zlib.hpp:998
restinio::transforms::zlib::body_appender_base_t::body_appender_base_t
body_appender_base_t(body_appender_base_t &&ba) noexcept
Definition: zlib.hpp:990
restinio::transforms::zlib::body_appender_base_t::body_appender_base_t
body_appender_base_t(const body_appender_base_t &)=delete
restinio::transforms::zlib::body_appender_base_t::m_resp
resp_t & m_resp
Definition: zlib.hpp:999
restinio::transforms::zlib::body_appender_base_t::body_appender_base_t
body_appender_base_t(const params_t &params, resp_t &resp)
Definition: zlib.hpp:973
restinio::transforms::zlib::body_appender_base_t::operator=
body_appender_base_t & operator=(const body_appender_base_t &)=delete
restinio::transforms::zlib::body_appender_base_t::~body_appender_base_t
virtual ~body_appender_base_t()
Definition: zlib.hpp:995
restinio::transforms::zlib::body_appender_t< chunked_output_t >
Definition: zlib.hpp:1167
restinio::transforms::zlib::body_appender_t< chunked_output_t >::flush
void flush()
Flushes currently available compressed data with possibly creating new chunk and then flushes target ...
Definition: zlib.hpp:1213
restinio::transforms::zlib::body_appender_t< chunked_output_t >::append
auto & append(string_view_t input)
Append data to be compressed.
Definition: zlib.hpp:1182
restinio::transforms::zlib::body_appender_t< chunked_output_t >::make_chunk
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
restinio::transforms::zlib::body_appender_t< chunked_output_t >::complete
void complete()
Complete zlib transformation operation.
Definition: zlib.hpp:1228
restinio::transforms::zlib::body_appender_t< restinio_controlled_output_t >
Definition: zlib.hpp:1060
restinio::transforms::zlib::body_appender_t< restinio_controlled_output_t >::size
auto size() const
Get the size of transformed body.
Definition: zlib.hpp:1069
restinio::transforms::zlib::body_appender_t< user_controlled_output_t >
Definition: zlib.hpp:1107
restinio::transforms::zlib::body_appender_t< user_controlled_output_t >::flush
auto & flush()
Definition: zlib.hpp:1117
restinio::transforms::zlib::body_appender_t
Definition: zlib.hpp:918
restinio::transforms::zlib::body_appender_t::body_appender_t
body_appender_t()=delete
restinio::transforms::zlib::params_t
Parameters of performing data transformation with zlib.
Definition: zlib.hpp:64
restinio::transforms::zlib::params_t::m_window_bits
int m_window_bits
Definition: zlib.hpp:352
restinio::transforms::zlib::params_t::strategy
params_t && strategy(int strategy_value) &&
Set compression strategy.
Definition: zlib.hpp:300
restinio::transforms::zlib::params_t::window_bits
params_t && window_bits(int window_bits_value) &&
Set window_bits.
Definition: zlib.hpp:210
restinio::transforms::zlib::params_t::window_bits
params_t & window_bits(int window_bits_value) &
Set window_bits.
Definition: zlib.hpp:171
restinio::transforms::zlib::params_t::format
format_t format() const
Get format.
Definition: zlib.hpp:121
restinio::transforms::zlib::params_t::params_t
params_t()
Default constructor for identiry transformator.
Definition: zlib.hpp:110
restinio::transforms::zlib::params_t::level
params_t && level(int level_value) &&
Set compression level.
Definition: zlib.hpp:154
restinio::transforms::zlib::params_t::window_bits
int window_bits() const
Get window_bits.
Definition: zlib.hpp:160
restinio::transforms::zlib::params_t::format_t
format_t
Formats of compressed data.
Definition: zlib.hpp:77
restinio::transforms::zlib::params_t::format_t::gzip
@ gzip
gzip format
restinio::transforms::zlib::params_t::format_t::deflate
@ deflate
zlib format.
restinio::transforms::zlib::params_t::format_t::identity
@ identity
Identity. With semantics descrobed here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ac...
restinio::transforms::zlib::params_t::mem_level
params_t & mem_level(int mem_level_value) &
Set compression mem_level.
Definition: zlib.hpp:232
restinio::transforms::zlib::params_t::m_operation
operation_t m_operation
Transformation type.
Definition: zlib.hpp:341
restinio::transforms::zlib::params_t::mem_level
int mem_level() const
Get compression mem_level.
Definition: zlib.hpp:219
restinio::transforms::zlib::params_t::m_level
int m_level
Compression level.
Definition: zlib.hpp:350
restinio::transforms::zlib::params_t::m_reserve_buffer_size
std::size_t m_reserve_buffer_size
Size initially reserved for buffer.
Definition: zlib.hpp:357
restinio::transforms::zlib::params_t::m_strategy
int m_strategy
Definition: zlib.hpp:354
restinio::transforms::zlib::params_t::m_format
format_t m_format
Format to be used for compressed data.
Definition: zlib.hpp:344
restinio::transforms::zlib::params_t::reserve_buffer_size
params_t & reserve_buffer_size(std::size_t size) &
Set the size initially reserved for buffer.
Definition: zlib.hpp:317
restinio::transforms::zlib::params_t::level
int level() const
Get compression level.
Definition: zlib.hpp:127
restinio::transforms::zlib::params_t::reserve_buffer_size
std::size_t reserve_buffer_size() const
Get the size initially reserved for buffer.
Definition: zlib.hpp:313
restinio::transforms::zlib::params_t::reserve_buffer_size
params_t && reserve_buffer_size(std::size_t size) &&
Set the size initially reserved for buffer.
Definition: zlib.hpp:331
restinio::transforms::zlib::params_t::m_mem_level
int m_mem_level
Definition: zlib.hpp:353
restinio::transforms::zlib::params_t::params_t
params_t(operation_t op, format_t f, int l=-1)
Init constructor.
Definition: zlib.hpp:96
restinio::transforms::zlib::params_t::level
params_t & level(int level_value) &
Set compression level.
Definition: zlib.hpp:136
restinio::transforms::zlib::params_t::reference_to_self
params_t & reference_to_self()
Get the reference to self.
Definition: zlib.hpp:338
restinio::transforms::zlib::params_t::mem_level
params_t && mem_level(int mem_level_value) &&
Set compression mem_level.
Definition: zlib.hpp:251
restinio::transforms::zlib::params_t::strategy
int strategy() const
Get compression strategy.
Definition: zlib.hpp:260
restinio::transforms::zlib::params_t::operation_t
operation_t
Types of transformation.
Definition: zlib.hpp:68
restinio::transforms::zlib::params_t::operation_t::decompress
@ decompress
Decompress input data.
restinio::transforms::zlib::params_t::operation_t::compress
@ compress
Compress the input data.
restinio::transforms::zlib::params_t::operation
operation_t operation() const
Get operation.
Definition: zlib.hpp:118
restinio::transforms::zlib::params_t::strategy
params_t & strategy(int strategy_value) &
Set compression strategy.
Definition: zlib.hpp:271
restinio::transforms::zlib::x_controlled_output_body_appender_base_t
Base class for body appenders with restinio or user controlled output.
Definition: zlib.hpp:1006
restinio::transforms::zlib::x_controlled_output_body_appender_base_t::append
Descendant & append(string_view_t input)
Append a piece of data to response.
Definition: zlib.hpp:1014
restinio::transforms::zlib::x_controlled_output_body_appender_base_t::complete
void complete()
Complete zlib transformation operation.
Definition: zlib.hpp:1023
restinio::transforms::zlib::zlib_t
Zlib transformator.
Definition: zlib.hpp:475
restinio::transforms::zlib::zlib_t::zlib_t
zlib_t(const zlib_t &)=delete
restinio::transforms::zlib::zlib_t::output_size
auto output_size() const
Get current output size.
Definition: zlib.hpp:689
restinio::transforms::zlib::zlib_t::m_zlib_stream_initialized
bool m_zlib_stream_initialized
Flag: was m_zlib_stream initialized properly.
Definition: zlib.hpp:844
restinio::transforms::zlib::zlib_t::inc_buffer
void inc_buffer()
Increment internal buffer for receiving output.
Definition: zlib.hpp:721
restinio::transforms::zlib::zlib_t::m_write_pos
std::size_t m_write_pos
Next write pos in out buffer.
Definition: zlib.hpp:852
restinio::transforms::zlib::zlib_t::m_operation_is_complete
bool m_operation_is_complete
Definition: zlib.hpp:854
restinio::transforms::zlib::zlib_t::is_completed
bool is_completed() const
Is operation complete?
Definition: zlib.hpp:692
restinio::transforms::zlib::zlib_t::write
void write(string_view_t input)
Append input data.
Definition: zlib.hpp:565
restinio::transforms::zlib::zlib_t::write_compress_impl
void write_compress_impl(int flush)
Handle incoming data for compression operation.
Definition: zlib.hpp:749
restinio::transforms::zlib::zlib_t::flush
void flush()
Flush the zlib stream.
Definition: zlib.hpp:611
restinio::transforms::zlib::zlib_t::get_error_msg
const char * get_error_msg() const
Get zlib error message if it exists.
Definition: zlib.hpp:702
restinio::transforms::zlib::zlib_t::ensure_operation_in_not_completed
void ensure_operation_in_not_completed() const
Checks completion flag and throws if operation is is already completed.
Definition: zlib.hpp:713
restinio::transforms::zlib::zlib_t::prepare_out_buffer
auto prepare_out_buffer()
Prepare out buffer for receiving data.
Definition: zlib.hpp:729
restinio::transforms::zlib::zlib_t::m_params
const params_t m_params
Parameters for zlib.
Definition: zlib.hpp:837
restinio::transforms::zlib::zlib_t::m_out_buffer
std::string m_out_buffer
Output buffer.
Definition: zlib.hpp:850
restinio::transforms::zlib::zlib_t::zlib_t
zlib_t(zlib_t &&)=delete
restinio::transforms::zlib::zlib_t::is_identity
bool is_identity() const
Definition: zlib.hpp:695
restinio::transforms::zlib::zlib_t::zlib_t
zlib_t(const params_t &transformation_params)
Definition: zlib.hpp:477
restinio::transforms::zlib::zlib_t::giveaway_output
std::string giveaway_output()
Get current accumulated output data.
Definition: zlib.hpp:678
restinio::transforms::zlib::zlib_t::write_decompress_impl
void write_decompress_impl(int flush)
Handle incoming data for decompression operation.
Definition: zlib.hpp:798
restinio::transforms::zlib::zlib_t::complete
void complete()
Complete the stream.
Definition: zlib.hpp:633
restinio::transforms::zlib::zlib_t::operator=
zlib_t & operator=(const zlib_t &)=delete
restinio::transforms::zlib::zlib_t::params
const params_t & params() const
Get parameters of current transformation.
Definition: zlib.hpp:557
restinio::transforms::zlib::zlib_t::m_zlib_stream
z_stream m_zlib_stream
zlib stream.
Definition: zlib.hpp:847
restinio::transforms::zlib::zlib_t::~zlib_t
~zlib_t()
Definition: zlib.hpp:541
compress
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
deflateEnd
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.c:1076
deflate
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.c:763
exception.hpp
include_fmtlib.hpp
A special wrapper around fmtlib include files.
inflate
int ZEXPORT inflate(z_streamp strm, int flush)
Definition: inflate.c:622
inflateEnd
int ZEXPORT inflateEnd(z_streamp strm)
Definition: inflate.c:1277
message_builders.hpp
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:465
nonstd::optional_lite::swap
void swap(optional< T > &x, optional< T > &y)
Definition: optional.hpp:1705
restinio::impl::is_equal_caseless
bool is_equal_caseless(const char *a, const char *b, std::size_t size) noexcept
Comparator for fields names.
Definition: string_caseless_compare.hpp:40
restinio::transforms::zlib::impl::content_encoding_token
std::string content_encoding_token(params_t::format_t f)
Get token for copression format.
Definition: zlib.hpp:944
restinio::transforms::zlib::impl::ensure_is_compression_operation
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
restinio::transforms::zlib::impl::ensure_valid_transforator
void ensure_valid_transforator(zlib_t *ztransformator)
Check if a pointer to zlib transformator is valid.
Definition: zlib.hpp:935
restinio::transforms::zlib::make_gzip_compress_params
params_t make_gzip_compress_params(int compression_level=-1)
Definition: zlib.hpp:397
restinio::transforms::zlib::make_gzip_decompress_params
params_t make_gzip_decompress_params()
Definition: zlib.hpp:406
restinio::transforms::zlib::gzip_decompress
std::string gzip_decompress(string_view_t input)
Definition: zlib.hpp:906
restinio::transforms::zlib::default_mem_level
constexpr int default_mem_level
Definition: zlib.hpp:47
restinio::transforms::zlib::transform
std::string transform(string_view_t input, const params_t &params)
Do a specified zlib transformation.
Definition: zlib.hpp:878
restinio::transforms::zlib::make_deflate_compress_params
params_t make_deflate_compress_params(int compression_level=-1)
Definition: zlib.hpp:380
restinio::transforms::zlib::default_strategy
constexpr int default_strategy
Definition: zlib.hpp:48
restinio::transforms::zlib::deflate_decompress
std::string deflate_decompress(string_view_t input)
Definition: zlib.hpp:894
restinio::transforms::zlib::handle_body
decltype(auto) handle_body(const generic_request_t< Extra_Data > &req, Handler &&handler)
Call a handler over a request body.
Definition: zlib.hpp:1317
restinio::transforms::zlib::deflate_compress
std::string deflate_compress(string_view_t input, int compression_level=-1)
Definition: zlib.hpp:888
restinio::transforms::zlib::deflate_body_appender
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
restinio::transforms::zlib::gzip_body_appender
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
restinio::transforms::zlib::default_output_reserve_buffer_size
constexpr std::size_t default_output_reserve_buffer_size
Default reserve buffer size for zlib transformator.
Definition: zlib.hpp:38
restinio::transforms::zlib::identity_body_appender
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
restinio::transforms::zlib::make_identity_params
params_t make_identity_params()
Definition: zlib.hpp:414
restinio::transforms::zlib::gzip_compress
std::string gzip_compress(string_view_t input, int compression_level=-1)
Definition: zlib.hpp:900
restinio::transforms::zlib::body_appender
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
restinio::transforms::zlib::make_deflate_decompress_params
params_t make_deflate_decompress_params()
Definition: zlib.hpp:389
restinio::transforms::zlib::default_window_bits
constexpr int default_window_bits
Definition: zlib.hpp:46
restinio
Definition: asio_include.hpp:21
restinio::string_view_t
nonstd::string_view string_view_t
Definition: string_view.hpp:19
std
STL namespace.
request_handler.hpp
string_caseless_compare.hpp
Helpers for caseless comparison of strings.
string_view.hpp
restinio::chunked_output_t
Tag type for chunked output response builder.
Definition: message_builders.hpp:622
restinio::restinio_controlled_output_t
Tag type for RESTinio controlled output response builder.
Definition: message_builders.hpp:248
restinio::user_controlled_output_t
Tag type for user controlled output response builder.
Definition: message_builders.hpp:392
z_stream_s
Definition: zlib.h:86
z_stream_s::avail_in
uInt avail_in
Definition: zlib.h:88
z_stream_s::zalloc
alloc_func zalloc
Definition: zlib.h:98
z_stream_s::avail_out
uInt avail_out
Definition: zlib.h:92
z_stream_s::next_in
z_const Bytef * next_in
Definition: zlib.h:87
z_stream_s::zfree
free_func zfree
Definition: zlib.h:99
z_stream_s::opaque
voidpf opaque
Definition: zlib.h:100
z_stream_s::next_out
Bytef * next_out
Definition: zlib.h:91
z_stream_s::msg
z_const char * msg
Definition: zlib.h:95
uInt
unsigned int uInt
Definition: zconf.h:393
MAX_MEM_LEVEL
#define MAX_MEM_LEVEL
Definition: zconf.h:260
MAX_WBITS
#define MAX_WBITS
Definition: zconf.h:270
Bytef
Byte FAR Bytef
Definition: zconf.h:400
zlib.h
Z_HUFFMAN_ONLY
#define Z_HUFFMAN_ONLY
Definition: zlib.h:197
Z_DEFLATED
#define Z_DEFLATED
Definition: zlib.h:209
Z_BUF_ERROR
#define Z_BUF_ERROR
Definition: zlib.h:184
Z_DEFAULT_STRATEGY
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:200
deflateInit2
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition: zlib.h:1797
inflateInit2
#define inflateInit2(strm, windowBits)
Definition: zlib.h:1800
Z_STREAM_END
#define Z_STREAM_END
Definition: zlib.h:178
Z_FINISH
#define Z_FINISH
Definition: zlib.h:172
Z_OK
#define Z_OK
Definition: zlib.h:177
Z_SYNC_FLUSH
#define Z_SYNC_FLUSH
Definition: zlib.h:170
Z_NO_FLUSH
#define Z_NO_FLUSH
Definition: zlib.h:168
Z_NULL
#define Z_NULL
Definition: zlib.h:212
Z_FILTERED
#define Z_FILTERED
Definition: zlib.h:196
Z_RLE
#define Z_RLE
Definition: zlib.h:198