1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  

10  

11  
#include <boost/url/detail/config.hpp>
11  
#include <boost/url/detail/config.hpp>
12  
#include "port_rule.hpp"
12  
#include "port_rule.hpp"
13  
#include <boost/url/grammar/parse.hpp>
13  
#include <boost/url/grammar/parse.hpp>
14  
#include <boost/url/grammar/token_rule.hpp>
14  
#include <boost/url/grammar/token_rule.hpp>
15  
#include <boost/url/grammar/unsigned_rule.hpp>
15  
#include <boost/url/grammar/unsigned_rule.hpp>
16  
#include <boost/core/detail/static_assert.hpp>
16  
#include <boost/core/detail/static_assert.hpp>
17  
#include <type_traits>
17  
#include <type_traits>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace urls {
20  
namespace urls {
21  
namespace detail {
21  
namespace detail {
22  

22  

23  
auto
23  
auto
24  
port_rule::
24  
port_rule::
25  
parse(
25  
parse(
26  
    char const*& it,
26  
    char const*& it,
27  
    char const* end) const noexcept ->
27  
    char const* end) const noexcept ->
28  
        system::result<value_type>
28  
        system::result<value_type>
29  
{
29  
{
30  
    value_type t;
30  
    value_type t;
31  
    auto const start = it;
31  
    auto const start = it;
32  
    while(
32  
    while(
33  
        it != end &&
33  
        it != end &&
34  
        *it == '0')
34  
        *it == '0')
35  
    {
35  
    {
36  
        ++it;
36  
        ++it;
37  
    }
37  
    }
38  

38  

39  
    if (it != end)
39  
    if (it != end)
40  
    {
40  
    {
41  
        grammar::unsigned_rule<std::uint16_t> r;
41  
        grammar::unsigned_rule<std::uint16_t> r;
42  
        auto it0 = it;
42  
        auto it0 = it;
43  
        auto rv = r.parse(it, end);
43  
        auto rv = r.parse(it, end);
44  
        if (rv)
44  
        if (rv)
45  
        {
45  
        {
46  
            // number < max uint16_t
46  
            // number < max uint16_t
47  
            t.str = core::string_view(start, it);
47  
            t.str = core::string_view(start, it);
48  
            t.has_number = true;
48  
            t.has_number = true;
49  
            t.number = *rv;
49  
            t.number = *rv;
50  
            return t;
50  
            return t;
51  
        }
51  
        }
52  
        it = it0;
52  
        it = it0;
53  
        if (grammar::digit_chars(*it))
53  
        if (grammar::digit_chars(*it))
54  
        {
54  
        {
55  
            // number > max uint16_t
55  
            // number > max uint16_t
56  
            while (
56  
            while (
57  
                it != end &&
57  
                it != end &&
58  
                grammar::digit_chars(*it))
58  
                grammar::digit_chars(*it))
59  
            {
59  
            {
60  
                ++it;
60  
                ++it;
61  
            }
61  
            }
62  
            t.str = core::string_view(start, it);
62  
            t.str = core::string_view(start, it);
63  
            t.has_number = true;
63  
            t.has_number = true;
64  
            t.number = 0;
64  
            t.number = 0;
65  
            return t;
65  
            return t;
66  
        }
66  
        }
67  
    }
67  
    }
68  
    // no digits
68  
    // no digits
69  
    t.str = core::string_view(start, it);
69  
    t.str = core::string_view(start, it);
70  
    t.has_number = it != end;
70  
    t.has_number = it != end;
71  
    t.number = 0;
71  
    t.number = 0;
72  
    return t;
72  
    return t;
73  
}
73  
}
74  

74  

75  
auto
75  
auto
76  
port_part_rule_t::
76  
port_part_rule_t::
77  
parse(
77  
parse(
78  
    char const*& it,
78  
    char const*& it,
79  
    char const* end) const noexcept ->
79  
    char const* end) const noexcept ->
80  
        system::result<value_type>
80  
        system::result<value_type>
81  
{
81  
{
82  
    value_type t;
82  
    value_type t;
83  
    if( it == end ||
83  
    if( it == end ||
84  
        *it != ':')
84  
        *it != ':')
85  
    {
85  
    {
86  
        t.has_port = false;
86  
        t.has_port = false;
87  
        return t;
87  
        return t;
88  
    }
88  
    }
89  
    ++it;
89  
    ++it;
90  
    auto rv = grammar::parse(
90  
    auto rv = grammar::parse(
91  
        it, end, port_rule{});
91  
        it, end, port_rule{});
92  
    if(! rv)
92  
    if(! rv)
93  
        return rv.error();
93  
        return rv.error();
94  
    t.has_port = true;
94  
    t.has_port = true;
95  
    t.port = rv->str;
95  
    t.port = rv->str;
96  
    t.has_number = rv->has_number;
96  
    t.has_number = rv->has_number;
97  
    t.port_number = rv->number;
97  
    t.port_number = rv->number;
98  
    return t;
98  
    return t;
99  
}
99  
}
100  

100  

101  
} // detail
101  
} // detail
102  
} // urls
102  
} // urls
103  
} // boost
103  
} // boost
104  

104