annotate utilities/json-cli.cpp @ 10:c8451896c40e

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