16 #include <fmt/format.h> 20 #include <restinio/exception.hpp> 21 #include <restinio/string_view.hpp> 22 #include <restinio/message_builders.hpp> 23 #include <restinio/request_handler.hpp> 136 if( level_value < -1 || level_value > 9 )
140 "invalid compression level: {}, must be " 141 "an integer value in the range of -1 to 9",
154 return std::move(
this->level( level_value ) );
186 if( ( window_bits_value < 8 || window_bits_value >
MAX_WBITS ) &&
191 "invalid window_bits: {}, must be " 192 "an integer value in the range of 8 to {} or " 193 "0 for decompress operation",
198 if( 8 == window_bits_value )
199 window_bits_value = 9;
210 return std::move(
this->window_bits( window_bits_value ) );
236 "invalid compression mem_level: {}, must be " 237 "an integer value in the range of 1 to {}",
251 return std::move(
this->mem_level( mem_level_value ) );
274 Z_RLE != strategy_value )
278 "invalid compression strategy: {}, must be " 280 "Z_DEFAULT_STRATEGY({}), ",
282 "Z_HUFFMAN_ONLY({}), ",
300 return std::move(
this->strategy( strategy_value ) );
319 throw exception_t{
"too small reserve buffer size" };
322 m_reserve_buffer_size = size;
331 return std::move(
this->reserve_buffer_size( size ) );
490 auto current_window_bits = m_params.window_bits();
492 if( params_t::format_t::gzip == m_params.format() )
494 current_window_bits += 16;
497 if( params_t::operation_t::compress == m_params.operation() )
506 m_params.mem_level(),
507 m_params.strategy() );
514 current_window_bits );
517 if(
Z_OK != init_result )
521 "Failed to initialize zlib stream: {}, {}",
543 if( params_t::operation_t::compress == m_params.operation() )
569 m_out_buffer.append( input.data(), input.size() );
570 m_write_pos = m_out_buffer.size();
574 if( std::numeric_limits<
decltype( m_zlib_stream.avail_in ) >::max() < input.size() )
578 "input data is too large: {} (max possible: {}), " 579 "try to break large data into pieces",
581 std::numeric_limits<
decltype( m_zlib_stream.avail_in ) >::max() ) };
584 if( 0 < input.size() )
586 m_zlib_stream.next_in =
587 reinterpret_cast< Bytef* >(
const_cast<
char* >( input.data() ) );
589 m_zlib_stream.avail_in =
static_cast< uInt >( input.size() );
591 if( params_t::operation_t::compress == m_params.operation() )
618 if( params_t::operation_t::compress == m_params.operation() )
640 if( params_t::operation_t::compress == m_params.operation() )
679 const auto data_size = m_write_pos;
680 std::swap( result, m_out_buffer );
682 result.resize( data_size );
695 return params_t::format_t::identity == m_params.format();
702 const char * err_msg =
"<no zlib error description>";
714 throw exception_t{
"zlib operation is already completed" };
722 m_out_buffer.size() + m_params.reserve_buffer_size() );
729 m_zlib_stream.next_out =
730 reinterpret_cast< Bytef* >(
731 const_cast<
char* >( m_out_buffer.data() + m_write_pos ) );
733 const auto provided_out_buffer_size =
734 m_out_buffer.size() - m_write_pos;
735 m_zlib_stream.avail_out =
736 static_cast<uInt>( provided_out_buffer_size );
738 return provided_out_buffer_size;
751 const auto provided_out_buffer_size = prepare_out_buffer();
755 if( !(
Z_OK == operation_result ||
759 const char * err_msg =
"<no error desc>";
765 "unexpected result of deflate() (zlib): {}, {}",
770 m_write_pos += provided_out_buffer_size - m_zlib_stream.avail_out;
800 const auto provided_out_buffer_size = prepare_out_buffer();
803 if( !(
Z_OK == operation_result ||
809 "unexpected result of inflate() (zlib): {}, {}",
814 m_write_pos += provided_out_buffer_size - m_zlib_stream.avail_out;
882 return z.giveaway_output();
888 return transform( input, make_deflate_compress_params( compression_level ) );
894 return transform( input, make_deflate_decompress_params() );
900 return transform( input, make_gzip_compress_params( compression_level ) );
906 return transform( input, make_gzip_decompress_params() );
914 template <
typename Response_Output_Strategy >
928 throw exception_t{
"operation is not copress" };
935 if(
nullptr == ztransformator )
937 throw exception_t{
"invalid body appender" };
944 std::string result{
"identity" };
948 result.assign(
"deflate" );
952 result.assign(
"gzip" );
965 template <
typename Response_Output_Strategy,
typename Descendant >
1001 template <
typename X_Controlled_Output,
typename Descendant >
1008 using base_type_t::base_type_t;
1117 impl::ensure_valid_transforator( m_ztransformator.get() );
1118 m_ztransformator->flush();
1120 .append_body( m_ztransformator->giveaway_output() )
1313 template <
typename Handler >
1317 const auto content_encoding =
1318 req.header().get_field_or( restinio::http_field::content_encoding,
"identity" );
1320 if( caseless_cmp( content_encoding,
"deflate" ) )
1322 return handler( deflate_decompress( req.body() ) );
1324 else if( caseless_cmp( content_encoding,
"gzip" ) )
1326 return handler( gzip_decompress( req.body() ) );
1328 else if( !caseless_cmp( content_encoding,
"identity" ) )
1331 fmt::format(
"content-encoding '{}' not supported", content_encoding ) };
1334 return handler( req.body() );
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
void complete()
Complete zlib transformation operation.
void complete()
Complete zlib transformation operation.
std::unique_ptr< zlib_t > m_ztransformator
virtual ~body_appender_base_t()
body_appender_base_t & operator=(const body_appender_base_t &)=delete
#define inflateInit2(strm, windowBits)
body_appender_base_t(body_appender_base_t &&ba)
body_appender_base_t & operator=(body_appender_base_t &&)=delete
body_appender_base_t(const body_appender_base_t &)=delete
Base class for body appenders with restinio or user controlled output.
#define Z_DEFAULT_STRATEGY
Base class for body appenders.
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
body_appender_base_t(const params_t ¶ms, resp_t &resp)
Descendant & append(string_view_t input)
Append a piece of data to response.