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 }