OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
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>
7namespace 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