summaryrefslogtreecommitdiff
path: root/graphics/asymptote/LspCpp/third_party/uri/src/detail/grammar.hpp
blob: 7630b4ca804ed10820527c70a3d039936c8284f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2016 Glyn Matthews.
// 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)

#ifndef NETWORK_DETAIL_URI_GRAMMAR_INC
#define NETWORK_DETAIL_URI_GRAMMAR_INC

#include <network/string_view.hpp>
#include <cstdlib>
#include <locale>
#include <cstring>
#include <string>

namespace network {
namespace detail {
inline bool isalnum(string_view::const_iterator &it,
                    string_view::const_iterator last) {
  if (it != last) {
    if (std::isalnum(*it, std::locale::classic())) {
      ++it;
      return true;
    }
  }
  return false;
}

inline bool isdigit(string_view::const_iterator &it,
                    string_view::const_iterator last) {
  if (it != last) {
    if (std::isdigit(*it, std::locale::classic())) {
      ++it;
      return true;
    }
  }
  return false;
}

inline bool is_in(string_view::const_iterator &it,
                  string_view::const_iterator last, const char *chars) {
  if (it != last) {
    auto length = std::strlen(chars);
    for (std::size_t i = 0; i < length; ++i) {
      if (*it == chars[i]) {
        ++it;
        return true;
      }
    }
  }
  return false;
}

inline bool is_sub_delim(string_view::const_iterator &it,
                         string_view::const_iterator last) {
  return is_in(it, last, "!$&'()*+,;=");
}

inline bool is_ucschar(string_view::const_iterator &it,
                       string_view::const_iterator last) {
  if (it == last) {
    return false;
  }

  return false;
}

inline bool is_private(string_view::const_iterator &it,
                       string_view::const_iterator last) {
  return false;
}

inline bool is_unreserved(string_view::const_iterator &it,
                          string_view::const_iterator last) {
  return isalnum(it, last) || is_in(it, last, "-._~");
}

inline bool is_pct_encoded(string_view::const_iterator &it,
                           string_view::const_iterator last) {
  if (it == last) {
    return false;
  }

  string_view::const_iterator it_copy = it;

  if (*it_copy == '%') {
    ++it_copy;
    if (it_copy == last) {
      return false;
    }
  }

  if (std::isxdigit(*it_copy, std::locale::classic())) {
    ++it_copy;
    if (it_copy == last) {
      return false;
    }
  }

  if (std::isxdigit(*it_copy, std::locale::classic())) {
    ++it_copy;
    it = it_copy;
    return true;
  }

  return false;
}

inline bool is_pchar(string_view::const_iterator &it,
                     string_view::const_iterator last) {
  return is_unreserved(it, last) || is_pct_encoded(it, last) ||
         is_sub_delim(it, last) || is_in(it, last, ":@") ||
         is_ucschar(it, last);
}

inline bool is_valid_port(string_view::const_iterator it) {
  const char *port_first = &(*it);
  char *port_last = 0;
  unsigned long value = std::strtoul(port_first, &port_last, 10);
  return (value < std::numeric_limits<unsigned short>::max());
}
}  // namespace detail
}  // namespace network

#endif  // NETWORK_DETAIL_URI_GRAMMAR_INC