File indexing completed on 2025-10-30 08:11:21
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
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 
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 
0032 template <int Level, int Name>
0033 class boolean
0034 {
0035 public:
0036   
0037   boolean()
0038     : value_(0)
0039   {
0040   }
0041 
0042   
0043   explicit boolean(bool v)
0044     : value_(v ? 1 : 0)
0045   {
0046   }
0047 
0048   
0049   boolean& operator=(bool v)
0050   {
0051     value_ = v ? 1 : 0;
0052     return *this;
0053   }
0054 
0055   
0056   bool value() const
0057   {
0058     return !!value_;
0059   }
0060 
0061   
0062   operator bool() const
0063   {
0064     return !!value_;
0065   }
0066 
0067   
0068   bool operator!() const
0069   {
0070     return !value_;
0071   }
0072 
0073   
0074   template <typename Protocol>
0075   int level(const Protocol&) const
0076   {
0077     return Level;
0078   }
0079 
0080   
0081   template <typename Protocol>
0082   int name(const Protocol&) const
0083   {
0084     return Name;
0085   }
0086 
0087   
0088   template <typename Protocol>
0089   int* data(const Protocol&)
0090   {
0091     return &value_;
0092   }
0093 
0094   
0095   template <typename Protocol>
0096   const int* data(const Protocol&) const
0097   {
0098     return &value_;
0099   }
0100 
0101   
0102   template <typename Protocol>
0103   std::size_t size(const Protocol&) const
0104   {
0105     return sizeof(value_);
0106   }
0107 
0108   
0109   template <typename Protocol>
0110   void resize(const Protocol&, std::size_t s)
0111   {
0112     
0113     
0114     
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 
0135 template <int Level, int Name>
0136 class integer
0137 {
0138 public:
0139   
0140   integer()
0141     : value_(0)
0142   {
0143   }
0144 
0145   
0146   explicit integer(int v)
0147     : value_(v)
0148   {
0149   }
0150 
0151   
0152   integer& operator=(int v)
0153   {
0154     value_ = v;
0155     return *this;
0156   }
0157 
0158   
0159   int value() const
0160   {
0161     return value_;
0162   }
0163 
0164   
0165   template <typename Protocol>
0166   int level(const Protocol&) const
0167   {
0168     return Level;
0169   }
0170 
0171   
0172   template <typename Protocol>
0173   int name(const Protocol&) const
0174   {
0175     return Name;
0176   }
0177 
0178   
0179   template <typename Protocol>
0180   int* data(const Protocol&)
0181   {
0182     return &value_;
0183   }
0184 
0185   
0186   template <typename Protocol>
0187   const int* data(const Protocol&) const
0188   {
0189     return &value_;
0190   }
0191 
0192   
0193   template <typename Protocol>
0194   std::size_t size(const Protocol&) const
0195   {
0196     return sizeof(value_);
0197   }
0198 
0199   
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 
0215 template <int Level, int Name>
0216 class linger
0217 {
0218 public:
0219   
0220   linger()
0221   {
0222     value_.l_onoff = 0;
0223     value_.l_linger = 0;
0224   }
0225 
0226   
0227   linger(bool e, int t)
0228   {
0229     enabled(e);
0230     timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION(t);
0231   }
0232 
0233   
0234   void enabled(bool value)
0235   {
0236     value_.l_onoff = value ? 1 : 0;
0237   }
0238 
0239   
0240   bool enabled() const
0241   {
0242     return value_.l_onoff != 0;
0243   }
0244 
0245   
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   
0256   int timeout BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION() const
0257   {
0258     return static_cast<int>(value_.l_linger);
0259   }
0260 
0261   
0262   template <typename Protocol>
0263   int level(const Protocol&) const
0264   {
0265     return Level;
0266   }
0267 
0268   
0269   template <typename Protocol>
0270   int name(const Protocol&) const
0271   {
0272     return Name;
0273   }
0274 
0275   
0276   template <typename Protocol>
0277   detail::linger_type* data(const Protocol&)
0278   {
0279     return &value_;
0280   }
0281 
0282   
0283   template <typename Protocol>
0284   const detail::linger_type* data(const Protocol&) const
0285   {
0286     return &value_;
0287   }
0288 
0289   
0290   template <typename Protocol>
0291   std::size_t size(const Protocol&) const
0292   {
0293     return sizeof(value_);
0294   }
0295 
0296   
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 } 
0312 } 
0313 } 
0314 } 
0315 
0316 #include <boost/asio/detail/pop_options.hpp>
0317 
0318 #endif