Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:44

0001 //
0002 // detail/socket_option.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP
0012 #define BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstddef>
0020 #include <stdexcept>
0021 #include <boost/asio/detail/socket_types.hpp>
0022 #include <boost/asio/detail/throw_exception.hpp>
0023 
0024 #include <boost/asio/detail/push_options.hpp>
0025 
0026 namespace boost {
0027 namespace asio {
0028 namespace detail {
0029 namespace socket_option {
0030 
0031 // Helper template for implementing boolean-based options.
0032 template <int Level, int Name>
0033 class boolean
0034 {
0035 public:
0036   // Default constructor.
0037   boolean()
0038     : value_(0)
0039   {
0040   }
0041 
0042   // Construct with a specific option value.
0043   explicit boolean(bool v)
0044     : value_(v ? 1 : 0)
0045   {
0046   }
0047 
0048   // Set the current value of the boolean.
0049   boolean& operator=(bool v)
0050   {
0051     value_ = v ? 1 : 0;
0052     return *this;
0053   }
0054 
0055   // Get the current value of the boolean.
0056   bool value() const
0057   {
0058     return !!value_;
0059   }
0060 
0061   // Convert to bool.
0062   operator bool() const
0063   {
0064     return !!value_;
0065   }
0066 
0067   // Test for false.
0068   bool operator!() const
0069   {
0070     return !value_;
0071   }
0072 
0073   // Get the level of the socket option.
0074   template <typename Protocol>
0075   int level(const Protocol&) const
0076   {
0077     return Level;
0078   }
0079 
0080   // Get the name of the socket option.
0081   template <typename Protocol>
0082   int name(const Protocol&) const
0083   {
0084     return Name;
0085   }
0086 
0087   // Get the address of the boolean data.
0088   template <typename Protocol>
0089   int* data(const Protocol&)
0090   {
0091     return &value_;
0092   }
0093 
0094   // Get the address of the boolean data.
0095   template <typename Protocol>
0096   const int* data(const Protocol&) const
0097   {
0098     return &value_;
0099   }
0100 
0101   // Get the size of the boolean data.
0102   template <typename Protocol>
0103   std::size_t size(const Protocol&) const
0104   {
0105     return sizeof(value_);
0106   }
0107 
0108   // Set the size of the boolean data.
0109   template <typename Protocol>
0110   void resize(const Protocol&, std::size_t s)
0111   {
0112     // On some platforms (e.g. Windows Vista), the getsockopt function will
0113     // return the size of a boolean socket option as one byte, even though a
0114     // four byte integer was passed in.
0115     switch (s)
0116     {
0117     case sizeof(char):
0118       value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
0119       break;
0120     case sizeof(value_):
0121       break;
0122     default:
0123       {
0124         std::length_error ex("boolean socket option resize");
0125         boost::asio::detail::throw_exception(ex);
0126       }
0127     }
0128   }
0129 
0130 private:
0131   int value_;
0132 };
0133 
0134 // Helper template for implementing integer options.
0135 template <int Level, int Name>
0136 class integer
0137 {
0138 public:
0139   // Default constructor.
0140   integer()
0141     : value_(0)
0142   {
0143   }
0144 
0145   // Construct with a specific option value.
0146   explicit integer(int v)
0147     : value_(v)
0148   {
0149   }
0150 
0151   // Set the value of the int option.
0152   integer& operator=(int v)
0153   {
0154     value_ = v;
0155     return *this;
0156   }
0157 
0158   // Get the current value of the int option.
0159   int value() const
0160   {
0161     return value_;
0162   }
0163 
0164   // Get the level of the socket option.
0165   template <typename Protocol>
0166   int level(const Protocol&) const
0167   {
0168     return Level;
0169   }
0170 
0171   // Get the name of the socket option.
0172   template <typename Protocol>
0173   int name(const Protocol&) const
0174   {
0175     return Name;
0176   }
0177 
0178   // Get the address of the int data.
0179   template <typename Protocol>
0180   int* data(const Protocol&)
0181   {
0182     return &value_;
0183   }
0184 
0185   // Get the address of the int data.
0186   template <typename Protocol>
0187   const int* data(const Protocol&) const
0188   {
0189     return &value_;
0190   }
0191 
0192   // Get the size of the int data.
0193   template <typename Protocol>
0194   std::size_t size(const Protocol&) const
0195   {
0196     return sizeof(value_);
0197   }
0198 
0199   // Set the size of the int data.
0200   template <typename Protocol>
0201   void resize(const Protocol&, std::size_t s)
0202   {
0203     if (s != sizeof(value_))
0204     {
0205       std::length_error ex("integer socket option resize");
0206       boost::asio::detail::throw_exception(ex);
0207     }
0208   }
0209 
0210 private:
0211   int value_;
0212 };
0213 
0214 // Helper template for implementing linger options.
0215 template <int Level, int Name>
0216 class linger
0217 {
0218 public:
0219   // Default constructor.
0220   linger()
0221   {
0222     value_.l_onoff = 0;
0223     value_.l_linger = 0;
0224   }
0225 
0226   // Construct with specific option values.
0227   linger(bool e, int t)
0228   {
0229     enabled(e);
0230     timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION(t);
0231   }
0232 
0233   // Set the value for whether linger is enabled.
0234   void enabled(bool value)
0235   {
0236     value_.l_onoff = value ? 1 : 0;
0237   }
0238 
0239   // Get the value for whether linger is enabled.
0240   bool enabled() const
0241   {
0242     return value_.l_onoff != 0;
0243   }
0244 
0245   // Set the value for the linger timeout.
0246   void timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION(int value)
0247   {
0248 #if defined(WIN32)
0249     value_.l_linger = static_cast<u_short>(value);
0250 #else
0251     value_.l_linger = value;
0252 #endif
0253   }
0254 
0255   // Get the value for the linger timeout.
0256   int timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION() const
0257   {
0258     return static_cast<int>(value_.l_linger);
0259   }
0260 
0261   // Get the level of the socket option.
0262   template <typename Protocol>
0263   int level(const Protocol&) const
0264   {
0265     return Level;
0266   }
0267 
0268   // Get the name of the socket option.
0269   template <typename Protocol>
0270   int name(const Protocol&) const
0271   {
0272     return Name;
0273   }
0274 
0275   // Get the address of the linger data.
0276   template <typename Protocol>
0277   detail::linger_type* data(const Protocol&)
0278   {
0279     return &value_;
0280   }
0281 
0282   // Get the address of the linger data.
0283   template <typename Protocol>
0284   const detail::linger_type* data(const Protocol&) const
0285   {
0286     return &value_;
0287   }
0288 
0289   // Get the size of the linger data.
0290   template <typename Protocol>
0291   std::size_t size(const Protocol&) const
0292   {
0293     return sizeof(value_);
0294   }
0295 
0296   // Set the size of the int data.
0297   template <typename Protocol>
0298   void resize(const Protocol&, std::size_t s)
0299   {
0300     if (s != sizeof(value_))
0301     {
0302       std::length_error ex("linger socket option resize");
0303       boost::asio::detail::throw_exception(ex);
0304     }
0305   }
0306 
0307 private:
0308   detail::linger_type value_;
0309 };
0310 
0311 } // namespace socket_option
0312 } // namespace detail
0313 } // namespace asio
0314 } // namespace boost
0315 
0316 #include <boost/asio/detail/pop_options.hpp>
0317 
0318 #endif // BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP