12#ifndef OPENVPN_BUFFER_ZLIB_H
13#define OPENVPN_BUFFER_ZLIB_H
30using namespace numeric_util;
43 std::memset(&s, 0,
sizeof(s));
47 ZStreamBase(
const ZStreamBase &) =
delete;
48 ZStreamBase &operator=(
const ZStreamBase &) =
delete;
51inline BufferPtr compress_gzip(BufferPtr src,
52 const size_t headroom,
53 const size_t tailroom,
55 const int window_bits = 15,
56 const int mem_level = 8)
58 constexpr int GZIP_ENCODING = 16;
60 struct ZStream :
public ZStreamBase
72 zs.s.next_in = src->data();
73 zs.s.avail_in =
numeric_cast<
decltype(zs.s.avail_in)>(src->size());
74 status = ::deflateInit2(&zs.s,
77 GZIP_ENCODING + window_bits,
81 OPENVPN_THROW(zlib_error,
"zlib deflateinit2 failed, error=" << status);
82 const uLong outcap = ::deflateBound(&zs.s, src->size());
83 auto b = BufferAllocatedRc::Create(outcap + headroom + tailroom, 0);
84 b->init_headroom(headroom);
85 zs.s.next_out = b->data();
86 zs.s.avail_out =
numeric_cast<
decltype(zs.s.avail_out)>(outcap);
87 status = ::deflate(&zs.s, Z_FINISH);
88 if (status != Z_STREAM_END)
89 OPENVPN_THROW(zlib_error,
"zlib deflate failed, error=" << status);
90 b->set_size(zs.s.total_out);
97inline BufferPtr decompress_gzip(BufferPtr src,
98 const size_t headroom,
99 const size_t tailroom,
100 const size_t max_size,
101 const size_t block_size = 4096,
102 const int window_bits = 15)
104 constexpr int GZIP_ENCODING = 16;
106 struct ZStream :
public ZStreamBase
118 zs.s.next_in = src->data();
119 zs.s.avail_in =
numeric_cast<
decltype(zs.s.avail_in)>(src->size());
120 status = ::inflateInit2(&zs.s, GZIP_ENCODING + window_bits);
122 OPENVPN_THROW(zlib_error,
"zlib inflateinit2 failed, error=" << status);
125 size_t hr = headroom;
126 size_t tr = tailroom;
131 auto b = BufferAllocatedRc::Create(block_size + hr + tr, 0);
132 b->init_headroom(hr);
133 const size_t avail = b->remaining(tr);
134 zs.s.next_out = b->data();
136 status = ::inflate(&zs.s, Z_SYNC_FLUSH);
137 if (status != Z_OK && status != Z_STREAM_END)
138 OPENVPN_THROW(zlib_error,
"zlib inflate failed, error=" << status);
139 b->set_size(avail - zs.s.avail_out);
140 blist.push_back(std::move(b));
141 if (max_size && zs.s.total_out > max_size)
142 OPENVPN_THROW(zlib_error,
"zlib inflate max_size " << max_size <<
" exceeded");
144 }
while (status == Z_OK);
145 return blist.join(headroom, tailroom,
true);
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_THROW(exc, stuff)
OutT numeric_cast(InT inVal)
Tests attempted casts to ensure the input value does not exceed the capacity of the output type.
OutT clamp_to_typerange(InT inVal)
Clamps the input value to the legal range for the output type.
Support deferred server-side state creation when client connects.
BufferCollection< std::list > BufferList
RCPtr< BufferAllocatedRc > BufferPtr