OSSIA
Open Scenario System for Interactive Application
get_query_parser.hpp
1 #pragma once
2 #include <ossia/detail/small_vector.hpp>
4 #include <ossia/network/exceptions.hpp>
5 #include <ossia/network/oscquery/detail/html_writer.hpp>
6 #include <ossia/network/oscquery/detail/json_writer.hpp>
7 #include <ossia/network/oscquery/detail/outbound_visitor.hpp>
8 #include <ossia/network/oscquery/oscquery_client.hpp>
9 #include <ossia/network/oscquery/oscquery_server.hpp>
10 
11 namespace ossia
12 {
13 namespace net
14 {
15 struct parameter_data;
16 }
17 namespace oscquery
18 {
19 
26 {
27 public:
28  template <typename OscqueryProtocol>
29  static json_writer::string_t handle_listen(
30  OscqueryProtocol& proto, const oscquery_server_protocol::connection_handler& hdl,
31  ossia::net::node_base& node, std::string_view path, const std::string& listen_text)
32  {
33  // First we find for a corresponding client
34  auto clt = proto.find_client(hdl);
35 
36  if(clt)
37  {
38  // Then we enable / disable listening
39  if(listen_text == detail::text_true())
40  {
41  clt->start_listen(std::string(path), node.get_parameter());
42  return {};
43  }
44  else if(listen_text == detail::text_false())
45  {
46  clt->stop_listen(std::string(path));
47  return {};
48  }
49  else
50  {
51  throw bad_request_error{"Wrong arguments to listen query: " + listen_text};
52  return {};
53  }
54  }
55  else
56  {
57  throw bad_request_error{"Client not found"};
58  return {};
59  }
60  }
61 
62  template <typename OscqueryProtocol>
63  auto operator()(
64  OscqueryProtocol& proto, const oscquery_server_protocol::connection_handler& hdl)
65  {
66  return [&proto, &hdl](
67  std::string_view path,
68  string_map<std::string>&& parameters) -> ossia::net::server_reply {
69  // Here we handle the url elements relative to oscquery
70  if(parameters.size() == 0)
71  {
72  auto& root = proto.get_device().get_root_node();
73  if(path == "/")
74  {
76  }
77  else
78  {
79  auto node = ossia::net::find_node(root, path);
80  if(node)
82  else
83  throw node_not_found_error{std::string(path)};
84  }
85  }
86  else
87  {
88  auto host_it = parameters.find("HOST_INFO");
89  if(host_it == parameters.end())
90  {
91  auto node = ossia::net::find_node(proto.get_device().get_root_node(), path);
92  // First check if we have the path
93  if(!node)
94  throw node_not_found_error{std::string(path)};
95 
96  // LISTEN
97  auto listen_it = parameters.find(detail::listen());
98  if(listen_it != parameters.end())
99  {
100  return handle_listen(proto, hdl, *node, path, listen_it->second);
101  }
102 
103  // HTML
104  auto html_it = parameters.find("HTML");
105  if(html_it != parameters.end())
106  {
107  return static_html_builder{}.build_tree(*node);
108  }
109 
110  // ADD_NODE
111  auto add_instance_it = parameters.find(detail::add_node());
112  if(add_instance_it != parameters.end())
113  {
114  proto.add_node(path, std::move(parameters));
115  return {};
116  }
117 
118  // REMOVE_NODE
119  auto rm_instance_it = parameters.find(detail::remove_node());
120  if(rm_instance_it != parameters.end())
121  {
122  // Value is the child to remove
123  proto.remove_node(path, rm_instance_it->second);
124  return {};
125  }
126 
127  // RENAME_NODE
128  auto rn_instance_it = parameters.find(detail::rename_node());
129  if(rn_instance_it != parameters.end())
130  {
131  // Value is the child to remove
132  proto.rename_node(path, rn_instance_it->second);
133  return {};
134  }
135 
136  // All the value-less parameters
137  ossia::small_vector<std::string, 5> attributes;
138  for(const auto& elt : parameters)
139  {
140  if(elt.second.empty())
141  {
142  attributes.push_back(elt.first);
143  }
144  }
145 
146  if(!attributes.empty())
147  {
148  return oscquery::json_writer::query_attributes(*node, attributes);
149  }
150  }
151  else
152  {
153  websocketpp::connection<websocketpp::config::asio>& sockets
154  = *proto.m_websocketServer->impl().get_con_from_hdl(hdl);
155  auto& socket = sockets.get_socket();
156 
157  std::string local_client_ip = socket.local_endpoint().address().to_string();
158  return oscquery::json_writer::query_host_info(
159  proto.get_device().get_name(), proto.get_osc_port(), local_client_ip,
160  proto.get_ws_port());
161  }
162  }
163  return {};
164  };
165  }
166 };
167 }
168 }
The node_base class.
Definition: network/base/node.hpp:48
OSCQuery get query-answering logic.
Definition: get_query_parser.hpp:26
static string_t query_attributes(const ossia::net::node_base &node, const StringVec_T &methods)
Reply to a query of attributes : /foo/bar?VALUE&RANGE.
Definition: json_writer.hpp:38
static string_t query_namespace(const ossia::net::node_base &node)
Reply to the namespace query : /foo/bar.
Definition: json_writer_detail.cpp:564
Definition: git_info.h:7
Used when a bad network request is done on a local server.
Definition: network/exceptions.hpp:72
Used when a requested node could not be found.
Definition: network/exceptions.hpp:60