Mercurial > hg > piper-cpp
comparison utilities/json-cli.cpp @ 7:2dc705f24b9b
Build & test json-cli as well
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 13 May 2016 17:07:15 +0100 |
parents | |
children | c8451896c40e |
comparison
equal
deleted
inserted
replaced
6:d8358afe3f2c | 7:2dc705f24b9b |
---|---|
1 | |
2 #include "VampJson.h" | |
3 | |
4 #include <iostream> | |
5 #include <sstream> | |
6 #include <stdexcept> | |
7 | |
8 #include <map> | |
9 #include <set> | |
10 | |
11 using namespace std; | |
12 using namespace Vamp; | |
13 using namespace Vamp::HostExt; | |
14 using namespace json11; | |
15 | |
16 static map<uint32_t, Plugin *> loadedPlugins; | |
17 static set<uint32_t> initialisedPlugins; | |
18 | |
19 static uint32_t nextHandle = 1; // plugin handle type must fit in JSON number | |
20 | |
21 Vamp::HostExt::LoadResponse | |
22 loadPlugin(json11::Json j) { | |
23 | |
24 auto req = VampJson::toLoadRequest(j); | |
25 auto loader = Vamp::HostExt::PluginLoader::getInstance(); | |
26 auto response = loader->loadPlugin(req); | |
27 | |
28 if (!response.plugin) { | |
29 throw VampJson::Failure("plugin load failed"); | |
30 } | |
31 | |
32 return response; | |
33 } | |
34 | |
35 Vamp::Plugin::OutputList | |
36 configurePlugin(Vamp::Plugin *plugin, json11::Json j) { | |
37 | |
38 auto config = VampJson::toPluginConfiguration(j); | |
39 auto loader = Vamp::HostExt::PluginLoader::getInstance(); | |
40 auto outputs = loader->configurePlugin(plugin, config); | |
41 | |
42 if (outputs.empty()) { | |
43 throw VampJson::Failure("plugin initialisation failed (invalid channelCount, stepSize, blockSize?)"); | |
44 } | |
45 | |
46 return outputs; | |
47 } | |
48 | |
49 Json | |
50 handle_list(Json content) | |
51 { | |
52 if (content != Json()) { | |
53 throw VampJson::Failure("no content expected for list request"); | |
54 } | |
55 | |
56 auto loader = PluginLoader::getInstance(); | |
57 auto pluginData = loader->listPluginData(); | |
58 | |
59 Json::array j; | |
60 for (const auto &pd: pluginData) { | |
61 j.push_back(VampJson::fromPluginStaticData(pd)); | |
62 } | |
63 return Json(j); | |
64 } | |
65 | |
66 Json | |
67 handle_load(Json j) | |
68 { | |
69 auto loadResponse = loadPlugin(j); | |
70 | |
71 if (!loadResponse.plugin) { | |
72 throw VampJson::Failure("plugin load failed"); | |
73 } | |
74 | |
75 uint32_t h = nextHandle++; | |
76 loadedPlugins[h] = loadResponse.plugin; | |
77 | |
78 Json::object response; | |
79 response["pluginHandle"] = double(h); | |
80 response["staticData"] = | |
81 VampJson::fromPluginStaticData(loadResponse.staticData); | |
82 response["defaultConfiguration"] = | |
83 VampJson::fromPluginConfiguration(loadResponse.defaultConfiguration); | |
84 | |
85 cerr << "Loaded plugin: handle is " << h << endl; | |
86 | |
87 return Json(response); | |
88 } | |
89 | |
90 Json | |
91 handle_configure(Json j) | |
92 { | |
93 string err; | |
94 | |
95 if (!j.has_shape({ | |
96 { "pluginHandle", Json::NUMBER }, | |
97 { "configuration", Json::OBJECT }}, err)) { | |
98 throw VampJson::Failure("malformed configuration request: " + err); | |
99 } | |
100 | |
101 uint32_t handle = j["pluginHandle"].int_value(); | |
102 | |
103 if (loadedPlugins.find(handle) == loadedPlugins.end()) { | |
104 throw VampJson::Failure("unknown plugin handle"); | |
105 } | |
106 | |
107 if (initialisedPlugins.find(handle) != initialisedPlugins.end()) { | |
108 throw VampJson::Failure("plugin has already been initialised"); | |
109 } | |
110 | |
111 Plugin *plugin = loadedPlugins[handle]; | |
112 | |
113 Json config = j["configuration"]; | |
114 | |
115 configurePlugin(plugin, config); | |
116 | |
117 initialisedPlugins.insert(handle); | |
118 | |
119 cerr << "Configured and initialised plugin " << handle << endl; | |
120 | |
121 Json::object jout; | |
122 Json::array outs; | |
123 Vamp::Plugin::OutputList vouts = plugin->getOutputDescriptors(); | |
124 for (auto &o: vouts) { | |
125 outs.push_back(VampJson::fromOutputDescriptor(o)); | |
126 } | |
127 jout["outputList"] = outs; | |
128 return Json(jout); | |
129 } | |
130 | |
131 Json | |
132 handle(string input) | |
133 { | |
134 string err; | |
135 Json j = Json::parse(input, err); | |
136 | |
137 if (err != "") { | |
138 throw VampJson::Failure("invalid request: " + err); | |
139 } | |
140 | |
141 if (!j["verb"].is_string()) { | |
142 throw VampJson::Failure("verb expected in request"); | |
143 } | |
144 | |
145 if (!j["content"].is_null() && | |
146 !j["content"].is_object()) { | |
147 throw VampJson::Failure("object expected for content"); | |
148 } | |
149 | |
150 string verb = j["verb"].string_value(); | |
151 Json content = j["content"]; | |
152 Json result; | |
153 | |
154 if (verb == "list") { | |
155 result = handle_list(content); | |
156 } else if (verb == "load") { | |
157 result = handle_load(content); | |
158 } else if (verb == "configure") { | |
159 result = handle_configure(content); | |
160 } else { | |
161 throw VampJson::Failure("unknown verb: " + verb + | |
162 " (known verbs are: list load configure)"); | |
163 } | |
164 | |
165 return result; | |
166 } | |
167 | |
168 Json | |
169 success_response(Json payload) | |
170 { | |
171 Json::object obj; | |
172 obj["success"] = true; | |
173 obj["response"] = payload; | |
174 return Json(obj); | |
175 } | |
176 | |
177 Json | |
178 error_response(string text) | |
179 { | |
180 Json::object obj; | |
181 obj["success"] = false; | |
182 obj["errorText"] = text; | |
183 return Json(obj); | |
184 } | |
185 | |
186 template<typename T> | |
187 T &getline(T &in, string prompt, string &out) | |
188 { | |
189 cerr << prompt; | |
190 return getline(in, out); | |
191 } | |
192 | |
193 int main(int, char **) | |
194 { | |
195 string line; | |
196 | |
197 while (getline(cin, "> ", line)) { | |
198 try { | |
199 Json result = handle(line); | |
200 cout << success_response(result).dump() << endl; | |
201 } catch (const VampJson::Failure &e) { | |
202 cout << error_response(e.what()).dump() << endl; | |
203 } | |
204 } | |
205 | |
206 return 0; | |
207 } | |
208 | |
209 |