comparison utilities/vampipe-convert.cpp @ 23:d678cd00e593

Begin vampipe-convert
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 20 May 2016 18:05:02 +0100
parents
children 533ca5ca3404
comparison
equal deleted inserted replaced
22:b0fc4eb51547 23:d678cd00e593
1
2 #include "VampJson.h"
3 #include "VampnProto.h"
4
5 #include <iostream>
6 #include <sstream>
7 #include <stdexcept>
8
9 using namespace std;
10 using namespace json11;
11 using namespace vampipe;
12
13 // Accepting JSON objects with two fields, "type" and "payload". The
14 // "type" string corresponds to the JSON schema filename
15 // (e.g. "outputdescriptor") and the "payload" is the JSON object
16 // encoded with that schema.
17
18 Json
19 json_input(string input)
20 {
21 string err;
22 Json j = Json::parse(input, err);
23 if (err != "") {
24 throw VampJson::Failure("invalid json: " + err);
25 }
26 if (!j.is_object()) {
27 throw VampJson::Failure("object expected at top level");
28 }
29 if (!j["type"].is_string()) {
30 throw VampJson::Failure("string expected for type field");
31 }
32 if (!j["payload"].is_object()) {
33 throw VampJson::Failure("object expected for payload field");
34 }
35 return j;
36 }
37
38 class PreservingPluginHandleMapper : public PluginHandleMapper
39 {
40 public:
41 PreservingPluginHandleMapper() : m_handle(0), m_plugin(0) { }
42
43 virtual int32_t pluginToHandle(Vamp::Plugin *p) {
44 if (p == m_plugin) return m_handle;
45 else throw NotFound();
46 }
47
48 virtual Vamp::Plugin *handleToPlugin(int32_t h) {
49 m_handle = h;
50 m_plugin = reinterpret_cast<Vamp::Plugin *>(h);
51 return m_plugin;
52 }
53
54 private:
55 int32_t m_handle;
56 Vamp::Plugin *m_plugin;
57 };
58
59 void
60 handle_input(::capnp::MallocMessageBuilder &message, string input)
61 {
62 string err;
63
64 Json j = json_input(input);
65 string type = j["type"].string_value();
66 Json payload = j["payload"];
67
68 if (type == "configurationrequest") {
69 auto req = message.initRoot<ConfigurationRequest>();
70 PreservingPluginHandleMapper mapper;
71 VampnProto::buildConfigurationRequest
72 (req, VampJson::toConfigurationRequest(payload, mapper), mapper);
73
74 } else if (type == "configurationresponse") {
75 auto resp = message.initRoot<ConfigurationResponse>();
76 VampnProto::buildConfigurationResponse
77 (resp, VampJson::toConfigurationResponse(payload));
78
79 } else if (type == "feature") {
80 auto f = message.initRoot<Feature>();
81 VampnProto::buildFeature
82 (f, VampJson::toFeature(payload));
83
84 } else if (type == "featureset") {
85 auto fs = message.initRoot<FeatureSet>();
86 VampnProto::buildFeatureSet
87 (fs, VampJson::toFeatureSet(payload));
88
89 } else if (type == "loadrequest") {
90 auto req = message.initRoot<LoadRequest>();
91 VampnProto::buildLoadRequest
92 (req, VampJson::toLoadRequest(payload));
93
94 } else if (type == "loadresponse") {
95 auto resp = message.initRoot<LoadResponse>();
96 PreservingPluginHandleMapper mapper;
97 VampnProto::buildLoadResponse
98 (resp, VampJson::toLoadResponse(payload, mapper), mapper);
99
100 } else if (type == "outputdescriptor") {
101 auto od = message.initRoot<OutputDescriptor>();
102 VampnProto::buildOutputDescriptor
103 (od, VampJson::toOutputDescriptor(payload));
104
105 } else if (type == "parameterdescriptor") {
106 auto pd = message.initRoot<ParameterDescriptor>();
107 VampnProto::buildParameterDescriptor
108 (pd, VampJson::toParameterDescriptor(payload));
109
110 } else if (type == "pluginconfiguration") {
111 auto pc = message.initRoot<PluginConfiguration>();
112 auto config = VampJson::toPluginConfiguration(payload);
113 VampnProto::buildPluginConfiguration(pc, config);
114
115 } else if (type == "pluginstaticdata") {
116 auto pc = message.initRoot<PluginStaticData>();
117 auto sd = VampJson::toPluginStaticData(payload);
118 VampnProto::buildPluginStaticData(pc, sd);
119
120 } else if (type == "processrequest") {
121 auto p = message.initRoot<ProcessRequest>();
122 PreservingPluginHandleMapper mapper;
123 VampnProto::buildProcessRequest
124 (p, VampJson::toProcessRequest(payload, mapper), mapper);
125
126 } else if (type == "realtime") {
127 auto b = message.initRoot<RealTime>();
128 VampnProto::buildRealTime
129 (b, VampJson::toRealTime(payload));
130
131 } else {
132 throw VampJson::Failure("unknown or unsupported JSON schema type " +
133 type);
134 }
135 }
136
137 void usage()
138 {
139 string myname = "vampipe-convert";
140 cerr << "\n" << myname <<
141 ": Convert Vamp request and response messages between formats\n\n"
142 " Usage: " << myname << " -i <informat> -o <outformat>\n\n"
143 "Where <informat> and <outformat> may be \"json\" or \"capnp\".\n"
144 "Messages are read from stdin and written to stdout.\n" << endl;
145 exit(2);
146 }
147
148 class RequestOrResponse
149 {
150 public:
151 enum Type {
152 List, Load, Configure, Process, Finish, Eof
153 };
154 RequestOrResponse() : // nothing by default
155 type(Eof),
156 success(false),
157 finishPlugin(0) { }
158
159 Type type;
160 bool success;
161 string errorText;
162
163 PreservingPluginHandleMapper mapper;
164
165 Vamp::HostExt::LoadRequest loadRequest;
166 Vamp::HostExt::LoadResponse loadResponse;
167 Vamp::HostExt::ConfigurationRequest configurationRequest;
168 Vamp::HostExt::ConfigurationResponse configurationResponse;
169 Vamp::HostExt::ProcessRequest processRequest;
170 Vamp::HostExt::ProcessResponse processResponse;
171 Vamp::Plugin *finishPlugin;
172 Vamp::HostExt::ProcessResponse finishResponse;
173
174 };
175
176 RequestOrResponse
177 readInputJson()
178 {
179 RequestOrResponse rr;
180 string input;
181 if (!getline(cin, input)) {
182 rr.type = RequestOrResponse::Eof;
183 return rr;
184 }
185
186 Json j = json_input(input);
187 string type = j["type"].string_value();
188
189 if (type == "list") {
190 rr.type = RequestOrResponse::List;
191
192 } else if (type == "load") {
193 //!!! ah, we need a way to know whether we're dealing with a request or response here
194 rr.type = RequestOrResponse::Load;
195 rr.loadRequest = VampJson::toLoadRequest(j["content"]);
196
197 } else if (type == "configure") {
198 rr.type = RequestOrResponse::Configure;
199 rr.configurationRequest =
200 VampJson::toConfigurationRequest(j["content"], rr.mapper);
201
202 } else if (type == "process") {
203 rr.type = RequestOrResponse::Process;
204 rr.processRequest =
205 VampJson::toProcessRequest(j["content"], rr.mapper);
206
207 } else if (type == "finish") {
208 rr.type = RequestOrResponse::Finish;
209 //!!! VampJsonify
210 rr.finishPlugin = rr.mapper.handleToPlugin(j["content"]["pluginHandle"].int_value());
211
212 } else {
213 throw runtime_error("unknown or unexpected request/response type \"" +
214 type + "\"");
215 }
216
217 return rr;
218 }
219
220 RequestOrResponse
221 readInput(string format)
222 {
223 if (format == "json") {
224 return readInputJson();
225 } else {
226 throw runtime_error("unknown or unimplemented format \"" + format + "\"");
227 }
228 }
229
230 void
231 writeOutput(string format, const RequestOrResponse &rr)
232 {
233 throw runtime_error("writeOutput not implemented yet");
234
235 }
236
237 int main(int argc, char **argv)
238 {
239 if (argc != 5) {
240 usage();
241 }
242
243 string informat, outformat;
244
245 for (int i = 1; i + 1 < argc; ++i) {
246
247 string arg = argv[i];
248
249 if (arg == "-i") {
250 if (informat != "") usage();
251 else informat = argv[++i];
252
253 } else if (arg == "-o") {
254 if (outformat != "") usage();
255 else outformat = argv[++i];
256
257 } else {
258 usage();
259 }
260 }
261
262 if (informat == "" || outformat == "") {
263 usage();
264 }
265
266 while (true) {
267
268 try {
269
270 RequestOrResponse rr = readInput(informat);
271 if (rr.type == RequestOrResponse::Eof) break;
272 writeOutput(outformat, rr);
273
274 } catch (std::exception &e) {
275 cerr << "Error: " << e.what() << endl;
276 exit(1);
277 }
278 }
279
280 exit(0);
281 }
282
283