1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! A private parser implementation of IPv4, IPv6, and socket addresses.
13 //! This module is "publicly exported" through the `FromStr` implementations
19 use net
::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}
;
22 // parsing as ASCII, so can use byte array
28 fn new(s
: &'a
str) -> Parser
<'a
> {
35 fn is_eof(&self) -> bool
{
36 self.pos
== self.s
.len()
39 // Commit only if parser returns Some
40 fn read_atomically
<T
, F
>(&mut self, cb
: F
) -> Option
<T
> where
41 F
: FnOnce(&mut Parser
) -> Option
<T
>,
51 // Commit only if parser read till EOF
52 fn read_till_eof
<T
, F
>(&mut self, cb
: F
) -> Option
<T
> where
53 F
: FnOnce(&mut Parser
) -> Option
<T
>,
55 self.read_atomically(move |p
| {
57 Some(x
) => if p
.is_eof() {Some(x)}
else {None}
,
63 // Return result of first successful parser
64 fn read_or
<T
>(&mut self, parsers
: &mut [Box
<FnMut(&mut Parser
) -> Option
<T
> + '
static>])
67 match self.read_atomically(|p
: &mut Parser
| pf(p
)) {
68 Some(r
) => return Some(r
),
75 // Apply 3 parsers sequentially
76 fn read_seq_3
<A
, B
, C
, PA
, PB
, PC
>(&mut self,
80 -> Option
<(A
, B
, C
)> where
81 PA
: FnOnce(&mut Parser
) -> Option
<A
>,
82 PB
: FnOnce(&mut Parser
) -> Option
<B
>,
83 PC
: FnOnce(&mut Parser
) -> Option
<C
>,
85 self.read_atomically(move |p
| {
87 let b
= if a
.is_some() { pb(p) }
else { None }
;
88 let c
= if b
.is_some() { pc(p) }
else { None }
;
90 (Some(a
), Some(b
), Some(c
)) => Some((a
, b
, c
)),
97 fn read_char(&mut self) -> Option
<char> {
101 let r
= self.s
[self.pos
] as char;
107 // Return char and advance iff next char is equal to requested
108 fn read_given_char(&mut self, c
: char) -> Option
<char> {
109 self.read_atomically(|p
| {
110 match p
.read_char() {
111 Some(next
) if next
== c
=> Some(next
),
118 fn read_digit(&mut self, radix
: u8) -> Option
<u8> {
119 fn parse_digit(c
: char, radix
: u8) -> Option
<u8> {
121 // assuming radix is either 10 or 16
122 if c
>= b'
0'
&& c
<= b'
9'
{
124 } else if radix
> 10 && c
>= b'a'
&& c
< b'a'
+ (radix
- 10) {
126 } else if radix
> 10 && c
>= b'A'
&& c
< b'A'
+ (radix
- 10) {
133 self.read_atomically(|p
| {
134 p
.read_char().and_then(|c
| parse_digit(c
, radix
))
138 fn read_number_impl(&mut self, radix
: u8, max_digits
: u32, upto
: u32) -> Option
<u32> {
140 let mut digit_count
= 0;
142 match self.read_digit(radix
) {
144 r
= r
* (radix
as u32) + (d
as u32);
146 if digit_count
> max_digits
|| r
>= upto
{
151 if digit_count
== 0 {
161 // Read number, failing if max_digits of number value exceeded
162 fn read_number(&mut self, radix
: u8, max_digits
: u32, upto
: u32) -> Option
<u32> {
163 self.read_atomically(|p
| p
.read_number_impl(radix
, max_digits
, upto
))
166 fn read_ipv4_addr_impl(&mut self) -> Option
<Ipv4Addr
> {
170 if i
!= 0 && self.read_given_char('
.'
).is_none() {
174 let octet
= self.read_number(10, 3, 0x100).map(|n
| n
as u8);
176 Some(d
) => bs
[i
] = d
,
181 Some(Ipv4Addr
::new(bs
[0], bs
[1], bs
[2], bs
[3]))
185 fn read_ipv4_addr(&mut self) -> Option
<Ipv4Addr
> {
186 self.read_atomically(|p
| p
.read_ipv4_addr_impl())
189 fn read_ipv6_addr_impl(&mut self) -> Option
<Ipv6Addr
> {
190 fn ipv6_addr_from_head_tail(head
: &[u16], tail
: &[u16]) -> Ipv6Addr
{
191 assert
!(head
.len() + tail
.len() <= 8);
193 gs
.clone_from_slice(head
);
194 gs
[(8 - tail
.len()) .. 8].clone_from_slice(tail
);
195 Ipv6Addr
::new(gs
[0], gs
[1], gs
[2], gs
[3], gs
[4], gs
[5], gs
[6], gs
[7])
198 fn read_groups(p
: &mut Parser
, groups
: &mut [u16; 8], limit
: usize)
203 let ipv4
= p
.read_atomically(|p
| {
204 if i
== 0 || p
.read_given_char('
:'
).is_some() {
210 if let Some(v4_addr
) = ipv4
{
211 let octets
= v4_addr
.octets();
212 groups
[i
+ 0] = ((octets
[0] as u16) << 8) | (octets
[1] as u16);
213 groups
[i
+ 1] = ((octets
[2] as u16) << 8) | (octets
[3] as u16);
214 return (i
+ 2, true);
218 let group
= p
.read_atomically(|p
| {
219 if i
== 0 || p
.read_given_char('
:'
).is_some() {
220 p
.read_number(16, 4, 0x10000).map(|n
| n
as u16)
226 Some(g
) => groups
[i
] = g
,
227 None
=> return (i
, false)
234 let mut head
= [0; 8];
235 let (head_size
, head_ipv4
) = read_groups(self, &mut head
, 8);
238 return Some(Ipv6Addr
::new(
239 head
[0], head
[1], head
[2], head
[3],
240 head
[4], head
[5], head
[6], head
[7]))
243 // IPv4 part is not allowed before `::`
248 // read `::` if previous code parsed less than 8 groups
249 if !self.read_given_char('
:'
).is_some() || !self.read_given_char('
:'
).is_some() {
253 let mut tail
= [0; 8];
254 let (tail_size
, _
) = read_groups(self, &mut tail
, 8 - head_size
);
255 Some(ipv6_addr_from_head_tail(&head
[..head_size
], &tail
[..tail_size
]))
258 fn read_ipv6_addr(&mut self) -> Option
<Ipv6Addr
> {
259 self.read_atomically(|p
| p
.read_ipv6_addr_impl())
262 fn read_ip_addr(&mut self) -> Option
<IpAddr
> {
263 let ipv4_addr
= |p
: &mut Parser
| p
.read_ipv4_addr().map(|v4
| IpAddr
::V4(v4
));
264 let ipv6_addr
= |p
: &mut Parser
| p
.read_ipv6_addr().map(|v6
| IpAddr
::V6(v6
));
265 self.read_or(&mut [Box
::new(ipv4_addr
), Box
::new(ipv6_addr
)])
268 fn read_socket_addr(&mut self) -> Option
<SocketAddr
> {
269 let ip_addr
= |p
: &mut Parser
| {
270 let ipv4_p
= |p
: &mut Parser
| p
.read_ip_addr();
271 let ipv6_p
= |p
: &mut Parser
| {
272 let open_br
= |p
: &mut Parser
| p
.read_given_char('
['
);
273 let ip_addr
= |p
: &mut Parser
| p
.read_ipv6_addr();
274 let clos_br
= |p
: &mut Parser
| p
.read_given_char('
]'
);
275 p
.read_seq_3
::<char, Ipv6Addr
, char, _
, _
, _
>(open_br
, ip_addr
, clos_br
)
276 .map(|t
| match t { (_, ip, _) => IpAddr::V6(ip) }
)
278 p
.read_or(&mut [Box
::new(ipv4_p
), Box
::new(ipv6_p
)])
280 let colon
= |p
: &mut Parser
| p
.read_given_char('
:'
);
281 let port
= |p
: &mut Parser
| p
.read_number(10, 5, 0x10000).map(|n
| n
as u16);
284 self.read_seq_3(ip_addr
, colon
, port
).map(|t
| {
285 let (ip
, _
, port
): (IpAddr
, char, u16) = t
;
287 IpAddr
::V4(ip
) => SocketAddr
::V4(SocketAddrV4
::new(ip
, port
)),
288 IpAddr
::V6(ip
) => SocketAddr
::V6(SocketAddrV6
::new(ip
, port
, 0, 0)),
294 #[stable(feature = "rust1", since = "1.0.0")]
295 impl FromStr
for IpAddr
{
296 type Err
= AddrParseError
;
297 fn from_str(s
: &str) -> Result
<IpAddr
, AddrParseError
> {
298 match Parser
::new(s
).read_till_eof(|p
| p
.read_ip_addr()) {
300 None
=> Err(AddrParseError(()))
305 #[stable(feature = "rust1", since = "1.0.0")]
306 impl FromStr
for Ipv4Addr
{
307 type Err
= AddrParseError
;
308 fn from_str(s
: &str) -> Result
<Ipv4Addr
, AddrParseError
> {
309 match Parser
::new(s
).read_till_eof(|p
| p
.read_ipv4_addr()) {
311 None
=> Err(AddrParseError(()))
316 #[stable(feature = "rust1", since = "1.0.0")]
317 impl FromStr
for Ipv6Addr
{
318 type Err
= AddrParseError
;
319 fn from_str(s
: &str) -> Result
<Ipv6Addr
, AddrParseError
> {
320 match Parser
::new(s
).read_till_eof(|p
| p
.read_ipv6_addr()) {
322 None
=> Err(AddrParseError(()))
327 #[stable(feature = "rust1", since = "1.0.0")]
328 impl FromStr
for SocketAddr
{
329 type Err
= AddrParseError
;
330 fn from_str(s
: &str) -> Result
<SocketAddr
, AddrParseError
> {
331 match Parser
::new(s
).read_till_eof(|p
| p
.read_socket_addr()) {
333 None
=> Err(AddrParseError(())),
338 /// An error returned when parsing an IP address or a socket address.
339 #[stable(feature = "rust1", since = "1.0.0")]
340 #[derive(Debug, Clone, PartialEq)]
341 pub struct AddrParseError(());