Clementine
socket_option.hpp
1 //
2 // detail/socket_option.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_DETAIL_SOCKET_OPTION_HPP
12 #define ASIO_DETAIL_SOCKET_OPTION_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include <cstddef>
20 #include <stdexcept>
21 #include "asio/detail/socket_types.hpp"
22 #include "asio/detail/throw_exception.hpp"
23 
24 #include "asio/detail/push_options.hpp"
25 
26 namespace asio {
27 namespace detail {
28 namespace socket_option {
29 
30 // Helper template for implementing boolean-based options.
31 template <int Level, int Name>
32 class boolean
33 {
34 public:
35  // Default constructor.
36  boolean()
37  : value_(0)
38  {
39  }
40 
41  // Construct with a specific option value.
42  explicit boolean(bool v)
43  : value_(v ? 1 : 0)
44  {
45  }
46 
47  // Set the current value of the boolean.
48  boolean& operator=(bool v)
49  {
50  value_ = v ? 1 : 0;
51  return *this;
52  }
53 
54  // Get the current value of the boolean.
55  bool value() const
56  {
57  return !!value_;
58  }
59 
60  // Convert to bool.
61  operator bool() const
62  {
63  return !!value_;
64  }
65 
66  // Test for false.
67  bool operator!() const
68  {
69  return !value_;
70  }
71 
72  // Get the level of the socket option.
73  template <typename Protocol>
74  int level(const Protocol&) const
75  {
76  return Level;
77  }
78 
79  // Get the name of the socket option.
80  template <typename Protocol>
81  int name(const Protocol&) const
82  {
83  return Name;
84  }
85 
86  // Get the address of the boolean data.
87  template <typename Protocol>
88  int* data(const Protocol&)
89  {
90  return &value_;
91  }
92 
93  // Get the address of the boolean data.
94  template <typename Protocol>
95  const int* data(const Protocol&) const
96  {
97  return &value_;
98  }
99 
100  // Get the size of the boolean data.
101  template <typename Protocol>
102  std::size_t size(const Protocol&) const
103  {
104  return sizeof(value_);
105  }
106 
107  // Set the size of the boolean data.
108  template <typename Protocol>
109  void resize(const Protocol&, std::size_t s)
110  {
111  // On some platforms (e.g. Windows Vista), the getsockopt function will
112  // return the size of a boolean socket option as one byte, even though a
113  // four byte integer was passed in.
114  switch (s)
115  {
116  case sizeof(char):
117  value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
118  break;
119  case sizeof(value_):
120  break;
121  default:
122  {
123  std::length_error ex("boolean socket option resize");
124  asio::detail::throw_exception(ex);
125  }
126  }
127  }
128 
129 private:
130  int value_;
131 };
132 
133 // Helper template for implementing integer options.
134 template <int Level, int Name>
135 class integer
136 {
137 public:
138  // Default constructor.
139  integer()
140  : value_(0)
141  {
142  }
143 
144  // Construct with a specific option value.
145  explicit integer(int v)
146  : value_(v)
147  {
148  }
149 
150  // Set the value of the int option.
151  integer& operator=(int v)
152  {
153  value_ = v;
154  return *this;
155  }
156 
157  // Get the current value of the int option.
158  int value() const
159  {
160  return value_;
161  }
162 
163  // Get the level of the socket option.
164  template <typename Protocol>
165  int level(const Protocol&) const
166  {
167  return Level;
168  }
169 
170  // Get the name of the socket option.
171  template <typename Protocol>
172  int name(const Protocol&) const
173  {
174  return Name;
175  }
176 
177  // Get the address of the int data.
178  template <typename Protocol>
179  int* data(const Protocol&)
180  {
181  return &value_;
182  }
183 
184  // Get the address of the int data.
185  template <typename Protocol>
186  const int* data(const Protocol&) const
187  {
188  return &value_;
189  }
190 
191  // Get the size of the int data.
192  template <typename Protocol>
193  std::size_t size(const Protocol&) const
194  {
195  return sizeof(value_);
196  }
197 
198  // Set the size of the int data.
199  template <typename Protocol>
200  void resize(const Protocol&, std::size_t s)
201  {
202  if (s != sizeof(value_))
203  {
204  std::length_error ex("integer socket option resize");
205  asio::detail::throw_exception(ex);
206  }
207  }
208 
209 private:
210  int value_;
211 };
212 
213 // Helper template for implementing linger options.
214 template <int Level, int Name>
215 class linger
216 {
217 public:
218  // Default constructor.
219  linger()
220  {
221  value_.l_onoff = 0;
222  value_.l_linger = 0;
223  }
224 
225  // Construct with specific option values.
226  linger(bool e, int t)
227  {
228  enabled(e);
229  timeout ASIO_PREVENT_MACRO_SUBSTITUTION(t);
230  }
231 
232  // Set the value for whether linger is enabled.
233  void enabled(bool value)
234  {
235  value_.l_onoff = value ? 1 : 0;
236  }
237 
238  // Get the value for whether linger is enabled.
239  bool enabled() const
240  {
241  return value_.l_onoff != 0;
242  }
243 
244  // Set the value for the linger timeout.
245  void timeout ASIO_PREVENT_MACRO_SUBSTITUTION(int value)
246  {
247 #if defined(WIN32)
248  value_.l_linger = static_cast<u_short>(value);
249 #else
250  value_.l_linger = value;
251 #endif
252  }
253 
254  // Get the value for the linger timeout.
255  int timeout ASIO_PREVENT_MACRO_SUBSTITUTION() const
256  {
257  return static_cast<int>(value_.l_linger);
258  }
259 
260  // Get the level of the socket option.
261  template <typename Protocol>
262  int level(const Protocol&) const
263  {
264  return Level;
265  }
266 
267  // Get the name of the socket option.
268  template <typename Protocol>
269  int name(const Protocol&) const
270  {
271  return Name;
272  }
273 
274  // Get the address of the linger data.
275  template <typename Protocol>
276  detail::linger_type* data(const Protocol&)
277  {
278  return &value_;
279  }
280 
281  // Get the address of the linger data.
282  template <typename Protocol>
283  const detail::linger_type* data(const Protocol&) const
284  {
285  return &value_;
286  }
287 
288  // Get the size of the linger data.
289  template <typename Protocol>
290  std::size_t size(const Protocol&) const
291  {
292  return sizeof(value_);
293  }
294 
295  // Set the size of the int data.
296  template <typename Protocol>
297  void resize(const Protocol&, std::size_t s)
298  {
299  if (s != sizeof(value_))
300  {
301  std::length_error ex("linger socket option resize");
302  asio::detail::throw_exception(ex);
303  }
304  }
305 
306 private:
307  detail::linger_type value_;
308 };
309 
310 } // namespace socket_option
311 } // namespace detail
312 } // namespace asio
313 
314 #include "asio/detail/pop_options.hpp"
315 
316 #endif // ASIO_DETAIL_SOCKET_OPTION_HPP
Definition: socket_option.hpp:215
Definition: blocking.hpp:208
Definition: socket_option.hpp:135
Definition: socket_option.hpp:32
Definition: chrono.h:284
Definition: any_io_executor.hpp:28