Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 :
11 : #include <boost/url/detail/config.hpp>
12 : #include <boost/url/ipv4_address.hpp>
13 : #include <boost/url/detail/except.hpp>
14 : #include <boost/url/grammar/parse.hpp>
15 : #include <boost/url/rfc/ipv4_address_rule.hpp>
16 : #include <cstring>
17 :
18 : namespace boost {
19 : namespace urls {
20 :
21 19 : ipv4_address::
22 : ipv4_address(
23 19 : uint_type addr) noexcept
24 19 : : addr_(addr)
25 : {
26 19 : }
27 :
28 142 : ipv4_address::
29 : ipv4_address(
30 142 : bytes_type const& bytes) noexcept
31 : {
32 142 : addr_ =
33 142 : (static_cast<unsigned long>(bytes[0]) << 24) |
34 142 : (static_cast<unsigned long>(bytes[1]) << 16) |
35 142 : (static_cast<unsigned long>(bytes[2]) << 8) |
36 142 : (static_cast<unsigned long>(bytes[3]));
37 142 : }
38 :
39 27 : ipv4_address::
40 : ipv4_address(
41 27 : core::string_view s)
42 : : ipv4_address(
43 27 : parse_ipv4_address(s
44 27 : ).value(BOOST_URL_POS))
45 : {
46 26 : }
47 :
48 : auto
49 76 : ipv4_address::
50 : to_bytes() const noexcept ->
51 : bytes_type
52 : {
53 : bytes_type bytes;
54 76 : bytes[0] = (addr_ >> 24) & 0xff;
55 76 : bytes[1] = (addr_ >> 16) & 0xff;
56 76 : bytes[2] = (addr_ >> 8) & 0xff;
57 76 : bytes[3] = addr_ & 0xff;
58 76 : return bytes;
59 : }
60 :
61 : auto
62 54 : ipv4_address::
63 : to_uint() const noexcept ->
64 : uint_type
65 : {
66 54 : return addr_;
67 : }
68 :
69 : core::string_view
70 19 : ipv4_address::
71 : to_buffer(
72 : char* dest,
73 : std::size_t dest_size) const
74 : {
75 19 : if(dest_size < max_str_len)
76 1 : detail::throw_length_error();
77 18 : auto n = print_impl(dest);
78 18 : return core::string_view(dest, n);
79 : }
80 :
81 : bool
82 4 : ipv4_address::
83 : is_loopback() const noexcept
84 : {
85 4 : return (to_uint() & 0xFF000000) ==
86 4 : 0x7F000000;
87 : }
88 :
89 : bool
90 7 : ipv4_address::
91 : is_unspecified() const noexcept
92 : {
93 7 : return to_uint() == 0;
94 : }
95 :
96 : bool
97 4 : ipv4_address::
98 : is_multicast() const noexcept
99 : {
100 4 : return (to_uint() & 0xF0000000) ==
101 4 : 0xE0000000;
102 : }
103 :
104 : void
105 1 : ipv4_address::
106 : write_ostream(std::ostream& os) const
107 : {
108 : char buf[ipv4_address::max_str_len];
109 1 : os << to_buffer(buf, sizeof(buf));
110 1 : }
111 :
112 : std::size_t
113 29 : ipv4_address::
114 : print_impl(
115 : char* dest) const noexcept
116 : {
117 29 : auto const start = dest;
118 : auto const write =
119 116 : []( char*& dest,
120 : unsigned char v)
121 : {
122 116 : if(v >= 100)
123 : {
124 33 : *dest++ = '0' +
125 33 : v / 100;
126 33 : v %= 100;
127 33 : *dest++ = '0' +
128 33 : v / 10;
129 33 : v %= 10;
130 : }
131 83 : else if(v >= 10)
132 : {
133 3 : *dest++ = '0' +
134 3 : v / 10;
135 3 : v %= 10;
136 : }
137 116 : *dest++ = '0' + v;
138 116 : };
139 29 : auto const v = to_uint();
140 29 : write(dest, (v >> 24) & 0xff);
141 29 : *dest++ = '.';
142 29 : write(dest, (v >> 16) & 0xff);
143 29 : *dest++ = '.';
144 29 : write(dest, (v >> 8) & 0xff);
145 29 : *dest++ = '.';
146 29 : write(dest, (v ) & 0xff);
147 29 : return dest - start;
148 : }
149 :
150 : void
151 2 : ipv4_address::
152 : to_string_impl(
153 : string_token::arg& t) const
154 : {
155 : char buf[max_str_len];
156 2 : auto const n = print_impl(buf);
157 2 : char* dest = t.prepare(n);
158 2 : std::memcpy(dest, buf, n);
159 2 : }
160 :
161 : //------------------------------------------------
162 :
163 : auto
164 127 : parse_ipv4_address(
165 : core::string_view s) noexcept ->
166 : system::result<ipv4_address>
167 : {
168 127 : return grammar::parse(
169 127 : s, ipv4_address_rule);
170 : }
171 :
172 : } // urls
173 : } // boost
174 :
|