socket_option.hpp
Go to the documentation of this file.
00001 //
00002 // socket_option.hpp
00003 // ~~~~~~~~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef ASIO_DETAIL_SOCKET_OPTION_HPP
00012 #define ASIO_DETAIL_SOCKET_OPTION_HPP
00013 
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017 
00018 #include "asio/detail/push_options.hpp"
00019 
00020 #include "asio/detail/push_options.hpp"
00021 #include <cstddef>
00022 #include <stdexcept>
00023 #include <boost/config.hpp>
00024 #include "asio/detail/pop_options.hpp"
00025 
00026 #include "asio/detail/socket_types.hpp"
00027 
00028 namespace asio {
00029 namespace detail {
00030 namespace socket_option {
00031 
00032 // Helper template for implementing boolean-based options.
00033 template <int Level, int Name>
00034 class boolean
00035 {
00036 public:
00037   // Default constructor.
00038   boolean()
00039     : value_(0)
00040   {
00041   }
00042 
00043   // Construct with a specific option value.
00044   explicit boolean(bool v)
00045     : value_(v ? 1 : 0)
00046   {
00047   }
00048 
00049   // Set the current value of the boolean.
00050   boolean& operator=(bool v)
00051   {
00052     value_ = v ? 1 : 0;
00053     return *this;
00054   }
00055 
00056   // Get the current value of the boolean.
00057   bool value() const
00058   {
00059     return !!value_;
00060   }
00061 
00062   // Convert to bool.
00063   operator bool() const
00064   {
00065     return !!value_;
00066   }
00067 
00068   // Test for false.
00069   bool operator!() const
00070   {
00071     return !value_;
00072   }
00073 
00074   // Get the level of the socket option.
00075   template <typename Protocol>
00076   int level(const Protocol&) const
00077   {
00078     return Level;
00079   }
00080 
00081   // Get the name of the socket option.
00082   template <typename Protocol>
00083   int name(const Protocol&) const
00084   {
00085     return Name;
00086   }
00087 
00088   // Get the address of the boolean data.
00089   template <typename Protocol>
00090   int* data(const Protocol&)
00091   {
00092     return &value_;
00093   }
00094 
00095   // Get the address of the boolean data.
00096   template <typename Protocol>
00097   const int* data(const Protocol&) const
00098   {
00099     return &value_;
00100   }
00101 
00102   // Get the size of the boolean data.
00103   template <typename Protocol>
00104   std::size_t size(const Protocol&) const
00105   {
00106     return sizeof(value_);
00107   }
00108 
00109   // Set the size of the boolean data.
00110   template <typename Protocol>
00111   void resize(const Protocol&, std::size_t s)
00112   {
00113     // On some platforms (e.g. Windows Vista), the getsockopt function will
00114     // return the size of a boolean socket option as one byte, even though a
00115     // four byte integer was passed in.
00116     switch (s)
00117     {
00118     case sizeof(char):
00119       value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
00120       break;
00121     case sizeof(value_):
00122       break;
00123     default:
00124       throw std::length_error("boolean socket option resize");
00125     }
00126   }
00127 
00128 private:
00129   int value_;
00130 };
00131 
00132 // Helper template for implementing integer options.
00133 template <int Level, int Name>
00134 class integer
00135 {
00136 public:
00137   // Default constructor.
00138   integer()
00139     : value_(0)
00140   {
00141   }
00142 
00143   // Construct with a specific option value.
00144   explicit integer(int v)
00145     : value_(v)
00146   {
00147   }
00148 
00149   // Set the value of the int option.
00150   integer& operator=(int v)
00151   {
00152     value_ = v;
00153     return *this;
00154   }
00155 
00156   // Get the current value of the int option.
00157   int value() const
00158   {
00159     return value_;
00160   }
00161 
00162   // Get the level of the socket option.
00163   template <typename Protocol>
00164   int level(const Protocol&) const
00165   {
00166     return Level;
00167   }
00168 
00169   // Get the name of the socket option.
00170   template <typename Protocol>
00171   int name(const Protocol&) const
00172   {
00173     return Name;
00174   }
00175 
00176   // Get the address of the int data.
00177   template <typename Protocol>
00178   int* data(const Protocol&)
00179   {
00180     return &value_;
00181   }
00182 
00183   // Get the address of the int data.
00184   template <typename Protocol>
00185   const int* data(const Protocol&) const
00186   {
00187     return &value_;
00188   }
00189 
00190   // Get the size of the int data.
00191   template <typename Protocol>
00192   std::size_t size(const Protocol&) const
00193   {
00194     return sizeof(value_);
00195   }
00196 
00197   // Set the size of the int data.
00198   template <typename Protocol>
00199   void resize(const Protocol&, std::size_t s)
00200   {
00201     if (s != sizeof(value_))
00202       throw std::length_error("integer socket option resize");
00203   }
00204 
00205 private:
00206   int value_;
00207 };
00208 
00209 // Helper template for implementing linger options.
00210 template <int Level, int Name>
00211 class linger
00212 {
00213 public:
00214   // Default constructor.
00215   linger()
00216   {
00217     value_.l_onoff = 0;
00218     value_.l_linger = 0;
00219   }
00220 
00221   // Construct with specific option values.
00222   linger(bool e, int t)
00223   {
00224     enabled(e);
00225     timeout(t);
00226   }
00227 
00228   // Set the value for whether linger is enabled.
00229   void enabled(bool value)
00230   {
00231     value_.l_onoff = value ? 1 : 0;
00232   }
00233 
00234   // Get the value for whether linger is enabled.
00235   bool enabled() const
00236   {
00237     return value_.l_onoff != 0;
00238   }
00239 
00240   // Set the value for the linger timeout.
00241   void timeout(int value)
00242   {
00243 #if defined(WIN32)
00244     value_.l_linger = static_cast<u_short>(value);
00245 #else
00246     value_.l_linger = value;
00247 #endif
00248   }
00249 
00250   // Get the value for the linger timeout.
00251   int timeout() const
00252   {
00253     return static_cast<int>(value_.l_linger);
00254   }
00255 
00256   // Get the level of the socket option.
00257   template <typename Protocol>
00258   int level(const Protocol&) const
00259   {
00260     return Level;
00261   }
00262 
00263   // Get the name of the socket option.
00264   template <typename Protocol>
00265   int name(const Protocol&) const
00266   {
00267     return Name;
00268   }
00269 
00270   // Get the address of the linger data.
00271   template <typename Protocol>
00272   ::linger* data(const Protocol&)
00273   {
00274     return &value_;
00275   }
00276 
00277   // Get the address of the linger data.
00278   template <typename Protocol>
00279   const ::linger* data(const Protocol&) const
00280   {
00281     return &value_;
00282   }
00283 
00284   // Get the size of the linger data.
00285   template <typename Protocol>
00286   std::size_t size(const Protocol&) const
00287   {
00288     return sizeof(value_);
00289   }
00290 
00291   // Set the size of the int data.
00292   template <typename Protocol>
00293   void resize(const Protocol&, std::size_t s)
00294   {
00295     if (s != sizeof(value_))
00296       throw std::length_error("linger socket option resize");
00297   }
00298 
00299 private:
00300   ::linger value_;
00301 };
00302 
00303 } // namespace socket_option
00304 } // namespace detail
00305 } // namespace asio
00306 
00307 #include "asio/detail/pop_options.hpp"
00308 
00309 #endif // ASIO_DETAIL_SOCKET_OPTION_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39