10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// detail/socket_option.hpp
30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~~~~~~~~~
40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying
80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_DETAIL_SOCKET_OPTION_HPP
120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_DETAIL_SOCKET_OPTION_HPP
130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp"
160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <cstddef>
170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <stdexcept>
180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/socket_types.hpp"
190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/throw_exception.hpp"
200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp"
220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio {
240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail {
250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace socket_option {
260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Helper template for implementing boolean-based options.
280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <int Level, int Name>
290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass boolean
300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Default constructor.
330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  boolean()
340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    : value_(0)
350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Construct with a specific option value.
390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  explicit boolean(bool v)
400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    : value_(v ? 1 : 0)
410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the current value of the boolean.
450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  boolean& operator=(bool v)
460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    value_ = v ? 1 : 0;
480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return *this;
490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the current value of the boolean.
520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  bool value() const
530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return !!value_;
550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Convert to bool.
580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  operator bool() const
590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return !!value_;
610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Test for false.
640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  bool operator!() const
650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return !value_;
670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the level of the socket option.
700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int level(const Protocol&) const
720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return Level;
740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the name of the socket option.
770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int name(const Protocol&) const
790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return Name;
810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the address of the boolean data.
840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int* data(const Protocol&)
860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &value_;
880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the address of the boolean data.
910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  const int* data(const Protocol&) const
930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &value_;
950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the size of the boolean data.
980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  std::size_t size(const Protocol&) const
1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return sizeof(value_);
1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the size of the boolean data.
1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void resize(const Protocol&, std::size_t s)
1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    // On some platforms (e.g. Windows Vista), the getsockopt function will
1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    // return the size of a boolean socket option as one byte, even though a
1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    // four byte integer was passed in.
1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    switch (s)
1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    {
1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    case sizeof(char):
1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      break;
1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    case sizeof(value_):
1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      break;
1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    default:
1190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      {
1200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie        std::length_error ex("boolean socket option resize");
1210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie        asio::detail::throw_exception(ex);
1220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      }
1230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    }
1240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
1270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int value_;
1280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
1290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Helper template for implementing integer options.
1310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <int Level, int Name>
1320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass integer
1330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
1340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
1350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Default constructor.
1360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  integer()
1370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    : value_(0)
1380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Construct with a specific option value.
1420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  explicit integer(int v)
1430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    : value_(v)
1440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the value of the int option.
1480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  integer& operator=(int v)
1490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    value_ = v;
1510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return *this;
1520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the current value of the int option.
1550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int value() const
1560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return value_;
1580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the level of the socket option.
1610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int level(const Protocol&) const
1630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return Level;
1650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the name of the socket option.
1680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int name(const Protocol&) const
1700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return Name;
1720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the address of the int data.
1750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int* data(const Protocol&)
1770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &value_;
1790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the address of the int data.
1820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  const int* data(const Protocol&) const
1840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &value_;
1860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the size of the int data.
1890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  std::size_t size(const Protocol&) const
1910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return sizeof(value_);
1930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
1940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the size of the int data.
1960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
1970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void resize(const Protocol&, std::size_t s)
1980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
1990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    if (s != sizeof(value_))
2000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    {
2010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      std::length_error ex("integer socket option resize");
2020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      asio::detail::throw_exception(ex);
2030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    }
2040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
2070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int value_;
2080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
2090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Helper template for implementing linger options.
2110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <int Level, int Name>
2120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass linger
2130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
2140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
2150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Default constructor.
2160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  linger()
2170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    value_.l_onoff = 0;
2190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    value_.l_linger = 0;
2200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Construct with specific option values.
2230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  linger(bool e, int t)
2240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    enabled(e);
2260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    timeout ASIO_PREVENT_MACRO_SUBSTITUTION(t);
2270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the value for whether linger is enabled.
2300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void enabled(bool value)
2310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    value_.l_onoff = value ? 1 : 0;
2330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the value for whether linger is enabled.
2360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  bool enabled() const
2370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return value_.l_onoff != 0;
2390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the value for the linger timeout.
2420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void timeout ASIO_PREVENT_MACRO_SUBSTITUTION(int value)
2430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    value_.l_linger = value;
2450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the value for the linger timeout.
2480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int timeout ASIO_PREVENT_MACRO_SUBSTITUTION() const
2490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return static_cast<int>(value_.l_linger);
2510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the level of the socket option.
2540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
2550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int level(const Protocol&) const
2560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return Level;
2580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the name of the socket option.
2610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
2620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  int name(const Protocol&) const
2630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return Name;
2650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the address of the linger data.
2680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
2690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  detail::linger_type* data(const Protocol&)
2700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &value_;
2720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the address of the linger data.
2750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
2760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  const detail::linger_type* data(const Protocol&) const
2770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &value_;
2790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Get the size of the linger data.
2820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
2830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  std::size_t size(const Protocol&) const
2840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return sizeof(value_);
2860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Set the size of the int data.
2890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Protocol>
2900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void resize(const Protocol&, std::size_t s)
2910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
2920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    if (s != sizeof(value_))
2930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    {
2940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      std::length_error ex("linger socket option resize");
2950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      asio::detail::throw_exception(ex);
2960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    }
2970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
2980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
3000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  detail::linger_type value_;
3010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
3020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace socket_option
3040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail
3050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio
3060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp"
3080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_DETAIL_SOCKET_OPTION_HPP
310