Chris@16: // Chris@16: // detail/socket_option.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP Chris@16: #define BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: namespace socket_option { Chris@16: Chris@16: // Helper template for implementing boolean-based options. Chris@16: template Chris@16: class boolean Chris@16: { Chris@16: public: Chris@16: // Default constructor. Chris@16: boolean() Chris@16: : value_(0) Chris@16: { Chris@16: } Chris@16: Chris@16: // Construct with a specific option value. Chris@16: explicit boolean(bool v) Chris@16: : value_(v ? 1 : 0) Chris@16: { Chris@16: } Chris@16: Chris@16: // Set the current value of the boolean. Chris@16: boolean& operator=(bool v) Chris@16: { Chris@16: value_ = v ? 1 : 0; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Get the current value of the boolean. Chris@16: bool value() const Chris@16: { Chris@16: return !!value_; Chris@16: } Chris@16: Chris@16: // Convert to bool. Chris@16: operator bool() const Chris@16: { Chris@16: return !!value_; Chris@16: } Chris@16: Chris@16: // Test for false. Chris@16: bool operator!() const Chris@16: { Chris@16: return !value_; Chris@16: } Chris@16: Chris@16: // Get the level of the socket option. Chris@16: template Chris@16: int level(const Protocol&) const Chris@16: { Chris@16: return Level; Chris@16: } Chris@16: Chris@16: // Get the name of the socket option. Chris@16: template Chris@16: int name(const Protocol&) const Chris@16: { Chris@16: return Name; Chris@16: } Chris@16: Chris@16: // Get the address of the boolean data. Chris@16: template Chris@16: int* data(const Protocol&) Chris@16: { Chris@16: return &value_; Chris@16: } Chris@16: Chris@16: // Get the address of the boolean data. Chris@16: template Chris@16: const int* data(const Protocol&) const Chris@16: { Chris@16: return &value_; Chris@16: } Chris@16: Chris@16: // Get the size of the boolean data. Chris@16: template Chris@16: std::size_t size(const Protocol&) const Chris@16: { Chris@16: return sizeof(value_); Chris@16: } Chris@16: Chris@16: // Set the size of the boolean data. Chris@16: template Chris@16: void resize(const Protocol&, std::size_t s) Chris@16: { Chris@16: // On some platforms (e.g. Windows Vista), the getsockopt function will Chris@16: // return the size of a boolean socket option as one byte, even though a Chris@16: // four byte integer was passed in. Chris@16: switch (s) Chris@16: { Chris@16: case sizeof(char): Chris@16: value_ = *reinterpret_cast(&value_) ? 1 : 0; Chris@16: break; Chris@16: case sizeof(value_): Chris@16: break; Chris@16: default: Chris@16: { Chris@16: std::length_error ex("boolean socket option resize"); Chris@16: boost::asio::detail::throw_exception(ex); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: int value_; Chris@16: }; Chris@16: Chris@16: // Helper template for implementing integer options. Chris@16: template Chris@16: class integer Chris@16: { Chris@16: public: Chris@16: // Default constructor. Chris@16: integer() Chris@16: : value_(0) Chris@16: { Chris@16: } Chris@16: Chris@16: // Construct with a specific option value. Chris@16: explicit integer(int v) Chris@16: : value_(v) Chris@16: { Chris@16: } Chris@16: Chris@16: // Set the value of the int option. Chris@16: integer& operator=(int v) Chris@16: { Chris@16: value_ = v; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Get the current value of the int option. Chris@16: int value() const Chris@16: { Chris@16: return value_; Chris@16: } Chris@16: Chris@16: // Get the level of the socket option. Chris@16: template Chris@16: int level(const Protocol&) const Chris@16: { Chris@16: return Level; Chris@16: } Chris@16: Chris@16: // Get the name of the socket option. Chris@16: template Chris@16: int name(const Protocol&) const Chris@16: { Chris@16: return Name; Chris@16: } Chris@16: Chris@16: // Get the address of the int data. Chris@16: template Chris@16: int* data(const Protocol&) Chris@16: { Chris@16: return &value_; Chris@16: } Chris@16: Chris@16: // Get the address of the int data. Chris@16: template Chris@16: const int* data(const Protocol&) const Chris@16: { Chris@16: return &value_; Chris@16: } Chris@16: Chris@16: // Get the size of the int data. Chris@16: template Chris@16: std::size_t size(const Protocol&) const Chris@16: { Chris@16: return sizeof(value_); Chris@16: } Chris@16: Chris@16: // Set the size of the int data. Chris@16: template Chris@16: void resize(const Protocol&, std::size_t s) Chris@16: { Chris@16: if (s != sizeof(value_)) Chris@16: { Chris@16: std::length_error ex("integer socket option resize"); Chris@16: boost::asio::detail::throw_exception(ex); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: int value_; Chris@16: }; Chris@16: Chris@16: // Helper template for implementing linger options. Chris@16: template Chris@16: class linger Chris@16: { Chris@16: public: Chris@16: // Default constructor. Chris@16: linger() Chris@16: { Chris@16: value_.l_onoff = 0; Chris@16: value_.l_linger = 0; Chris@16: } Chris@16: Chris@16: // Construct with specific option values. Chris@16: linger(bool e, int t) Chris@16: { Chris@16: enabled(e); Chris@16: timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION(t); Chris@16: } Chris@16: Chris@16: // Set the value for whether linger is enabled. Chris@16: void enabled(bool value) Chris@16: { Chris@16: value_.l_onoff = value ? 1 : 0; Chris@16: } Chris@16: Chris@16: // Get the value for whether linger is enabled. Chris@16: bool enabled() const Chris@16: { Chris@16: return value_.l_onoff != 0; Chris@16: } Chris@16: Chris@16: // Set the value for the linger timeout. Chris@16: void timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION(int value) Chris@16: { Chris@16: #if defined(WIN32) Chris@16: value_.l_linger = static_cast(value); Chris@16: #else Chris@16: value_.l_linger = value; Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Get the value for the linger timeout. Chris@16: int timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION() const Chris@16: { Chris@16: return static_cast(value_.l_linger); Chris@16: } Chris@16: Chris@16: // Get the level of the socket option. Chris@16: template Chris@16: int level(const Protocol&) const Chris@16: { Chris@16: return Level; Chris@16: } Chris@16: Chris@16: // Get the name of the socket option. Chris@16: template Chris@16: int name(const Protocol&) const Chris@16: { Chris@16: return Name; Chris@16: } Chris@16: Chris@16: // Get the address of the linger data. Chris@16: template Chris@16: detail::linger_type* data(const Protocol&) Chris@16: { Chris@16: return &value_; Chris@16: } Chris@16: Chris@16: // Get the address of the linger data. Chris@16: template Chris@16: const detail::linger_type* data(const Protocol&) const Chris@16: { Chris@16: return &value_; Chris@16: } Chris@16: Chris@16: // Get the size of the linger data. Chris@16: template Chris@16: std::size_t size(const Protocol&) const Chris@16: { Chris@16: return sizeof(value_); Chris@16: } Chris@16: Chris@16: // Set the size of the int data. Chris@16: template Chris@16: void resize(const Protocol&, std::size_t s) Chris@16: { Chris@16: if (s != sizeof(value_)) Chris@16: { Chris@16: std::length_error ex("linger socket option resize"); Chris@16: boost::asio::detail::throw_exception(ex); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: detail::linger_type value_; Chris@16: }; Chris@16: Chris@16: } // namespace socket_option Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP