OSSIA
Open Scenario System for Interactive Application
json_query_parser.hpp
1 #pragma once
2 #include <ossia/network/oscquery/detail/json_parser.hpp>
3 #include <ossia/network/oscquery/detail/json_writer.hpp>
4 #include <ossia/network/oscquery/detail/outbound_visitor.hpp>
5 #include <ossia/network/oscquery/oscquery_client.hpp>
6 #include <ossia/network/oscquery/oscquery_server.hpp>
7 namespace ossia::oscquery
8 {
9 
16 {
17  template <typename Protocol>
18  auto operator()(
19  Protocol& proto, const typename Protocol::connection_handler& hdl,
20  const rapidjson::Document& doc)
21  {
22  auto& dev = proto.get_device();
23  auto& root = proto.get_device().get_root_node();
24 
25  // [ { "/addr/val" : 123 } ] or { "/addr/val": 123 }
26  if(doc.IsArray())
27  {
28  const auto& arr = doc.GetArray();
29  for(const auto& e : arr)
30  {
31  json_parser::parse_parameter_value(root, e, dev);
32  }
33  }
34  else
35  {
36  switch(json_parser::message_type(doc))
37  {
38  case message_type::StartOscStreaming:
39  handle_start_streaming(proto, hdl, doc);
40  break;
41  case message_type::Listen:
42  handle_listen(proto, hdl, doc);
43  break;
44  case message_type::Ignore:
45  handle_ignore(proto, hdl, doc);
46  break;
47  default:
48  json_parser::parse_parameter_value(root, doc, dev);
49  break;
50  }
51  }
52  return rapidjson::StringBuffer{};
53  }
54 
55  template <typename Protocol>
56  static json_writer::string_t handle_start_streaming(
57  Protocol& proto, const oscquery_server_protocol::connection_handler& hdl,
58  const rapidjson::Document& doc)
59  {
60  auto m = doc.FindMember("DATA");
61  if(m == doc.MemberEnd())
62  return {};
63  if(!m->value.IsObject())
64  return {};
65  auto obj = m->value.GetObject();
66  auto remote_server_port_it = obj.FindMember(detail::local_server_port().data());
67  auto remote_sender_port_it = obj.FindMember(detail::local_sender_port().data());
68 
69  if(remote_server_port_it == obj.MemberEnd())
70  return {};
71  if(!remote_server_port_it->value.IsInt())
72  return {};
73 
74  int remote_server = remote_server_port_it->value.GetInt();
75  int remote_sender = 0;
76 
77  if(remote_sender_port_it != obj.MemberEnd())
78  {
79  if(remote_sender_port_it->value.IsInt())
80  {
81  remote_sender = remote_sender_port_it->value.GetInt();
82  }
83  }
84 
85  return open_osc_sender(proto, hdl, remote_server, remote_sender);
86  }
87 
88  template <typename Protocol>
89  static json_writer::string_t open_osc_sender(
90  Protocol& proto, const typename Protocol::connection_handler& hdl, int port,
91  int remotePort)
92  {
93  // First we find for a corresponding client
94  auto clt = proto.find_client(hdl);
95 
96  if(!clt)
97  {
98  // It's an http-connecting client - we can't open a streaming connection
99  // to it
100  throw bad_request_error{"Client not found"};
101  }
102 
103  if(port != 0)
104  {
105  // Then we set-up the sender
106  clt->open_osc_sender(proto, port);
107  if(remotePort != 0)
108  {
109  clt->remote_sender_port = remotePort;
110  }
111  }
112 
113  return {};
114  }
115 
116  template <typename Protocol>
117  static json_writer::string_t handle_listen(
118  Protocol& proto, const typename Protocol::connection_handler& hdl,
119  const rapidjson::Document& doc)
120  {
121  // First we find for a corresponding client
122  auto clt = proto.find_client(hdl);
123 
124  if(!clt)
125  throw bad_request_error{"Client not found"};
126 
127  auto m = doc.FindMember("DATA");
128  if(m == doc.MemberEnd())
129  return {};
130 
131  auto nodes = ossia::net::find_nodes(
132  proto.get_device().get_root_node(), m->value.GetString());
133  for(auto n : nodes)
134  {
135  clt->start_listen(n->osc_address(), n->get_parameter());
136  }
137  return {};
138  }
139 
140  template <typename Protocol>
141  static json_writer::string_t handle_ignore(
142  Protocol& proto, const typename Protocol::connection_handler& hdl,
143  const rapidjson::Document& doc)
144  {
145  // First we find for a corresponding client
146  auto clt = proto.find_client(hdl);
147 
148  if(!clt)
149  throw bad_request_error{"Client not found"};
150 
151  auto m = doc.FindMember("DATA");
152  if(m == doc.MemberEnd())
153  return {};
154 
155  auto nodes = ossia::net::find_nodes(
156  proto.get_device().get_root_node(), m->value.GetString());
157  for(auto n : nodes)
158  {
159  clt->stop_listen(n->osc_address());
160  }
161  return {};
162  }
163 };
164 }
Used when a bad network request is done on a local server.
Definition: network/exceptions.hpp:72
OSCQuery JSON query-answering logic.
Definition: json_query_parser.hpp:16