basic_endpoint.hpp
Go to the documentation of this file.
00001 //
00002 // basic_endpoint.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_IP_BASIC_ENDPOINT_HPP
00012 #define ASIO_IP_BASIC_ENDPOINT_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 <boost/throw_exception.hpp>
00022 #include <boost/detail/workaround.hpp>
00023 #include <cstring>
00024 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00025 # include <ostream>
00026 #endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00027 #include "asio/detail/pop_options.hpp"
00028 
00029 #include "asio/error.hpp"
00030 #include "asio/ip/address.hpp"
00031 #include "asio/detail/socket_ops.hpp"
00032 #include "asio/detail/socket_types.hpp"
00033 
00034 namespace asio {
00035 namespace ip {
00036 
00038 
00049 template <typename InternetProtocol>
00050 class basic_endpoint
00051 {
00052 public:
00054   typedef InternetProtocol protocol_type;
00055 
00058 #if defined(GENERATING_DOCUMENTATION)
00059   typedef implementation_defined data_type;
00060 #else
00061   typedef asio::detail::socket_addr_type data_type;
00062 #endif
00063 
00065   basic_endpoint()
00066     : data_()
00067   {
00068     data_.v4.sin_family = AF_INET;
00069     data_.v4.sin_port = 0;
00070     data_.v4.sin_addr.s_addr = INADDR_ANY;
00071   }
00072 
00077 
00089   basic_endpoint(const InternetProtocol& protocol, unsigned short port_num)
00090     : data_()
00091   {
00092     using namespace std; // For memcpy.
00093     if (protocol.family() == PF_INET)
00094     {
00095       data_.v4.sin_family = AF_INET;
00096       data_.v4.sin_port =
00097         asio::detail::socket_ops::host_to_network_short(port_num);
00098       data_.v4.sin_addr.s_addr = INADDR_ANY;
00099     }
00100     else
00101     {
00102       data_.v6.sin6_family = AF_INET6;
00103       data_.v6.sin6_port =
00104         asio::detail::socket_ops::host_to_network_short(port_num);
00105       data_.v6.sin6_flowinfo = 0;
00106       asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
00107       data_.v6.sin6_addr = tmp_addr;
00108       data_.v6.sin6_scope_id = 0;
00109     }
00110   }
00111 
00115   basic_endpoint(const asio::ip::address& addr, unsigned short port_num)
00116     : data_()
00117   {
00118     using namespace std; // For memcpy.
00119     if (addr.is_v4())
00120     {
00121       data_.v4.sin_family = AF_INET;
00122       data_.v4.sin_port =
00123         asio::detail::socket_ops::host_to_network_short(port_num);
00124       data_.v4.sin_addr.s_addr =
00125         asio::detail::socket_ops::host_to_network_long(
00126             addr.to_v4().to_ulong());
00127     }
00128     else
00129     {
00130       data_.v6.sin6_family = AF_INET6;
00131       data_.v6.sin6_port =
00132         asio::detail::socket_ops::host_to_network_short(port_num);
00133       data_.v6.sin6_flowinfo = 0;
00134       asio::ip::address_v6 v6_addr = addr.to_v6();
00135       asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes();
00136       memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16);
00137       data_.v6.sin6_scope_id = v6_addr.scope_id();
00138     }
00139   }
00140 
00142   basic_endpoint(const basic_endpoint& other)
00143     : data_(other.data_)
00144   {
00145   }
00146 
00148   basic_endpoint& operator=(const basic_endpoint& other)
00149   {
00150     data_ = other.data_;
00151     return *this;
00152   }
00153 
00155   protocol_type protocol() const
00156   {
00157     if (is_v4())
00158       return InternetProtocol::v4();
00159     return InternetProtocol::v6();
00160   }
00161 
00163   data_type* data()
00164   {
00165     return &data_.base;
00166   }
00167 
00169   const data_type* data() const
00170   {
00171     return &data_.base;
00172   }
00173 
00175   std::size_t size() const
00176   {
00177     if (is_v4())
00178       return sizeof(asio::detail::sockaddr_in4_type);
00179     else
00180       return sizeof(asio::detail::sockaddr_in6_type);
00181   }
00182 
00184   void resize(std::size_t size)
00185   {
00186     if (size > sizeof(asio::detail::sockaddr_storage_type))
00187     {
00188       asio::system_error e(asio::error::invalid_argument);
00189       boost::throw_exception(e);
00190     }
00191   }
00192 
00194   std::size_t capacity() const
00195   {
00196     return sizeof(asio::detail::sockaddr_storage_type);
00197   }
00198 
00201   unsigned short port() const
00202   {
00203     if (is_v4())
00204     {
00205       return asio::detail::socket_ops::network_to_host_short(
00206           data_.v4.sin_port);
00207     }
00208     else
00209     {
00210       return asio::detail::socket_ops::network_to_host_short(
00211           data_.v6.sin6_port);
00212     }
00213   }
00214 
00217   void port(unsigned short port_num)
00218   {
00219     if (is_v4())
00220     {
00221       data_.v4.sin_port
00222         = asio::detail::socket_ops::host_to_network_short(port_num);
00223     }
00224     else
00225     {
00226       data_.v6.sin6_port
00227         = asio::detail::socket_ops::host_to_network_short(port_num);
00228     }
00229   }
00230 
00232   asio::ip::address address() const
00233   {
00234     using namespace std; // For memcpy.
00235     if (is_v4())
00236     {
00237       return asio::ip::address_v4(
00238           asio::detail::socket_ops::network_to_host_long(
00239             data_.v4.sin_addr.s_addr));
00240     }
00241     else
00242     {
00243       asio::ip::address_v6::bytes_type bytes;
00244       memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16);
00245       return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);
00246     }
00247   }
00248 
00250   void address(const asio::ip::address& addr)
00251   {
00252     basic_endpoint<InternetProtocol> tmp_endpoint(addr, port());
00253     data_ = tmp_endpoint.data_;
00254   }
00255 
00257   friend bool operator==(const basic_endpoint<InternetProtocol>& e1,
00258       const basic_endpoint<InternetProtocol>& e2)
00259   {
00260     return e1.address() == e2.address() && e1.port() == e2.port();
00261   }
00262 
00264   friend bool operator!=(const basic_endpoint<InternetProtocol>& e1,
00265       const basic_endpoint<InternetProtocol>& e2)
00266   {
00267     return e1.address() != e2.address() || e1.port() != e2.port();
00268   }
00269 
00271   friend bool operator<(const basic_endpoint<InternetProtocol>& e1,
00272       const basic_endpoint<InternetProtocol>& e2)
00273   {
00274     if (e1.address() < e2.address())
00275       return true;
00276     if (e1.address() != e2.address())
00277       return false;
00278     return e1.port() < e2.port();
00279   }
00280 
00281 private:
00282   // Helper function to determine whether the endpoint is IPv4.
00283   bool is_v4() const
00284   {
00285     return data_.base.sa_family == AF_INET;
00286   }
00287 
00288   // The underlying IP socket address.
00289   union data_union
00290   {
00291     asio::detail::socket_addr_type base;
00292     asio::detail::sockaddr_storage_type storage;
00293     asio::detail::sockaddr_in4_type v4;
00294     asio::detail::sockaddr_in6_type v6;
00295   } data_;
00296 };
00297 
00299 
00310 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00311 template <typename InternetProtocol>
00312 std::ostream& operator<<(std::ostream& os,
00313     const basic_endpoint<InternetProtocol>& endpoint)
00314 {
00315   const address& addr = endpoint.address();
00316   asio::error_code ec;
00317   std::string a = addr.to_string(ec);
00318   if (ec)
00319   {
00320     if (os.exceptions() & std::ios::failbit)
00321       asio::detail::throw_error(ec);
00322     else
00323       os.setstate(std::ios_base::failbit);
00324   }
00325   else
00326   {
00327     if (addr.is_v4())
00328       os << a;
00329     else
00330       os << '[' << a << ']';
00331     os << ':' << endpoint.port();
00332   }
00333   return os;
00334 }
00335 #else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00336 template <typename Elem, typename Traits, typename InternetProtocol>
00337 std::basic_ostream<Elem, Traits>& operator<<(
00338     std::basic_ostream<Elem, Traits>& os,
00339     const basic_endpoint<InternetProtocol>& endpoint)
00340 {
00341   const address& addr = endpoint.address();
00342   asio::error_code ec;
00343   std::string a = addr.to_string(ec);
00344   if (ec)
00345   {
00346     if (os.exceptions() & std::ios::failbit)
00347       asio::detail::throw_error(ec);
00348     else
00349       os.setstate(std::ios_base::failbit);
00350   }
00351   else
00352   {
00353     if (addr.is_v4())
00354       os << a;
00355     else
00356       os << '[' << a << ']';
00357     os << ':' << endpoint.port();
00358   }
00359   return os;
00360 }
00361 #endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00362 
00363 } // namespace ip
00364 } // namespace asio
00365 
00366 #include "asio/detail/pop_options.hpp"
00367 
00368 #endif // ASIO_IP_BASIC_ENDPOINT_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