Mercurial > hg > piper-cpp
comparison utilities/vampipe-convert.cpp @ 60:8a4bcb3dc3a6
Replace exceptions throughout the JSON-handling and adapter code with string-arg error handling. No longer need exception handling enabled in Emscripten (with its consequent runtime overhead - though we still need to check whether this error handling regime is actually faster).
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Tue, 20 Sep 2016 16:35:47 +0100 |
parents | 77833938f0f8 |
children | 6f160dee1192 |
comparison
equal
deleted
inserted
replaced
59:77833938f0f8 | 60:8a4bcb3dc3a6 |
---|---|
35 | 35 |
36 exit(2); | 36 exit(2); |
37 } | 37 } |
38 | 38 |
39 Json | 39 Json |
40 convertRequestJson(string input) | 40 convertRequestJson(string input, string &err) |
41 { | 41 { |
42 string err; | |
43 Json j = Json::parse(input, err); | 42 Json j = Json::parse(input, err); |
44 if (err != "") { | 43 if (err != "") { |
45 throw VampJson::Failure("invalid json: " + err); | 44 err = "invalid json: " + err; |
45 return {}; | |
46 } | 46 } |
47 if (!j.is_object()) { | 47 if (!j.is_object()) { |
48 throw VampJson::Failure("object expected at top level"); | 48 err = "object expected at top level"; |
49 } | 49 } else if (!j["type"].is_string()) { |
50 if (!j["type"].is_string()) { | 50 err = "string expected for type field"; |
51 throw VampJson::Failure("string expected for type field"); | 51 } else if (!j["content"].is_null() && !j["content"].is_object()) { |
52 } | 52 err = "object expected for content field"; |
53 if (!j["content"].is_null() && !j["content"].is_object()) { | |
54 throw VampJson::Failure("object expected for content field"); | |
55 } | 53 } |
56 return j; | 54 return j; |
57 } | 55 } |
58 | 56 |
59 Json | 57 Json |
60 convertResponseJson(string input) | 58 convertResponseJson(string input, string &err) |
61 { | 59 { |
62 string err; | |
63 Json j = Json::parse(input, err); | 60 Json j = Json::parse(input, err); |
64 if (err != "") { | 61 if (err != "") { |
65 throw VampJson::Failure("invalid json: " + err); | 62 err = "invalid json: " + err; |
63 return {}; | |
66 } | 64 } |
67 if (!j.is_object()) { | 65 if (!j.is_object()) { |
68 throw VampJson::Failure("object expected at top level"); | 66 err = "object expected at top level"; |
69 } | 67 } else if (!j["success"].is_bool()) { |
70 if (!j["success"].is_bool()) { | 68 err = "bool expected for success field"; |
71 throw VampJson::Failure("bool expected for success field"); | 69 } else if (!j["content"].is_object()) { |
72 } | 70 err = "object expected for content field"; |
73 if (!j["content"].is_object()) { | |
74 throw VampJson::Failure("object expected for content field"); | |
75 } | 71 } |
76 return j; | 72 return j; |
77 } | 73 } |
78 | 74 |
79 //!!! Lots of potential for refactoring the conversion classes based | 75 //!!! Lots of potential for refactoring the conversion classes based |
80 //!!! on the common matter in the following eight functions... | 76 //!!! on the common matter in the following eight functions... |
81 | 77 |
82 PreservingPluginHandleMapper mapper; | 78 PreservingPluginHandleMapper mapper; |
83 | 79 |
84 RequestOrResponse | 80 RequestOrResponse |
85 readRequestJson() | 81 readRequestJson(string &err) |
86 { | 82 { |
87 RequestOrResponse rr; | 83 RequestOrResponse rr; |
88 rr.direction = RequestOrResponse::Request; | 84 rr.direction = RequestOrResponse::Request; |
89 | 85 |
90 string input; | 86 string input; |
91 if (!getline(cin, input)) { | 87 if (!getline(cin, input)) { |
88 // the EOF case, not actually an error | |
92 rr.type = RRType::NotValid; | 89 rr.type = RRType::NotValid; |
93 return rr; | 90 return rr; |
94 } | 91 } |
95 | 92 |
96 Json j = convertRequestJson(input); | 93 Json j = convertRequestJson(input, err); |
97 | 94 if (err != "") return {}; |
98 rr.type = VampJson::getRequestResponseType(j); | 95 |
96 rr.type = VampJson::getRequestResponseType(j, err); | |
97 if (err != "") return {}; | |
98 | |
99 VampJson::BufferSerialisation serialisation = VampJson::BufferSerialisation::Text; | 99 VampJson::BufferSerialisation serialisation = VampJson::BufferSerialisation::Text; |
100 | 100 |
101 switch (rr.type) { | 101 switch (rr.type) { |
102 | 102 |
103 case RRType::List: | 103 case RRType::List: |
104 VampJson::toVampRequest_List(j); // type check only | 104 VampJson::toVampRequest_List(j, err); // type check only |
105 break; | 105 break; |
106 case RRType::Load: | 106 case RRType::Load: |
107 rr.loadRequest = VampJson::toVampRequest_Load(j); | 107 rr.loadRequest = VampJson::toVampRequest_Load(j, err); |
108 break; | 108 break; |
109 case RRType::Configure: | 109 case RRType::Configure: |
110 rr.configurationRequest = VampJson::toVampRequest_Configure(j, mapper); | 110 rr.configurationRequest = VampJson::toVampRequest_Configure(j, mapper, err); |
111 break; | 111 break; |
112 case RRType::Process: | 112 case RRType::Process: |
113 rr.processRequest = VampJson::toVampRequest_Process(j, mapper, serialisation); | 113 rr.processRequest = VampJson::toVampRequest_Process(j, mapper, serialisation, err); |
114 break; | 114 break; |
115 case RRType::Finish: | 115 case RRType::Finish: |
116 rr.finishRequest = VampJson::toVampRequest_Finish(j, mapper); | 116 rr.finishRequest = VampJson::toVampRequest_Finish(j, mapper, err); |
117 break; | 117 break; |
118 case RRType::NotValid: | 118 case RRType::NotValid: |
119 break; | 119 break; |
120 } | 120 } |
121 | 121 |
156 | 156 |
157 cout << j.dump() << endl; | 157 cout << j.dump() << endl; |
158 } | 158 } |
159 | 159 |
160 RequestOrResponse | 160 RequestOrResponse |
161 readResponseJson() | 161 readResponseJson(string &err) |
162 { | 162 { |
163 RequestOrResponse rr; | 163 RequestOrResponse rr; |
164 rr.direction = RequestOrResponse::Response; | 164 rr.direction = RequestOrResponse::Response; |
165 | 165 |
166 string input; | 166 string input; |
167 if (!getline(cin, input)) { | 167 if (!getline(cin, input)) { |
168 // the EOF case, not actually an error | |
168 rr.type = RRType::NotValid; | 169 rr.type = RRType::NotValid; |
169 return rr; | 170 return rr; |
170 } | 171 } |
171 | 172 |
172 Json j = convertResponseJson(input); | 173 Json j = convertResponseJson(input, err); |
173 | 174 if (err != "") return {}; |
174 rr.type = VampJson::getRequestResponseType(j); | 175 |
176 rr.type = VampJson::getRequestResponseType(j, err); | |
177 if (err != "") return {}; | |
178 | |
175 VampJson::BufferSerialisation serialisation = VampJson::BufferSerialisation::Text; | 179 VampJson::BufferSerialisation serialisation = VampJson::BufferSerialisation::Text; |
176 | 180 |
177 rr.success = j["success"].bool_value(); | 181 rr.success = j["success"].bool_value(); |
178 rr.errorText = j["errorText"].string_value(); | 182 rr.errorText = j["errorText"].string_value(); |
179 | 183 |
180 switch (rr.type) { | 184 switch (rr.type) { |
181 | 185 |
182 case RRType::List: | 186 case RRType::List: |
183 rr.listResponse = VampJson::toVampResponse_List(j); | 187 rr.listResponse = VampJson::toVampResponse_List(j, err); |
184 break; | 188 break; |
185 case RRType::Load: | 189 case RRType::Load: |
186 rr.loadResponse = VampJson::toVampResponse_Load(j, mapper); | 190 rr.loadResponse = VampJson::toVampResponse_Load(j, mapper, err); |
187 break; | 191 break; |
188 case RRType::Configure: | 192 case RRType::Configure: |
189 rr.configurationResponse = VampJson::toVampResponse_Configure(j, mapper); | 193 rr.configurationResponse = VampJson::toVampResponse_Configure(j, mapper, err); |
190 break; | 194 break; |
191 case RRType::Process: | 195 case RRType::Process: |
192 rr.processResponse = VampJson::toVampResponse_Process(j, mapper, serialisation); | 196 rr.processResponse = VampJson::toVampResponse_Process(j, mapper, serialisation, err); |
193 break; | 197 break; |
194 case RRType::Finish: | 198 case RRType::Finish: |
195 rr.finishResponse = VampJson::toVampResponse_Finish(j, mapper, serialisation); | 199 rr.finishResponse = VampJson::toVampResponse_Finish(j, mapper, serialisation, err); |
196 break; | 200 break; |
197 case RRType::NotValid: | 201 case RRType::NotValid: |
198 break; | 202 break; |
199 } | 203 } |
200 | 204 |
386 | 390 |
387 writeMessageToFd(1, message); | 391 writeMessageToFd(1, message); |
388 } | 392 } |
389 | 393 |
390 RequestOrResponse | 394 RequestOrResponse |
391 readInputJson(RequestOrResponse::Direction direction) | 395 readInputJson(RequestOrResponse::Direction direction, string &err) |
392 { | 396 { |
393 if (direction == RequestOrResponse::Request) { | 397 if (direction == RequestOrResponse::Request) { |
394 return readRequestJson(); | 398 return readRequestJson(err); |
395 } else { | 399 } else { |
396 return readResponseJson(); | 400 return readResponseJson(err); |
397 } | 401 } |
398 } | 402 } |
399 | 403 |
400 RequestOrResponse | 404 RequestOrResponse |
401 readInputCapnp(RequestOrResponse::Direction direction) | 405 readInputCapnp(RequestOrResponse::Direction direction) |
416 | 420 |
417 RequestOrResponse | 421 RequestOrResponse |
418 readInput(string format, RequestOrResponse::Direction direction) | 422 readInput(string format, RequestOrResponse::Direction direction) |
419 { | 423 { |
420 if (format == "json") { | 424 if (format == "json") { |
421 return readInputJson(direction); | 425 string err; |
426 auto result = readInputJson(direction, err); | |
427 if (err != "") throw runtime_error(err); | |
428 else return result; | |
422 } else if (format == "capnp") { | 429 } else if (format == "capnp") { |
423 return readInputCapnp(direction); | 430 return readInputCapnp(direction); |
424 } else { | 431 } else { |
425 throw runtime_error("unknown input format \"" + format + "\""); | 432 throw runtime_error("unknown input format \"" + format + "\""); |
426 } | 433 } |