00001
00002
00003
00004
00005
00006
00007
00008
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
00033 template <int Level, int Name>
00034 class boolean
00035 {
00036 public:
00037
00038 boolean()
00039 : value_(0)
00040 {
00041 }
00042
00043
00044 explicit boolean(bool v)
00045 : value_(v ? 1 : 0)
00046 {
00047 }
00048
00049
00050 boolean& operator=(bool v)
00051 {
00052 value_ = v ? 1 : 0;
00053 return *this;
00054 }
00055
00056
00057 bool value() const
00058 {
00059 return !!value_;
00060 }
00061
00062
00063 operator bool() const
00064 {
00065 return !!value_;
00066 }
00067
00068
00069 bool operator!() const
00070 {
00071 return !value_;
00072 }
00073
00074
00075 template <typename Protocol>
00076 int level(const Protocol&) const
00077 {
00078 return Level;
00079 }
00080
00081
00082 template <typename Protocol>
00083 int name(const Protocol&) const
00084 {
00085 return Name;
00086 }
00087
00088
00089 template <typename Protocol>
00090 int* data(const Protocol&)
00091 {
00092 return &value_;
00093 }
00094
00095
00096 template <typename Protocol>
00097 const int* data(const Protocol&) const
00098 {
00099 return &value_;
00100 }
00101
00102
00103 template <typename Protocol>
00104 std::size_t size(const Protocol&) const
00105 {
00106 return sizeof(value_);
00107 }
00108
00109
00110 template <typename Protocol>
00111 void resize(const Protocol&, std::size_t s)
00112 {
00113 if (s != sizeof(value_))
00114 throw std::length_error("boolean socket option resize");
00115 }
00116
00117 private:
00118 int value_;
00119 };
00120
00121
00122 template <int Level, int Name>
00123 class integer
00124 {
00125 public:
00126
00127 integer()
00128 : value_(0)
00129 {
00130 }
00131
00132
00133 explicit integer(int v)
00134 : value_(v)
00135 {
00136 }
00137
00138
00139 integer& operator=(int v)
00140 {
00141 value_ = v;
00142 return *this;
00143 }
00144
00145
00146 int value() const
00147 {
00148 return value_;
00149 }
00150
00151
00152 template <typename Protocol>
00153 int level(const Protocol&) const
00154 {
00155 return Level;
00156 }
00157
00158
00159 template <typename Protocol>
00160 int name(const Protocol&) const
00161 {
00162 return Name;
00163 }
00164
00165
00166 template <typename Protocol>
00167 int* data(const Protocol&)
00168 {
00169 return &value_;
00170 }
00171
00172
00173 template <typename Protocol>
00174 const int* data(const Protocol&) const
00175 {
00176 return &value_;
00177 }
00178
00179
00180 template <typename Protocol>
00181 std::size_t size(const Protocol&) const
00182 {
00183 return sizeof(value_);
00184 }
00185
00186
00187 template <typename Protocol>
00188 void resize(const Protocol&, std::size_t s)
00189 {
00190 if (s != sizeof(value_))
00191 throw std::length_error("integer socket option resize");
00192 }
00193
00194 private:
00195 int value_;
00196 };
00197
00198
00199 template <int Level, int Name>
00200 class linger
00201 {
00202 public:
00203
00204 linger()
00205 {
00206 value_.l_onoff = 0;
00207 value_.l_linger = 0;
00208 }
00209
00210
00211 linger(bool e, int t)
00212 {
00213 enabled(e);
00214 timeout(t);
00215 }
00216
00217
00218 void enabled(bool value)
00219 {
00220 value_.l_onoff = value ? 1 : 0;
00221 }
00222
00223
00224 bool enabled() const
00225 {
00226 return value_.l_onoff != 0;
00227 }
00228
00229
00230 void timeout(int value)
00231 {
00232 #if defined(WIN32)
00233 value_.l_linger = static_cast<u_short>(value);
00234 #else
00235 value_.l_linger = value;
00236 #endif
00237 }
00238
00239
00240 int timeout() const
00241 {
00242 return static_cast<int>(value_.l_linger);
00243 }
00244
00245
00246 template <typename Protocol>
00247 int level(const Protocol&) const
00248 {
00249 return Level;
00250 }
00251
00252
00253 template <typename Protocol>
00254 int name(const Protocol&) const
00255 {
00256 return Name;
00257 }
00258
00259
00260 template <typename Protocol>
00261 ::linger* data(const Protocol&)
00262 {
00263 return &value_;
00264 }
00265
00266
00267 template <typename Protocol>
00268 const ::linger* data(const Protocol&) const
00269 {
00270 return &value_;
00271 }
00272
00273
00274 template <typename Protocol>
00275 std::size_t size(const Protocol&) const
00276 {
00277 return sizeof(value_);
00278 }
00279
00280
00281 template <typename Protocol>
00282 void resize(const Protocol&, std::size_t s)
00283 {
00284 if (s != sizeof(value_))
00285 throw std::length_error("linger socket option resize");
00286 }
00287
00288 private:
00289 ::linger value_;
00290 };
00291
00292 }
00293 }
00294 }
00295
00296 #include "asio/detail/pop_options.hpp"
00297
00298 #endif // ASIO_DETAIL_SOCKET_OPTION_HPP