GCC Code Coverage Report


Directory: libs/http_proto/
File: src_zlib/service/stream_cast.hpp
Date: 2025-05-26 06:53:21
Exec Total Coverage
Lines: 0 5 0.0%
Functions: 0 2 0.0%
Branches: 0 0 -%

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