comparison VamPipePluginLibrary.cpp @ 70:caf75dce15e5

Exception handling in adapter code
author Chris Cannam <c.cannam@qmul.ac.uk>
date Tue, 23 Aug 2016 11:17:01 +0100
parents 967b0619b090
children 4d6e60a7c80e
comparison
equal deleted inserted replaced
69:967b0619b090 70:caf75dce15e5
76 VamPipePluginLibrary::readRequest(string req) const 76 VamPipePluginLibrary::readRequest(string req) const
77 { 77 {
78 RequestOrResponse rr; 78 RequestOrResponse rr;
79 rr.direction = RequestOrResponse::Request; 79 rr.direction = RequestOrResponse::Request;
80 80
81 //!!! todo: handle exceptions (can't pass through C abi)
82 Json j = convertRequestJson(req); 81 Json j = convertRequestJson(req);
83 82
84 //!!! reduce, reduce 83 //!!! reduce, reduce
85 rr.type = VampJson::getRequestResponseType(j); 84 rr.type = VampJson::getRequestResponseType(j);
86 85
183 } 182 }
184 183
185 string 184 string
186 VamPipePluginLibrary::requestJsonImpl(string req) 185 VamPipePluginLibrary::requestJsonImpl(string req)
187 { 186 {
188 RequestOrResponse request = readRequest(req); 187 RequestOrResponse request;
188
189 try {
190 request = readRequest(req);
191 } catch (const std::exception &e) {
192 return VampJson::fromException(e, RRType::NotValid).dump();
193 }
189 194
190 RequestOrResponse response; 195 RequestOrResponse response;
191 response.direction = RequestOrResponse::Response; 196 response.direction = RequestOrResponse::Response;
192 response.type = request.type; 197 response.type = request.type;
193 198
194 switch (request.type) { 199 try {
195 200 switch (request.type) {
196 case RRType::List: 201
197 response.listResponse = listPluginData(); 202 case RRType::List:
198 response.success = true; 203 response.listResponse = listPluginData();
199 break;
200
201 case RRType::Load:
202 response.loadResponse = loadPlugin(request.loadRequest);
203 if (response.loadResponse.plugin) {
204 m_mapper.addPlugin(response.loadResponse.plugin);
205 response.success = true; 204 response.success = true;
206 } 205 break;
207 break; 206
207 case RRType::Load:
208 response.loadResponse = loadPlugin(request.loadRequest);
209 if (response.loadResponse.plugin) {
210 m_mapper.addPlugin(response.loadResponse.plugin);
211 response.success = true;
212 }
213 break;
208 214
209 case RRType::Configure: 215 case RRType::Configure:
210 { 216 {
211 auto &creq = request.configurationRequest; 217 auto &creq = request.configurationRequest;
212 auto h = m_mapper.pluginToHandle(creq.plugin); 218 auto h = m_mapper.pluginToHandle(creq.plugin);
213 if (m_mapper.isConfigured(h)) { 219 if (m_mapper.isConfigured(h)) {
214 //!!! again, can't return through C abi 220 //!!! again, can't return through C abi
215 throw runtime_error("plugin has already been configured"); 221 throw runtime_error("plugin has already been configured");
216 } 222 }
217 223
218 response.configurationResponse = configurePlugin(creq); 224 response.configurationResponse = configurePlugin(creq);
219 225
220 if (!response.configurationResponse.outputs.empty()) { 226 if (!response.configurationResponse.outputs.empty()) {
221 m_mapper.markConfigured 227 m_mapper.markConfigured
222 (h, creq.configuration.channelCount, creq.configuration.blockSize); 228 (h, creq.configuration.channelCount, creq.configuration.blockSize);
229 response.success = true;
230 }
231 break;
232 }
233
234 case RRType::Process:
235 {
236 auto &preq = request.processRequest;
237 auto h = m_mapper.pluginToHandle(preq.plugin);
238 if (!m_mapper.isConfigured(h)) {
239 throw runtime_error("plugin has not been configured");
240 }
241
242 int channels = int(preq.inputBuffers.size());
243 if (channels != m_mapper.getChannelCount(h)) {
244 throw runtime_error("wrong number of channels supplied to process");
245 }
246
247 const float **fbuffers = new const float *[channels];
248 for (int i = 0; i < channels; ++i) {
249 if (int(preq.inputBuffers[i].size()) != m_mapper.getBlockSize(h)) {
250 delete[] fbuffers;
251 throw runtime_error("wrong block size supplied to process");
252 }
253 fbuffers[i] = preq.inputBuffers[i].data();
254 }
255
256 response.processResponse.features =
257 preq.plugin->process(fbuffers, preq.timestamp);
223 response.success = true; 258 response.success = true;
224 } 259
225 break; 260 delete[] fbuffers;
226 } 261 break;
227 262 }
228 case RRType::Process: 263
229 { 264 case RRType::Finish:
230 auto &preq = request.processRequest; 265 {
231 auto h = m_mapper.pluginToHandle(preq.plugin); 266 auto h = m_mapper.pluginToHandle(request.finishPlugin);
232 if (!m_mapper.isConfigured(h)) { 267
233 throw runtime_error("plugin has not been configured"); 268 response.finishResponse.features =
234 } 269 request.finishPlugin->getRemainingFeatures();
235
236 int channels = int(preq.inputBuffers.size());
237 if (channels != m_mapper.getChannelCount(h)) {
238 throw runtime_error("wrong number of channels supplied to process");
239 }
240
241 const float **fbuffers = new const float *[channels];
242 for (int i = 0; i < channels; ++i) {
243 if (int(preq.inputBuffers[i].size()) != m_mapper.getBlockSize(h)) {
244 delete[] fbuffers;
245 throw runtime_error("wrong block size supplied to process");
246 }
247 fbuffers[i] = preq.inputBuffers[i].data();
248 }
249
250 response.processResponse.features =
251 preq.plugin->process(fbuffers, preq.timestamp);
252 response.success = true;
253
254 delete[] fbuffers;
255 break;
256 }
257
258 case RRType::Finish:
259 {
260 auto h = m_mapper.pluginToHandle(request.finishPlugin);
261
262 response.finishResponse.features =
263 request.finishPlugin->getRemainingFeatures();
264 270
265 m_mapper.removePlugin(h); 271 m_mapper.removePlugin(h);
266 delete request.finishPlugin; 272 delete request.finishPlugin;
267 response.success = true; 273 response.success = true;
268 break; 274 break;
269 } 275 }
270 276
271 case RRType::NotValid: 277 case RRType::NotValid:
272 break; 278 break;
273 } 279 }
274 280
275 return writeResponse(response); 281 return writeResponse(response);
276 } 282
277 283 } catch (const std::exception &e) {
278 } 284 return VampJson::fromException(e, request.type).dump();
279 285 }
286 }
287
288 }
289