Line |
Branch |
Exec |
Source |
1 |
|
|
// |
2 |
|
|
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) |
3 |
|
|
// |
4 |
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 |
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 |
|
|
// |
7 |
|
|
// Official repository: https://github.com/cppalliance/http_proto |
8 |
|
|
// |
9 |
|
|
|
10 |
|
|
#ifndef SRC_SERVICE_STREAM_CAST_HPP |
11 |
|
|
#define SRC_SERVICE_STREAM_CAST_HPP |
12 |
|
|
|
13 |
|
|
#include <boost/http_proto/detail/config.hpp> |
14 |
|
|
#include <boost/http_proto/service/zlib_service.hpp> |
15 |
|
|
#include <zlib.h> |
16 |
|
|
#include <cstddef> |
17 |
|
|
|
18 |
|
|
namespace boost { |
19 |
|
|
namespace http_proto { |
20 |
|
|
namespace zlib { |
21 |
|
|
|
22 |
|
|
//------------------------------------------------ |
23 |
|
|
|
24 |
|
|
#define SAME_FIELD(T1,T2,M) \ |
25 |
|
|
offsetof(T1,M)==offsetof(T2,M) && \ |
26 |
|
|
sizeof(decltype(T1::M)) == sizeof(decltype(T2::M)) |
27 |
|
|
|
28 |
|
|
template<class T1, class T2> |
29 |
|
|
constexpr |
30 |
|
|
bool |
31 |
|
|
is_layout_identical() |
32 |
|
|
{ |
33 |
|
|
return |
34 |
|
|
sizeof(T1) == sizeof(T2) && |
35 |
|
|
SAME_FIELD(T1, T2, next_in) && |
36 |
|
|
SAME_FIELD(T1, T2, avail_in) && |
37 |
|
|
SAME_FIELD(T1, T2, total_in) && |
38 |
|
|
SAME_FIELD(T1, T2, next_out) && |
39 |
|
|
SAME_FIELD(T1, T2, avail_out) && |
40 |
|
|
SAME_FIELD(T1, T2, total_out) && |
41 |
|
|
SAME_FIELD(T1, T2, msg) && |
42 |
|
|
SAME_FIELD(T1, T2, state) && |
43 |
|
|
SAME_FIELD(T1, T2, zalloc) && |
44 |
|
|
SAME_FIELD(T1, T2, zfree) && |
45 |
|
|
SAME_FIELD(T1, T2, opaque) && |
46 |
|
|
SAME_FIELD(T1, T2, data_type) && |
47 |
|
|
SAME_FIELD(T1, T2, adler) && |
48 |
|
|
SAME_FIELD(T1, T2, reserved) |
49 |
|
|
; |
50 |
|
|
} |
51 |
|
|
|
52 |
|
|
//------------------------------------------------ |
53 |
|
|
|
54 |
|
|
template<bool isLayoutIdentical = |
55 |
|
|
is_layout_identical<stream_t, z_stream_s>()> |
56 |
|
|
struct stream_cast_impl |
57 |
|
|
{ |
58 |
|
|
explicit |
59 |
|
|
stream_cast_impl( |
60 |
|
|
stream_t& st) |
61 |
|
|
: pzs_(reinterpret_cast<z_stream_s*>(&st)) |
62 |
|
|
, st_(st) |
63 |
|
|
{ |
64 |
|
|
zs_.next_in = st_.next_in; |
65 |
|
|
zs_.avail_in = st_.avail_in; |
66 |
|
|
zs_.total_in = st_.total_in; |
67 |
|
|
zs_.next_out = st_.next_out; |
68 |
|
|
zs_.avail_out = st_.avail_out; |
69 |
|
|
zs_.total_out = st_.total_out; |
70 |
|
|
zs_.msg = nullptr; |
71 |
|
|
zs_.state = reinterpret_cast< |
72 |
|
|
internal_state*>(st_.state); |
73 |
|
|
zs_.zalloc = st_.zalloc; |
74 |
|
|
zs_.zfree = st_.zfree; |
75 |
|
|
zs_.opaque = st_.opaque; |
76 |
|
|
zs_.data_type = st_.data_type; |
77 |
|
|
zs_.adler = st_.adler; |
78 |
|
|
zs_.reserved = st_.reserved; |
79 |
|
|
} |
80 |
|
|
|
81 |
|
|
~stream_cast_impl() |
82 |
|
|
{ |
83 |
|
|
st_.next_in = zs_.next_in; |
84 |
|
|
st_.avail_in = zs_.avail_in; |
85 |
|
|
st_.total_in = zs_.total_in; |
86 |
|
|
st_.next_out = zs_.next_out; |
87 |
|
|
st_.avail_out = zs_.avail_out; |
88 |
|
|
st_.total_out = zs_.total_out; |
89 |
|
|
st_.msg = zs_.msg; |
90 |
|
|
st_.state = zs_.state; |
91 |
|
|
st_.zalloc = zs_.zalloc; |
92 |
|
|
st_.zfree = zs_.zfree; |
93 |
|
|
st_.opaque = zs_.opaque; |
94 |
|
|
st_.data_type = zs_.data_type; |
95 |
|
|
st_.adler = zs_.adler; |
96 |
|
|
st_.reserved = zs_.reserved; |
97 |
|
|
} |
98 |
|
|
|
99 |
|
|
z_stream_s* |
100 |
|
|
get() noexcept |
101 |
|
|
{ |
102 |
|
|
return pzs_; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
private: |
106 |
|
|
z_stream_s* pzs_ = nullptr; |
107 |
|
|
stream_t& st_; |
108 |
|
|
z_stream_s zs_; |
109 |
|
|
}; |
110 |
|
|
|
111 |
|
|
//------------------------------------------------ |
112 |
|
|
|
113 |
|
|
template<> |
114 |
|
|
struct stream_cast_impl<true> |
115 |
|
|
{ |
116 |
|
|
explicit |
117 |
|
✗ |
stream_cast_impl( |
118 |
|
|
stream_t& st) |
119 |
|
|
// VFALCO A pinch of undefined behavior here |
120 |
|
✗ |
: pzs_(reinterpret_cast<z_stream_s*>(&st)) |
121 |
|
|
{ |
122 |
|
|
|
123 |
|
✗ |
} |
124 |
|
|
|
125 |
|
|
z_stream_s* |
126 |
|
✗ |
get() noexcept |
127 |
|
|
{ |
128 |
|
✗ |
return pzs_; |
129 |
|
|
} |
130 |
|
|
|
131 |
|
|
private: |
132 |
|
|
z_stream_s* pzs_; |
133 |
|
|
}; |
134 |
|
|
|
135 |
|
|
//------------------------------------------------ |
136 |
|
|
|
137 |
|
|
using stream_cast = stream_cast_impl<>; |
138 |
|
|
|
139 |
|
|
} // zlib |
140 |
|
|
} // http_proto |
141 |
|
|
} // boost |
142 |
|
|
|
143 |
|
|
#endif |
144 |
|
|
|