summaryrefslogtreecommitdiff
path: root/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp
blob: 6eec782c8200618f844d6c8036c4047007c60784 (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
// Copyright 2016-2017 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)

#include "uri_advance_parts.hpp"
#include <iterator>
#include <utility>
#include <limits>

namespace network {
namespace detail {
namespace {
template <class Iterator>
uri_part copy_part(Iterator first, Iterator last,
                   string_view::const_iterator &it) {
  auto part_first = it;
  std::advance(it, std::distance(first, last));
  return detail::uri_part(part_first, it);
}
}  // namespace

uri_part copy_part(const std::string &uri, string_view::const_iterator &it) {
  return copy_part(std::begin(uri), std::end(uri), it);
}

void advance_parts(string_view uri_view, uri_parts &parts,
                   const uri_parts &existing_parts) {
  auto first = std::begin(uri_view);

  auto it = first;
  if (auto scheme = existing_parts.scheme) {
    parts.scheme = copy_part(std::begin(*scheme), std::end(*scheme), it);

    // ignore : for all URIs
    if (*it == ':') {
      ++it;
    }

    // ignore // for hierarchical URIs
    if (existing_parts.hier_part.host) {
      std::advance(it, 2);
    }
  }

  if (auto user_info = existing_parts.hier_part.user_info) {
    parts.hier_part.user_info =
      copy_part(std::begin(*user_info), std::end(*user_info), it);
    ++it;  // ignore @
  }

  if (auto host = existing_parts.hier_part.host) {
    parts.hier_part.host = copy_part(std::begin(*host), std::end(*host), it);
  }

  if (auto port = existing_parts.hier_part.port) {
    ++it;  // ignore :
    parts.hier_part.port = copy_part(std::begin(*port), std::end(*port), it);
  }

  if (auto path = existing_parts.hier_part.path) {
    parts.hier_part.path = copy_part(std::begin(*path), std::end(*path), it);
  }

  if (auto query = existing_parts.query) {
    ++it;  // ignore ?
    parts.query = copy_part(std::begin(*query), std::end(*query), it);
  }

  if (auto fragment = existing_parts.fragment) {
    ++it;  // ignore #
    parts.fragment = copy_part(std::begin(*fragment), std::end(*fragment), it);
  }
}
}  // namespace detail
}  // namespace network