ext-boost/boost/url/impl/ipv4_address.ipp
2023-05-22 18:45:02 +10:00

168 lines
3.1 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/url
//
#ifndef BOOST_URL_IMPL_IPV4_ADDRESS_IPP
#define BOOST_URL_IMPL_IPV4_ADDRESS_IPP
#include <boost/url/ipv4_address.hpp>
#include <boost/url/detail/except.hpp>
#include <boost/url/rfc/ipv4_address_rule.hpp>
#include <cstring>
namespace boost {
namespace urls {
ipv4_address::
ipv4_address(
uint_type addr) noexcept
: addr_(addr)
{
}
ipv4_address::
ipv4_address(
bytes_type const& bytes) noexcept
{
addr_ =
(static_cast<unsigned long>(bytes[0]) << 24) |
(static_cast<unsigned long>(bytes[1]) << 16) |
(static_cast<unsigned long>(bytes[2]) << 8) |
(static_cast<unsigned long>(bytes[3]));
}
ipv4_address::
ipv4_address(
string_view s)
: ipv4_address(
parse_ipv4_address(s
).value(BOOST_URL_POS))
{
}
auto
ipv4_address::
to_bytes() const noexcept ->
bytes_type
{
bytes_type bytes;
bytes[0] = (addr_ >> 24) & 0xff;
bytes[1] = (addr_ >> 16) & 0xff;
bytes[2] = (addr_ >> 8) & 0xff;
bytes[3] = addr_ & 0xff;
return bytes;
}
auto
ipv4_address::
to_uint() const noexcept ->
uint_type
{
return addr_;
}
string_view
ipv4_address::
to_buffer(
char* dest,
std::size_t dest_size) const
{
if(dest_size < max_str_len)
detail::throw_length_error();
auto n = print_impl(dest);
return string_view(dest, n);
}
bool
ipv4_address::
is_loopback() const noexcept
{
return (to_uint() & 0xFF000000) ==
0x7F000000;
}
bool
ipv4_address::
is_unspecified() const noexcept
{
return to_uint() == 0;
}
bool
ipv4_address::
is_multicast() const noexcept
{
return (to_uint() & 0xF0000000) ==
0xE0000000;
}
std::size_t
ipv4_address::
print_impl(
char* dest) const noexcept
{
auto const start = dest;
auto const write =
[]( char*& dest,
unsigned char v)
{
if(v >= 100)
{
*dest++ = '0' +
v / 100;
v %= 100;
*dest++ = '0' +
v / 10;
v %= 10;
}
else if(v >= 10)
{
*dest++ = '0' +
v / 10;
v %= 10;
}
*dest++ = '0' + v;
};
auto const v = to_uint();
write(dest, (v >> 24) & 0xff);
*dest++ = '.';
write(dest, (v >> 16) & 0xff);
*dest++ = '.';
write(dest, (v >> 8) & 0xff);
*dest++ = '.';
write(dest, (v ) & 0xff);
return dest - start;
}
void
ipv4_address::
to_string_impl(
string_token::arg& t) const
{
char buf[max_str_len];
auto const n = print_impl(buf);
char* dest = t.prepare(n);
std::memcpy(dest, buf, n);
}
//------------------------------------------------
auto
parse_ipv4_address(
string_view s) noexcept ->
result<ipv4_address>
{
return grammar::parse(
s, ipv4_address_rule);
}
} // urls
} // boost
#endif