OSSIA
Open Scenario System for Interactive Application
http_query_parser.hpp
Go to the documentation of this file.
1 #pragma once
3 
4 #include <boost/fusion/adapted/std_pair.hpp>
5 #include <boost/spirit/home/x3.hpp>
6 
7 #include <sstream>
8 
18 namespace ossia::net
19 {
20 
21 // See
22 // https://stackoverflow.com/questions/45948473/boost-spirit-porting-string-pairs-from-qi-to-x3/
23 template <typename T = std::string>
24 auto& query()
25 {
26  namespace x3 = boost::spirit::x3;
27  static const auto s_pair = x3::rule<struct pair_, std::pair<std::string, T>>{"pair"}
28  = +~x3::char_("&=") >> -('=' >> *~x3::char_("&"));
29  static const auto s_query = x3::rule<struct query_, string_map<T>>{"query"}
30  = s_pair % '&';
31 
32  return s_query;
33 }
34 
35 inline string_map<std::string> parse_http_methods_encoded(std::string_view str)
36 {
37  // TODO a vector would be more efficient.
38  string_map<std::string> methods;
39  boost::spirit::x3::parse(str.cbegin(), str.cend(), query(), methods);
40  return methods;
41 }
42 
44 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
45 // Distributed under the Boost Software License, Version 1.0.
46 inline bool url_decode(std::string_view in, std::string& out)
47 {
48  out.clear();
49  out.reserve(in.size());
50  const std::size_t N = in.size();
51  for(std::size_t i = 0; i < N; ++i)
52  {
53  switch(in[i])
54  {
55  case '%': {
56  if(i + 3 <= N)
57  {
58  int value = 0;
59  std::istringstream is(std::string(in.substr(i + 1, 2)));
60  if(is >> std::hex >> value)
61  {
62  out += static_cast<char>(value);
63  i += 2;
64  }
65  else
66  {
67  return false;
68  }
69  }
70  else
71  {
72  return false;
73  }
74  break;
75  }
76  case '+':
77  out += ' ';
78  break;
79  case '\0':
80  return true;
81  default:
82  out += in[i];
83  break;
84  }
85  }
86  return true;
87 }
88 }
The value class.
Definition: value.hpp:173
bool url_decode(std::string_view in, std::string &out)
url_decode taken from boost
Definition: http_query_parser.hpp:46