Refactor IP::Endpoint

This commit is contained in:
Vinnie Falco
2013-12-01 21:14:14 -08:00
parent 3e6818b407
commit 864b20565b
17 changed files with 1481 additions and 1042 deletions

View File

@@ -157,8 +157,12 @@
<ClInclude Include="..\..\beast\mpl\IsCallPossible.h" />
<ClInclude Include="..\..\beast\Net.h" />
<ClInclude Include="..\..\beast\net\BufferType.h" />
<ClInclude Include="..\..\beast\net\detail\Parse.h" />
<ClInclude Include="..\..\beast\net\DynamicBuffer.h" />
<ClInclude Include="..\..\beast\net\IPAddress.h" />
<ClInclude Include="..\..\beast\net\IPAddressV4.h" />
<ClInclude Include="..\..\beast\net\IPAddressV6.h" />
<ClInclude Include="..\..\beast\net\IPEndpoint.h" />
<ClInclude Include="..\..\beast\SafeBool.h" />
<ClInclude Include="..\..\beast\SmartPtr.h" />
<ClInclude Include="..\..\beast\smart_ptr\AbstractObject.h" />
@@ -577,6 +581,24 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddressV4.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddressV6.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPEndpoint.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\Net.cpp" />
<ClCompile Include="..\..\beast\smart_ptr\impl\AbstractObject.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>

View File

@@ -294,6 +294,9 @@
<Filter Include="beast\crypto\impl\sha2">
<UniqueIdentifier>{44489531-f44a-439a-a6ea-d32c252b1e8b}</UniqueIdentifier>
</Filter>
<Filter Include="beast\net\detail">
<UniqueIdentifier>{43cc0f2a-9905-4081-8104-48d2c4be9e7e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
@@ -1143,9 +1146,6 @@
<ClInclude Include="..\..\beast\utility\BaseFromMember.h">
<Filter>beast\utility</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\net\IPAddress.h">
<Filter>beast\net</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\Asio.h">
<Filter>beast</Filter>
</ClInclude>
@@ -1254,6 +1254,21 @@
<ClInclude Include="..\..\beast\insight\Groups.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\net\detail\Parse.h">
<Filter>beast\net\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\net\IPAddress.h">
<Filter>beast\net</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\net\IPAddressV4.h">
<Filter>beast\net</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\net\IPAddressV6.h">
<Filter>beast\net</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\net\IPEndpoint.h">
<Filter>beast\net</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
@@ -1769,9 +1784,6 @@
<ClCompile Include="..\..\beast\utility\impl\PropertyStream.cpp">
<Filter>beast\utility\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddress.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\Asio.cpp">
<Filter>beast\asio</Filter>
</ClCompile>
@@ -1820,6 +1832,18 @@
<ClCompile Include="..\..\beast\insight\impl\Groups.cpp">
<Filter>beast\insight\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddress.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddressV4.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddressV6.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPEndpoint.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\TODO.txt">

View File

@@ -24,5 +24,13 @@
#include "net/DynamicBuffer.h"
#include "net/IPAddress.h"
#include "net/IPAddressV4.h"
#include "net/IPAddressV6.h"
#include "net/IPEndpoint.h"
// VFALCO DEPRECATED, REMOVE ASAP!
namespace beast {
typedef IP::Endpoint IPAddress;
}
#endif

View File

@@ -20,41 +20,47 @@
#ifndef BEAST_ASIO_IPADDRESSCONVERSION_H_INCLUDED
#define BEAST_ASIO_IPADDRESSCONVERSION_H_INCLUDED
#include "../net/IPAddress.h"
#include "../net/IPEndpoint.h"
#include <sstream>
#include <boost/asio.hpp>
namespace beast {
namespace IP {
/** Convert to Endpoint.
The port is set to zero.
*/
Endpoint from_asio (boost::asio::ip::address const& address);
/** Convert to Endpoint. */
Endpoint from_asio (boost::asio::ip::tcp::endpoint const& endpoint);
/** Convert to asio::ip::address.
The port is ignored.
*/
boost::asio::ip::address to_asio_address (Endpoint const& endpoint);
/** Convert to asio::ip::tcp::endpoint. */
boost::asio::ip::tcp::endpoint to_asio_endpoint (Endpoint const& endpoint);
}
}
namespace beast {
// DEPRECATED
struct IPAddressConversion
{
/** Convert to IPAddress.
The port is set to zero.
*/
static IPAddress from_asio (boost::asio::ip::address const& address);
/** Convert to IPAddress, including port. */
static IPAddress from_asio (boost::asio::ip::tcp::endpoint const& endpoint);
/** Convert to asio::ip::address.
The port is ignored.
*/
static boost::asio::ip::address to_asio_address (IPAddress const& address);
/** Convert to asio::ip::tcp::endpoint. */
static boost::asio::ip::tcp::endpoint to_asio_endpoint (IPAddress const& address);
/** Conversions to string. */
/** @{ */
static std::string to_string (boost::asio::ip::tcp::endpoint const& endpoint)
{
std::stringstream ss;
ss << endpoint;
return ss.str();
}
/** @} */
static IP::Endpoint from_asio (boost::asio::ip::address const& address)
{ return IP::from_asio (address); }
static IP::Endpoint from_asio (boost::asio::ip::tcp::endpoint const& endpoint)
{ return IP::from_asio (endpoint); }
static boost::asio::ip::address to_asio_address (IP::Endpoint const& address)
{ return IP::to_asio_address (address); }
static boost::asio::ip::tcp::endpoint to_asio_endpoint (IP::Endpoint const& address)
{ return IP::to_asio_endpoint (address); }
};
}

View File

@@ -20,34 +20,35 @@
#include "../IPAddressConversion.h"
namespace beast {
namespace IP {
IPAddress IPAddressConversion::from_asio (boost::asio::ip::address const& address)
Endpoint from_asio (boost::asio::ip::address const& address)
{
if (address.is_v4 ())
{
boost::asio::ip::address_v4::bytes_type const bytes (
address.to_v4().to_bytes());
return IPAddress (IPAddress::V4 (
return Endpoint (AddressV4 (
bytes [0], bytes [1], bytes [2], bytes [3]));
}
// VFALCO TODO IPv6 support
bassertfalse;
return IPAddress();
return Endpoint();
}
IPAddress IPAddressConversion::from_asio (boost::asio::ip::tcp::endpoint const& endpoint)
Endpoint from_asio (boost::asio::ip::tcp::endpoint const& endpoint)
{
return from_asio (endpoint.address()).withPort (endpoint.port());
return from_asio (endpoint.address()).at_port (endpoint.port());
}
boost::asio::ip::address IPAddressConversion::to_asio_address (IPAddress const& address)
boost::asio::ip::address to_asio_address (Endpoint const& endpoint)
{
if (address.isV4 ())
if (endpoint.address().is_v4())
{
return boost::asio::ip::address (
boost::asio::ip::address_v4 (
address.v4().value));
endpoint.address().to_v4().value));
}
// VFALCO TODO IPv6 support
@@ -56,10 +57,11 @@ boost::asio::ip::address IPAddressConversion::to_asio_address (IPAddress const&
boost::asio::ip::address_v6 ());
}
boost::asio::ip::tcp::endpoint IPAddressConversion::to_asio_endpoint (IPAddress const& address)
boost::asio::ip::tcp::endpoint to_asio_endpoint (Endpoint const& endpoint)
{
return boost::asio::ip::tcp::endpoint (
to_asio_address (address), address.port());
to_asio_address (endpoint), endpoint.port());
}
}
}

View File

@@ -215,11 +215,11 @@ private:
static boost::asio::ip::udp::endpoint to_endpoint (
IPAddress const &address)
{
if (address.isV4 ())
if (address.is_v4 ())
{
return boost::asio::ip::udp::endpoint (
boost::asio::ip::address_v4 (
address.v4().value), address.port ());
address.to_v4().value), address.port ());
}
// VFALCO TODO IPv6 support

View File

@@ -23,388 +23,140 @@
#include <string>
#include <ios>
#include <sstream>
#include "../CStdInt.h"
#include "IPAddressV4.h"
#include "IPAddressV6.h"
//------------------------------------------------------------------------------
namespace beast {
namespace IP {
/** Represents an IP address (v4 or v6) and port combination. */
class IPAddress
/** A version-independent IP address.
This object can represent either an IPv4 or IPv6 address.
*/
class Address
{
public:
/** Create an unspecified IPv4 address. */
Address ();
/** Create an IPv4 address. */
Address (AddressV4 const& addr);
/** Create an IPv6 address. */
Address (AddressV6 const& addr);
/** Assign a copy from another address in any format. */
/** @{ */
Address& operator= (AddressV4 const& addr);
Address& operator= (AddressV6 const& addr);
/** @} */
/** Create an Address from a string.
@return A pair with the address, and bool set to `true` on success.
*/
static std::pair <Address, bool> from_string (std::string const& s);
/** Returns a string representing the address. */
std::string to_string () const;
/** Returns `true` if this address represents an IPv4 address. */
bool is_v4 () const
{ return m_type == ipv4; }
/** Returns `true` if this address represents an IPv6 address. */
bool is_v6 () const
{ return m_type == ipv6; }
/** Returns the IPv4 address.
Precondition:
is_v4() returns true
*/
AddressV4 const& to_v4 () const;
/** Returns the IPv6 address.
Precondition:
is_v6() returns true
*/
AddressV6 const& to_v6 () const;
/** Arithmetic comparison. */
/** @{ */
friend bool operator== (Address const& lhs, Address const& rhs);
friend bool operator< (Address const& lhs, Address const& rhs);
friend bool operator!= (Address const& lhs, Address const& rhs)
{ return ! (lhs == rhs); }
friend bool operator> (Address const& lhs, Address const& rhs)
{ return rhs < lhs; }
friend bool operator<= (Address const& lhs, Address const& rhs)
{ return ! (lhs > rhs); }
friend bool operator>= (Address const& lhs, Address const& rhs)
{ return ! (rhs > lhs); }
/** @} */
private:
enum Type
{
none,
ipv4,
ipv6
};
template <typename Number>
static std::string numberToString (Number n)
{
std::ostringstream os;
os << std::dec << n;
return std::string (os.str());
}
//--------------------------------------------------------------------------
/** Used for IPv4 formats. */
struct V4
{
/** Construct the "any" address. */
V4 ();
/** Construct from a 32-bit unsigned.
@note Octets are formed in order from the MSB to the LSB.
*/
explicit V4 (uint32 value_);
/** Construct from four individual octets..
@note The resulting address is a.b.c.d
*/
V4 (uint8 a, uint8 b, uint8 c, uint8 d);
/** Construct a copy of another address. */
V4 (V4 const& other);
/** Assign a copy of another address. */
V4& operator= (V4 const& other);
/** Returns a V4 address representing the local broadcast address. */
static V4 localBroadcastAddress ();
/** Returns the directed broadcast address for the network implied by this address. */
V4 broadcastAddress () const;
/** Returns the IPv4 address class as 'A', 'B', 'C', or 'D'.
@note Class 'D' represents multicast addresses (224.*.*.*).
*/
char getClass () const;
/** Returns `true` if this is a public routable address. */
bool isPublic () const;
/** Returns `true` if this is a private, non-routable address. */
bool isPrivate () const;
/** Returns `true` if this is a broadcast address. */
bool isBroadcast () const;
/** Returns `true` if this is a multicast address. */
bool isMulticast () const;
/** Returns `true` if this refers to any loopback adapter address. */
bool isLoopback () const;
/** Supports access via operator[]. */
template <bool IsConst>
class Proxy
{
public:
typedef typename std::conditional <
IsConst, uint32 const*, uint32*>::type Pointer;
Proxy (int shift, Pointer value)
: m_shift (shift)
, m_value (value)
{
}
operator uint8() const
{
return ((*m_value)>>m_shift) & 0xff;
}
template <typename IntegralType>
Proxy& operator= (IntegralType v)
{
(*m_value) =
( (*m_value) & (~((0xff)<<m_shift)) )
| ((v&0xff) << m_shift);
return *this;
}
private:
int m_shift;
Pointer m_value;
};
/** Provides read access to individual octets of the IPv4 address. */
Proxy <true> operator[] (std::size_t index) const;
/** Provides read/write access to individual octets of the IPv4 address. */
Proxy <false> operator[] (std::size_t index);
/** Convert the address to a human readable string. */
/** @{ */
std::string to_string () const;
operator std::string () const;
/** @} */
struct hasher
{
std::size_t operator() (V4 const& v) const
{
return v.value;
}
};
/** The value as a 32 bit unsigned. */
uint32 value;
};
//--------------------------------------------------------------------------
/** Used for IPv6 formats. */
struct V6
{
/** Returns `true` if this is a public routable address. */
bool isPublic () const
{
return false;
}
/** Returns `true` if this is a private, non-routable address. */
bool isPrivate () const
{
return false;
}
/** Returns `true` if this is a broadcast address. */
bool isBroadcast () const
{
return false;
}
/** Returns `true` if this is a multicast address. */
bool isMulticast () const
{
return false;
}
/** Returns `true` if this refers to any loopback adapter address. */
bool isLoopback () const
{
return false;
}
/** Convert the address to a human readable string. */
/** @{ */
std::string to_string () const
{
return std::string();
}
operator std::string () const
{
return to_string();
}
/** @} */
struct hasher
{
std::size_t operator() (V6 const&) const
{
return 0;
}
};
};
//--------------------------------------------------------------------------
/** Create an empty address. */
IPAddress ();
/** Create an IPv4 address with optional port. */
IPAddress (V4 const& v4, uint16 port = 0);
/** Create an IPv6 address with optional port. */
IPAddress (V6 const& v6, uint16 port = 0);
/** Create a copy of another IPAddress. */
IPAddress (IPAddress const& other);
/** Copy assign another IPAddress. */
IPAddress& operator= (IPAddress const& other);
/** Create an IPAddress from a string.
If a parsing error occurs, the endpoint will be empty.
*/
static IPAddress from_string (std::string const& s);
/** Create an IPAddress from a string.
If a parsing error occurs, the endpoint will be empty.
This recognizes an alternate form of the text. Instead of a colon
separating the optional port specification, any amount of whitespace
is allowed.
*/
static IPAddress from_string_altform (std::string const& s);
/** Copy assign an IPv4 address.
The port is set to zero.
*/
IPAddress& operator= (V4 const& address);
/** Copy assign an IPv6 address.
The port is set to zero.
*/
IPAddress& operator= (V6 const& address);
/** Returns a new IPAddress with this address, and the given port. */
IPAddress withPort (uint16 port) const;
/** Returns `true` if this IPAddress refers to nothing. */
bool empty () const;
/** Returns `true` if this IPAddress refers to nothing. */
bool isNull () const;
/** Returns `true` if this IPAddress refers to something. */
bool isNotNull () const;
/** Returns the type of this IPAddress. */
Type type () const;
/** Returns `true` if this IPAddress represents an IPv4 address. */
bool isV4 () const;
/** Returns `true` if this IPAddress represents an IPv6 address. */
bool isV6 () const;
/** Returns the IPv4 address.
Undefined behavior results if type() != ipv4.
*/
V4 const& v4 () const;
/** Returns the IPv6 address.
Undefined behavior results if type() != ipv4.
*/
V6 const& v6 () const;
/** Returns the port number.
Undefined if type() == none.
*/
uint16 port () const;
/** Returns `true` if this is a public routable address. */
bool isPublic () const;
/** Returns `true` if this is a private, non-routable address. */
bool isPrivate () const;
/** Returns `true` if this is a broadcast address. */
bool isBroadcast () const;
/** Returns `true` if this is a multicast address. */
bool isMulticast () const;
/** Returns `true` if this refers to any loopback adapter address. */
bool isLoopback () const;
/** Convert the address to a human readable string. */
/** @{ */
std::string to_string () const;
operator std::string () const;
/** @} */
typedef std::hash <IPAddress> hasher;
struct key_equal;
/** LessThanComparable functor that ignores the port. */
struct LessWithoutPort
{
bool operator() (IPAddress const& lhs, IPAddress const& rhs) const;
};
/** EqualityComparable functor that ignores the port. */
struct EqualWithoutPort
{
bool operator() (IPAddress const& lhs, IPAddress const& rhs) const;
};
private:
Type m_type;
uint16 m_port;
V4 m_v4;
V6 m_v6;
AddressV4 m_v4;
AddressV6 m_v6;
};
/** Comparison. */
/** @{ */
bool operator== (IPAddress::V4 const& lhs, IPAddress::V4 const& rhs);
bool operator!= (IPAddress::V4 const& lhs, IPAddress::V4 const& rhs);
bool operator< (IPAddress::V4 const& lhs, IPAddress::V4 const& rhs);
bool operator<= (IPAddress::V4 const& lhs, IPAddress::V4 const& rhs);
bool operator> (IPAddress::V4 const& lhs, IPAddress::V4 const& rhs);
bool operator>= (IPAddress::V4 const& lhs, IPAddress::V4 const& rhs);
//------------------------------------------------------------------------------
bool operator== (IPAddress const& lhs, IPAddress const& rhs);
bool operator!= (IPAddress const& lhs, IPAddress const& rhs);
bool operator< (IPAddress const& lhs, IPAddress const& rhs);
bool operator<= (IPAddress const& lhs, IPAddress const& rhs);
bool operator> (IPAddress const& lhs, IPAddress const& rhs);
bool operator>= (IPAddress const& lhs, IPAddress const& rhs);
// Properties
/** Output stream conversions. */
/** @{ */
std::ostream& operator<< (std::ostream& os, IPAddress::V4 const& addr);
std::ostream& operator<< (std::ostream& os, IPAddress::V6 const& addr);
std::ostream& operator<< (std::ostream& os, IPAddress const& ep);
/** @} */
/** Returns `true` if this is a loopback address. */
bool is_loopback (Address const& addr);
/** Input stream conversions. */
/** @{ */
std::istream& operator>> (std::istream& is, IPAddress::V4& addr);
std::istream& operator>> (std::istream& is, IPAddress& ep);
//std::istream& operator>> (std::istream &is, IPAddress::V6&);
/** @} */
/** Returns `true` if the address is unspecified. */
bool is_unspecified (Address const& addr);
struct IPAddress::key_equal
{
bool operator() (IPAddress const& lhs, IPAddress const& rhs) const
{
return lhs == rhs;
}
};
/** Returns `true` if the address is a multicast address. */
bool is_multicast (Address const& addr);
/** Returns `true` if the address is a private unroutable address. */
bool is_private (Address const& addr);
/** Returns `true` if the address is a public routable address. */
bool is_public (Address const& addr);
//------------------------------------------------------------------------------
/** boost::hash support. */
std::size_t hash_value (Address const& addr);
/** Returns the address represented as a string. */
inline std::string to_string (Address const& addr)
{ return addr.to_string (); }
/** Output stream conversion. */
template <typename OutputStream>
OutputStream& operator<< (OutputStream& os, Address const& addr)
{ return os << to_string (addr); }
/** Input stream conversion. */
std::istream& operator>> (std::istream& is, Address& addr);
inline bool IPAddress::LessWithoutPort::operator() (
IPAddress const& lhs, IPAddress const& rhs) const
{
return lhs.withPort (0) < rhs.withPort (0);
}
inline bool IPAddress::EqualWithoutPort::operator() (
IPAddress const& lhs, IPAddress const& rhs) const
{
return lhs.withPort (0) == rhs.withPort (0);
}
}
//------------------------------------------------------------------------------
namespace std {
template <>
struct hash <beast::IPAddress>
struct hash <beast::IP::Address>
{
std::size_t operator() (beast::IPAddress const& value) const
{
std::size_t hash (0);
if (value.isV4())
hash = beast::IPAddress::V4::hasher() (value.v4());
else if (value.isV6())
hash = beast::IPAddress::V6::hasher() (value.v6());
hash += value.port();
return hash;
}
std::size_t operator() (beast::IP::Address const& addr) const
{ return hash_value (addr); }
};
}
#endif

197
beast/net/IPAddressV4.h Normal file
View File

@@ -0,0 +1,197 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_NET_IPADDRESSV4_H_INCLUDED
#define BEAST_NET_IPADDRESSV4_H_INCLUDED
#include <string>
#include <ios>
#include <utility>
#include "../CStdInt.h"
namespace beast {
namespace IP {
/** Represents a version 4 IP address. */
struct AddressV4
{
/** Default constructor represents the 'any' address. */
AddressV4 ();
/** Construct from a 32-bit unsigned.
@note Octets are formed in order from the MSB to the LSB.
*/
explicit AddressV4 (uint32 value_);
/** Construct from four individual octets..
@note The resulting address is a.b.c.d
*/
AddressV4 (uint8 a, uint8 b, uint8 c, uint8 d);
/** Create an address from an IPv4 address string in dotted decimal form.
@return A pair with the address, and bool set to `true` on success.
*/
static std::pair <AddressV4, bool> from_string (std::string const& s);
/** Returns an address that represents 'any' address. */
static AddressV4 any ()
{ return AddressV4(); }
/** Returns an address that represents the loopback address. */
static AddressV4 loopback ()
{ return AddressV4 (0x7f000001); }
/** Returns an address that represents the broadcast address. */
static AddressV4 broadcast ()
{ return AddressV4 (0xffffffff); }
/** Returns the broadcast address for the specified address. */
static AddressV4 broadcast (AddressV4 const& address);
/** Returns the broadcast address corresponding to the address and mask. */
static AddressV4 broadcast (
AddressV4 const& address, AddressV4 const& mask);
/** Returns `true` if this is a broadcast address. */
bool is_broadcast () const
{ return *this == broadcast (*this); }
/** Returns the address class for the given address.
@note Class 'D' represents multicast addresses (224.*.*.*).
*/
static char get_class (AddressV4 const& address);
/** Returns the netmask for the address class or address. */
/** @{ */
static AddressV4 netmask (char address_class);
static AddressV4 netmask (AddressV4 const& v);
/** @} */
/** Arithmetic comparison. */
/** @{ */
friend bool operator== (AddressV4 const& lhs, AddressV4 const& rhs)
{ return lhs.value == rhs.value; }
friend bool operator< (AddressV4 const& lhs, AddressV4 const& rhs)
{ return lhs.value < rhs.value; }
friend bool operator!= (AddressV4 const& lhs, AddressV4 const& rhs)
{ return ! (lhs == rhs); }
friend bool operator> (AddressV4 const& lhs, AddressV4 const& rhs)
{ return rhs < lhs; }
friend bool operator<= (AddressV4 const& lhs, AddressV4 const& rhs)
{ return ! (lhs > rhs); }
friend bool operator>= (AddressV4 const& lhs, AddressV4 const& rhs)
{ return ! (rhs > lhs); }
/** @} */
/** Array indexing for reading and writing indiviual octets. */
/** @{ */
template <bool IsConst>
class Proxy
{
public:
typedef typename std::conditional <
IsConst, uint32 const*, uint32*>::type Pointer;
Proxy (int shift, Pointer value)
: m_shift (shift)
, m_value (value)
{
}
operator uint8() const
{
return ((*m_value)>>m_shift) & 0xff;
}
template <typename IntegralType>
Proxy& operator= (IntegralType v)
{
(*m_value) =
( (*m_value) & (~((0xff)<<m_shift)) )
| ((v&0xff) << m_shift);
return *this;
}
private:
int m_shift;
Pointer m_value;
};
Proxy <true> operator[] (std::size_t index) const;
Proxy <false> operator[] (std::size_t index);
/** @{ */
/** The value as a 32 bit unsigned. */
uint32 value;
};
//------------------------------------------------------------------------------
/** Returns `true` if this is a loopback address. */
bool is_loopback (AddressV4 const& addr);
/** Returns `true` if the address is unspecified. */
bool is_unspecified (AddressV4 const& addr);
/** Returns `true` if the address is a multicast address. */
bool is_multicast (AddressV4 const& addr);
/** Returns `true` if the address is a private unroutable address. */
bool is_private (AddressV4 const& addr);
/** Returns `true` if the address is a public routable address. */
bool is_public (AddressV4 const& addr);
//------------------------------------------------------------------------------
/** boost::hash support. */
inline std::size_t hash_value (AddressV4 const& addr)
{ return addr.value; }
/** Returns the address represented as a string. */
std::string to_string (AddressV4 const& addr);
/** Output stream conversion. */
template <typename OutputStream>
OutputStream& operator<< (OutputStream& os, AddressV4 const& addr)
{ return os << to_string (addr); }
/** Input stream conversion. */
std::istream& operator>> (std::istream& is, AddressV4& addr);
}
}
//------------------------------------------------------------------------------
namespace std {
template <typename T> struct hash;
/** std::hash support. */
template <>
struct hash <beast::IP::AddressV4>
{
std::size_t operator() (beast::IP::AddressV4 const& addr) const
{ return hash_value (addr); }
};
}
#endif

105
beast/net/IPAddressV6.h Normal file
View File

@@ -0,0 +1,105 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_NET_IPADDRESSV6_H_INCLUDED
#define BEAST_NET_IPADDRESSV6_H_INCLUDED
#include <string>
#include <ios>
#include <utility>
#include "../CStdInt.h"
namespace beast {
namespace IP {
/** Represents a version 4 IP address. */
struct AddressV6
{
// VFALCO TODO
/** Arithmetic comparison. */
/** @{ */
friend bool operator== (AddressV6 const&, AddressV6 const&)
{ bassertfalse; return false; }
friend bool operator< (AddressV6 const&, AddressV6 const&)
{ bassertfalse; return false; }
friend bool operator!= (AddressV6 const& lhs, AddressV6 const& rhs)
{ return ! (lhs == rhs); }
friend bool operator> (AddressV6 const& lhs, AddressV6 const& rhs)
{ return rhs < lhs; }
friend bool operator<= (AddressV6 const& lhs, AddressV6 const& rhs)
{ return ! (lhs > rhs); }
friend bool operator>= (AddressV6 const& lhs, AddressV6 const& rhs)
{ return ! (rhs > lhs); }
/** @} */
};
//------------------------------------------------------------------------------
/** Returns `true` if this is a loopback address. */
bool is_loopback (AddressV6 const& addr);
/** Returns `true` if the address is unspecified. */
bool is_unspecified (AddressV6 const& addr);
/** Returns `true` if the address is a multicast address. */
bool is_multicast (AddressV6 const& addr);
/** Returns `true` if the address is a private unroutable address. */
bool is_private (AddressV6 const& addr);
/** Returns `true` if the address is a public routable address. */
bool is_public (AddressV6 const& addr);
//------------------------------------------------------------------------------
/** boost::hash support. */
inline std::size_t hash_value (AddressV6 const&)
{ bassertfalse; return 0; }
/** Returns the address represented as a string. */
std::string to_string (AddressV6 const& addr);
/** Output stream conversion. */
template <typename OutputStream>
OutputStream& operator<< (OutputStream& os, AddressV6 const& addr)
{ return os << to_string (addr); }
/** Input stream conversion. */
std::istream& operator>> (std::istream& is, AddressV6& addr);
}
}
//------------------------------------------------------------------------------
namespace std {
template <typename T> struct hash;
/** std::hash support. */
template <>
struct hash <beast::IP::AddressV6>
{
std::size_t operator() (beast::IP::AddressV6 const& addr) const
{ return hash_value (addr); }
};
}
#endif

159
beast/net/IPEndpoint.h Normal file
View File

@@ -0,0 +1,159 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_NET_IPENDPOINT_H_INCLUDED
#define BEAST_NET_IPENDPOINT_H_INCLUDED
#include <string>
#include <ios>
#include "../CStdInt.h"
#include "IPAddress.h"
namespace beast {
namespace IP {
typedef uint16 Port;
/** A version-independent IP address and port combination. */
class Endpoint
{
public:
/** Create an unspecified endpoint. */
Endpoint ();
/** Create an endpoint from the address and optional port. */
explicit Endpoint (Address const& addr, Port port = 0);
/** Create an Endpoint from a string.
If the port is omitted, the endpoint will have a zero port.
@return A pair with the endpoint, and bool set to `true` on success.
*/
static std::pair <Endpoint, bool> from_string_checked (std::string const& s);
static Endpoint from_string (std::string const& s);
static Endpoint from_string_altform (std::string const& s);
/** Returns a string representing the endpoint. */
std::string to_string () const;
/** Returns the port number on the endpoint. */
Port port () const
{ return m_port; }
/** Returns a new Endpoint with a different port. */
Endpoint at_port (Port port) const
{ return Endpoint (m_addr, port); }
/** Returns the address portion of this endpoint. */
Address const& address () const
{ return m_addr; }
/** Convenience accessors for the address part. */
/** @{ */
bool is_v4 () const
{ return m_addr.is_v4(); }
bool is_v6 () const
{ return m_addr.is_v6(); }
AddressV4 const& to_v4 () const
{ return m_addr.to_v4 (); }
AddressV6 const& to_v6 () const
{ return m_addr.to_v6 (); }
/** @} */
/** Arithmetic comparison. */
/** @{ */
friend bool operator== (Endpoint const& lhs, Endpoint const& rhs);
friend bool operator< (Endpoint const& lhs, Endpoint const& rhs);
friend bool operator!= (Endpoint const& lhs, Endpoint const& rhs)
{ return ! (lhs == rhs); }
friend bool operator> (Endpoint const& lhs, Endpoint const& rhs)
{ return rhs < lhs; }
friend bool operator<= (Endpoint const& lhs, Endpoint const& rhs)
{ return ! (lhs > rhs); }
friend bool operator>= (Endpoint const& lhs, Endpoint const& rhs)
{ return ! (rhs > lhs); }
/** @} */
private:
Address m_addr;
Port m_port;
};
//------------------------------------------------------------------------------
// Properties
/** Returns `true` if the endpoint is a loopback address. */
inline bool is_loopback (Endpoint const& endpoint)
{ return is_loopback (endpoint.address ()); }
/** Returns `true` if the endpoint is unspecified. */
inline bool is_unspecified (Endpoint const& endpoint)
{ return is_unspecified (endpoint.address ()); }
/** Returns `true` if the endpoint is a multicast address. */
inline bool is_multicast (Endpoint const& endpoint)
{ return is_multicast (endpoint.address ()); }
/** Returns `true` if the endpoint is a private unroutable address. */
inline bool is_private (Endpoint const& endpoint)
{ return is_private (endpoint.address ()); }
/** Returns `true` if the endpoint is a public routable address. */
inline bool is_public (Endpoint const& endpoint)
{ return is_public (endpoint.address ()); }
//------------------------------------------------------------------------------
/** boost::hash support. */
std::size_t hash_value (Endpoint const& endpoint);
/** Returns the endpoint represented as a string. */
inline std::string to_string (Endpoint const& endpoint)
{ return endpoint.to_string(); }
/** Output stream conversion. */
template <typename OutputStream>
OutputStream& operator<< (OutputStream& os, Endpoint const& endpoint)
{
os << to_string (endpoint);
return os;
}
/** Input stream conversion. */
std::istream& operator>> (std::istream& is, Endpoint& endpoint);
}
}
//------------------------------------------------------------------------------
namespace std {
template <typename T> struct hash;
/** std::hash support. */
template <>
struct hash <beast::IP::Endpoint>
{
std::size_t operator() (beast::IP::Endpoint const& endpoint) const
{ return hash_value (endpoint); }
};
}
#endif

View File

@@ -25,3 +25,8 @@
#include "impl/DynamicBuffer.cpp"
#include "impl/IPAddress.cpp"
#include "impl/IPAddressV4.cpp"
#include "impl/IPAddressV6.cpp"
#include "impl/IPEndpoint.cpp"

89
beast/net/detail/Parse.h Normal file
View File

@@ -0,0 +1,89 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_NET_DETAIL_PARSE_H_INCLUDED
#define BEAST_NET_DETAIL_PARSE_H_INCLUDED
#include <ios>
#include <string>
namespace beast {
namespace IP {
namespace detail {
/** Require and consume the specified character from the input.
@return `true` if the character matched.
*/
template <typename InputStream>
bool expect (InputStream& is, char v)
{
char c;
if (is.get(c) && v == c)
return true;
is.unget();
is.setstate (std::ios_base::failbit);
return false;
}
/** Used to disambiguate 8-bit integers from characters. */
template <typename IntType>
struct integer_holder
{
IntType* pi;
explicit integer_holder (IntType& i)
: pi (&i)
{
}
template <typename OtherIntType>
IntType& operator= (OtherIntType o) const
{
*pi = o;
return *pi;
}
};
/** Parse 8-bit unsigned integer. */
template <typename InputStream>
InputStream& operator>> (InputStream& is, integer_holder <uint8> const& i)
{
uint16 v;
is >> v;
if (! (v>=0 && v<=255))
{
is.setstate (std::ios_base::failbit);
return is;
}
i = uint8(v);
return is;
}
/** Free function for template argument deduction. */
template <typename IntType>
integer_holder <IntType> integer (IntType& i)
{
return integer_holder <IntType> (i);
}
}
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../IPAddressV4.h"
namespace beast {
namespace IP {
AddressV4::AddressV4 ()
: value (0)
{
}
AddressV4::AddressV4 (uint32 value_)
: value (value_)
{
}
AddressV4::AddressV4 (uint8 a, uint8 b, uint8 c, uint8 d)
: value ((a<<24)|(b<<16)|(c<<8)|d)
{
}
std::pair <AddressV4, bool> AddressV4::from_string (std::string const& s)
{
std::stringstream is (s);
AddressV4 addr;
is >> addr;
if (! is.fail() && is.rdbuf()->in_avail() == 0)
return std::make_pair (addr, true);
return std::make_pair (AddressV4 (), false);
}
AddressV4 AddressV4::broadcast (AddressV4 const& address)
{
return broadcast (address, netmask (address));
}
AddressV4 AddressV4::broadcast (
AddressV4 const& address, AddressV4 const& mask)
{
return AddressV4 (address.value | (mask.value ^ 0xffffffff));
}
char AddressV4::get_class (AddressV4 const& addr)
{
static char const* table = "AAAABBCD";
return table [(addr.value & 0xE0000000) >> 29];
}
AddressV4 AddressV4::netmask (char address_class)
{
switch (address_class)
{
case 'A': return AddressV4 (0xff000000);
case 'B': return AddressV4 (0xffff0000);
case 'C': return AddressV4 (0xffffff00);
case 'D':
default:
break;
}
return AddressV4 (0xffffffff);
}
AddressV4 AddressV4::netmask (AddressV4 const& addr)
{
return netmask (get_class (addr));
}
AddressV4::Proxy <true> AddressV4::operator[] (std::size_t index) const
{
switch (index)
{
default:
bassertfalse;
case 0: return Proxy <true> (24, &value);
case 1: return Proxy <true> (16, &value);
case 2: return Proxy <true> ( 8, &value);
case 3: return Proxy <true> ( 0, &value);
};
};
AddressV4::Proxy <false> AddressV4::operator[] (std::size_t index)
{
switch (index)
{
default:
bassertfalse;
case 0: return Proxy <false> (24, &value);
case 1: return Proxy <false> (16, &value);
case 2: return Proxy <false> ( 8, &value);
case 3: return Proxy <false> ( 0, &value);
};
};
//------------------------------------------------------------------------------
bool is_loopback (AddressV4 const& addr)
{
return (addr.value & 0xff000000) == 0x7f000000;
}
bool is_unspecified (AddressV4 const& addr)
{
return addr.value == 0;
}
bool is_multicast (AddressV4 const& addr)
{
return (addr.value & 0xf0000000) == 0xe0000000;
}
bool is_private (AddressV4 const& addr)
{
return
((addr.value & 0xff000000) == 0x0a000000) || // Prefix /8, 10. #.#.#
((addr.value & 0xfff00000) == 0xac100000) || // Prefix /12 172. 16.#.# - 172.31.#.#
((addr.value & 0xffff0000) == 0xc0a80000) || // Prefix /16 192.168.#.#
is_loopback (addr);
}
bool is_public (AddressV4 const& addr)
{
return
! is_private (addr) &&
! is_multicast (addr) &&
(addr != AddressV4::broadcast (addr));
}
//------------------------------------------------------------------------------
std::string to_string (AddressV4 const& addr)
{
std::string s;
s.reserve (15);
s =
std::to_string (addr[0]) + "." +
std::to_string (addr[1]) + "." +
std::to_string (addr[2]) + "." +
std::to_string (addr[3]);
return s;
}
std::istream& operator>> (std::istream& is, AddressV4& addr)
{
uint8 octet [4];
is >> IP::detail::integer (octet [0]);
for (int i = 1; i < 4; ++i)
{
if (!is || !IP::detail::expect (is, '.'))
return is;
is >> IP::detail::integer (octet [i]);
if (!is)
return is;
}
addr = AddressV4 (octet[0], octet[1], octet[2], octet[3]);
return is;
}
}
}

View File

@@ -0,0 +1,79 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../IPAddressV6.h"
namespace beast {
namespace IP {
//------------------------------------------------------------------------------
bool is_loopback (AddressV6 const&)
{
// VFALCO TODO
bassertfalse;
return false;
}
bool is_unspecified (AddressV6 const&)
{
// VFALCO TODO
bassertfalse;
return false;
}
bool is_multicast (AddressV6 const&)
{
// VFALCO TODO
bassertfalse;
return false;
}
bool is_private (AddressV6 const&)
{
// VFALCO TODO
bassertfalse;
return false;
}
bool is_public (AddressV6 const&)
{
// VFALCO TODO
bassertfalse;
return false;
}
//------------------------------------------------------------------------------
std::string to_string (AddressV6 const&)
{
// VFALCO TODO
bassertfalse;
return "";
}
std::istream& operator>> (std::istream& is, AddressV6&)
{
// VFALCO TODO
bassertfalse;
return is;
}
}
}

View File

@@ -0,0 +1,176 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast {
namespace IP {
Endpoint::Endpoint ()
: m_port (0)
{
}
Endpoint::Endpoint (Address const& addr, Port port)
: m_addr (addr)
, m_port (port)
{
}
std::pair <Endpoint, bool> Endpoint::from_string_checked (std::string const& s)
{
std::stringstream is (s);
Endpoint endpoint;
is >> endpoint;
if (! is.fail() && is.rdbuf()->in_avail() == 0)
return std::make_pair (endpoint, true);
return std::make_pair (Endpoint (), false);
}
Endpoint Endpoint::from_string (std::string const& s)
{
std::pair <Endpoint, bool> const result (
from_string_checked (s));
if (result.second)
return result.first;
return Endpoint();
}
// VFALCO NOTE This is a hack to support legacy data format
//
Endpoint Endpoint::from_string_altform (std::string const& s)
{
// Accept the regular form if it parses
{
Endpoint ep (Endpoint::from_string (s));
if (! is_unspecified (ep))
return ep;
}
// Now try the alt form
std::stringstream is (s);
AddressV4 v4;
is >> v4;
if (! is.fail())
{
Endpoint ep (v4);
if (is.rdbuf()->in_avail()>0)
{
if (! IP::detail::expect (is, ' '))
return Endpoint();
while (is.rdbuf()->in_avail()>0)
{
char c;
is.get(c);
if (c != ' ')
{
is.unget();
break;
}
}
Port port;
is >> port;
if (is.fail())
return Endpoint();
return ep.at_port (port);
}
else
{
// Just an address with no port
return ep;
}
}
// Could be V6 here...
return Endpoint();
}
std::string Endpoint::to_string () const
{
std::string s (address ().to_string ());
if (port() != 0)
s = s + ":" + std::to_string (port());
return s;
}
bool operator== (Endpoint const& lhs, Endpoint const& rhs)
{
return lhs.address() == rhs.address() &&
lhs.port() == rhs.port();
}
bool operator< (Endpoint const& lhs, Endpoint const& rhs)
{
if (lhs.address() < rhs.address())
return true;
if (lhs.address() > rhs.address())
return false;
return lhs.port() < rhs.port();
}
//------------------------------------------------------------------------------
std::size_t hash_value (Endpoint const& endpoint)
{
std::size_t seed (hash_value (endpoint.address ()));
// boost::hash_combine()
seed ^= (std::hash <Port> () (endpoint.port ()))
+ 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
std::istream& operator>> (std::istream& is, Endpoint& endpoint)
{
// VFALCO TODO Support ipv6!
Address addr;
is >> addr;
if (is.fail())
return is;
if (is.rdbuf()->in_avail()>0)
{
char c;
is.get(c);
if (c != ':')
{
is.unget();
endpoint = Endpoint (addr);
return is;
}
Port port;
is >> port;
if (is.fail())
return is;
endpoint = Endpoint (addr, port);
return is;
}
endpoint = Endpoint (addr);
return is;
}
}
}

View File

@@ -146,6 +146,4 @@
//#define BEAST_USE_BOOST_FEATURES 1
#endif
//------------------------------------------------------------------------------
#endif