Mercurial > hg > piper-vamp-js
changeset 100:708bd44f8019
Merge from noexcept branch
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 23 Sep 2016 14:23:10 +0100 |
parents | 22a09aca4b4a (current diff) dfd107ef991f (diff) |
children | d91781a91861 |
files | |
diffstat | 3 files changed, 174 insertions(+), 136 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.inc.em Mon Sep 19 16:35:05 2016 +0100 +++ b/Makefile.inc.em Fri Sep 23 14:23:10 2016 +0100 @@ -30,7 +30,6 @@ -s MODULARIZE=1 \ -s NO_FILESYSTEM=1 \ -s ERROR_ON_UNDEFINED_SYMBOLS=1 \ - -s DISABLE_EXCEPTION_CATCHING=0 \ -s EXPORT_NAME="'$(MODULE_SYMBOL)'" \ -s EXPORTED_FUNCTIONS="['_vampipeRequestJson','_vampipeProcessRaw','_vampipeFreeJson']" \ $(EMFLAGS)
--- a/VamPipePluginLibrary.cpp Mon Sep 19 16:35:05 2016 +0100 +++ b/VamPipePluginLibrary.cpp Fri Sep 23 14:23:10 2016 +0100 @@ -44,22 +44,20 @@ //!!! too many explicit namespaces here //!!! dup with vampipe-convert -static Json -convertRequestJson(string input) +Json +convertRequestJson(string input, string &err) { - string err; Json j = Json::parse(input, err); if (err != "") { - throw VampJson::Failure("invalid json: " + err); + err = "invalid json: " + err; + return {}; } if (!j.is_object()) { - throw VampJson::Failure("object expected at top level"); - } - if (!j["type"].is_string()) { - throw VampJson::Failure("string expected for type field"); - } - if (!j["content"].is_null() && !j["content"].is_object()) { - throw VampJson::Failure("object expected for content field"); + err = "object expected at top level"; + } else if (!j["type"].is_string()) { + err = "string expected for type field"; + } else if (!j["content"].is_null() && !j["content"].is_object()) { + err = "object expected for content field"; } return j; } @@ -84,18 +82,27 @@ } Vamp::HostExt::LoadResponse -VamPipePluginLibrary::loadPlugin(Vamp::HostExt::LoadRequest req) const +VamPipePluginLibrary::loadPlugin(Vamp::HostExt::LoadRequest req, string &err) const { string key = req.pluginKey; if (m_adapters.find(key) != m_adapters.end()) { - return m_adapters.at(key)->loadPlugin(req); + auto resp = m_adapters.at(key)->loadPlugin(req); + if (!resp.plugin) { + // This should not actually happen -- the load call here + // is just an object construction, not a dynamic load. But + // report it if it does... + err = "failed to construct plugin with key " + key; + } + return resp; } else { - throw runtime_error("no adapter for plugin key " + key); + err = "no adapter for plugin key " + key; + return {}; } } Vamp::HostExt::ConfigurationResponse -VamPipePluginLibrary::configurePlugin(Vamp::HostExt::ConfigurationRequest req) const +VamPipePluginLibrary::configurePlugin(Vamp::HostExt::ConfigurationRequest req, + string &err) const { for (Vamp::HostExt::PluginConfiguration::ParameterMap::const_iterator i = req.configuration.parameterValues.begin(); @@ -115,6 +122,8 @@ req.configuration.stepSize, req.configuration.blockSize)) { response.outputs = req.plugin->getOutputDescriptors(); + } else { + err = "configuration failed (wrong channel count, step size, block size?)"; } return response; @@ -126,42 +135,44 @@ int sec, int nsec) { - try { - if (!m_mapper.isConfigured(pluginHandle)) { - throw runtime_error("plugin has not been configured"); - } - - Vamp::Plugin *plugin = m_mapper.handleToPlugin(pluginHandle); - Vamp::RealTime timestamp(sec, nsec); - - Vamp::HostExt::ProcessResponse resp; - resp.plugin = plugin; - resp.features = plugin->process(inputBuffers, timestamp); - - m_useBase64 = true; - - return VampJson::fromVampResponse_Process - (resp, m_mapper, - VampJson::BufferSerialisation::Base64) - .dump(); - - } catch (const std::exception &e) { - return VampJson::fromException(e, RRType::Process) + Vamp::Plugin *plugin = m_mapper.handleToPlugin(pluginHandle); + if (!plugin) { + return VampJson::fromError("unknown plugin handle", RRType::Process) .dump(); } + + if (!m_mapper.isConfigured(pluginHandle)) { + return VampJson::fromError("plugin has not been configured", RRType::Process) + .dump(); + } + + Vamp::RealTime timestamp(sec, nsec); + + Vamp::HostExt::ProcessResponse resp; + resp.plugin = plugin; + resp.features = plugin->process(inputBuffers, timestamp); + + m_useBase64 = true; + + return VampJson::fromVampResponse_Process + (resp, m_mapper, + VampJson::BufferSerialisation::Base64) + .dump(); } string VamPipePluginLibrary::requestJsonImpl(string req) { - Json j = convertRequestJson(req); - - RRType type; - try { - type = VampJson::getRequestResponseType(j); - } catch (const std::exception &e) { - return VampJson::fromException(e, RRType::NotValid) - .dump(); + string err; + + Json j = convertRequestJson(req, err); + if (err != "") { + return VampJson::fromError(err, RRType::NotValid).dump(); + } + + RRType type = VampJson::getRequestResponseType(j, err); + if (err != "") { + return VampJson::fromError(err, RRType::NotValid).dump(); } VampJson::BufferSerialisation serialisation = @@ -171,108 +182,134 @@ Json rj; - try { - switch (type) { + switch (type) { - case RRType::List: - rj = VampJson::fromVampResponse_List(listPluginData()); - break; + case RRType::List: + rj = VampJson::fromVampResponse_List(listPluginData()); + break; - case RRType::Load: - { - auto req = VampJson::toVampRequest_Load(j); - auto resp = loadPlugin(req); - if (resp.plugin) { + case RRType::Load: + { + auto req = VampJson::toVampRequest_Load(j, err); + if (err != "") { + rj = VampJson::fromError(err, type); + } else { + auto resp = loadPlugin(req, err); + if (err != "") { + rj = VampJson::fromError(err, type); + } else { m_mapper.addPlugin(resp.plugin); + rj = VampJson::fromVampResponse_Load(resp, m_mapper); } - rj = VampJson::fromVampResponse_Load(resp, m_mapper); - break; } + break; + } - case RRType::Configure: - { - auto req = VampJson::toVampRequest_Configure(j, m_mapper); + case RRType::Configure: + { + auto req = VampJson::toVampRequest_Configure(j, m_mapper, err); + if (err != "") { + rj = VampJson::fromError(err, type); + } else { auto h = m_mapper.pluginToHandle(req.plugin); - if (m_mapper.isConfigured(h)) { - throw runtime_error("plugin has already been configured"); + if (h == m_mapper.INVALID_HANDLE) { + rj = VampJson::fromError("unknown or invalid plugin handle", type); + } else if (m_mapper.isConfigured(h)) { + rj = VampJson::fromError("plugin has already been configured", type); + } else { + auto resp = configurePlugin(req, err); + if (err != "") { + rj = VampJson::fromError(err, type); + } else { + m_mapper.markConfigured(h, + req.configuration.channelCount, + req.configuration.blockSize); + rj = VampJson::fromVampResponse_Configure(resp, m_mapper); + } } + } + break; + } - auto resp = configurePlugin(req); - if (!resp.outputs.empty()) { - m_mapper.markConfigured(h, - req.configuration.channelCount, - req.configuration.blockSize); + case RRType::Process: + { + VampJson::BufferSerialisation serialisation; + + auto req = VampJson::toVampRequest_Process(j, m_mapper, + serialisation, err); + if (err != "") { + rj = VampJson::fromError(err, type); + } else { + auto h = m_mapper.pluginToHandle(req.plugin); + int channels = int(req.inputBuffers.size()); + if (h == m_mapper.INVALID_HANDLE) { + rj = VampJson::fromError("unknown or invalid plugin handle", type); + } else if (!m_mapper.isConfigured(h)) { + rj = VampJson::fromError("plugin has not been configured", type); + } else if (channels != m_mapper.getChannelCount(h)) { + rj = VampJson::fromError("wrong number of channels supplied", type); + } else { + + if (serialisation == VampJson::BufferSerialisation::Base64) { + m_useBase64 = true; + } + + size_t blockSize = m_mapper.getBlockSize(h); + + const float **fbuffers = new const float *[channels]; + for (int i = 0; i < channels; ++i) { + if (req.inputBuffers[i].size() != blockSize) { + delete[] fbuffers; + fbuffers = 0; + rj = VampJson::fromError("wrong block size supplied", type); + break; + } + fbuffers[i] = req.inputBuffers[i].data(); + } + + if (fbuffers) { + Vamp::HostExt::ProcessResponse resp; + resp.plugin = req.plugin; + resp.features = req.plugin->process(fbuffers, req.timestamp); + delete[] fbuffers; + rj = VampJson::fromVampResponse_Process + (resp, m_mapper, serialisation); + } } + } + break; + } - rj = VampJson::fromVampResponse_Configure(resp, m_mapper); - break; + case RRType::Finish: + { + auto req = VampJson::toVampRequest_Finish(j, m_mapper, err); + if (err != "") { + rj = VampJson::fromError(err, type); + } else { + auto h = m_mapper.pluginToHandle(req.plugin); + if (h == m_mapper.INVALID_HANDLE) { + rj = VampJson::fromError("unknown or invalid plugin handle", type); + } else if (!m_mapper.isConfigured(h)) { + rj = VampJson::fromError("plugin has not been configured", type); + } else { + + Vamp::HostExt::ProcessResponse resp; + resp.plugin = req.plugin; + resp.features = req.plugin->getRemainingFeatures(); + + rj = VampJson::fromVampResponse_Finish + (resp, m_mapper, serialisation); + + m_mapper.removePlugin(h); + delete req.plugin; + } } + break; + } - case RRType::Process: - { - VampJson::BufferSerialisation serialisation; - - auto req = VampJson::toVampRequest_Process(j, m_mapper, - serialisation); - - auto h = m_mapper.pluginToHandle(req.plugin); - if (!m_mapper.isConfigured(h)) { - throw runtime_error("plugin has not been configured"); - } - - int channels = int(req.inputBuffers.size()); - if (channels != m_mapper.getChannelCount(h)) { - throw runtime_error("wrong number of channels supplied to process"); - } - - if (serialisation == VampJson::BufferSerialisation::Base64) { - m_useBase64 = true; - } - - const float **fbuffers = new const float *[channels]; - for (int i = 0; i < channels; ++i) { - if (int(req.inputBuffers[i].size()) != m_mapper.getBlockSize(h)) { - delete[] fbuffers; - throw runtime_error("wrong block size supplied to process"); - } - fbuffers[i] = req.inputBuffers[i].data(); - } - - Vamp::HostExt::ProcessResponse resp; - resp.plugin = req.plugin; - resp.features = req.plugin->process(fbuffers, req.timestamp); - delete[] fbuffers; - - rj = VampJson::fromVampResponse_Process(resp, m_mapper, serialisation); - break; - } - - case RRType::Finish: - { - auto req = VampJson::toVampRequest_Finish(j, m_mapper); - auto h = m_mapper.pluginToHandle(req.plugin); - if (!m_mapper.isConfigured(h)) { - throw runtime_error("plugin has not been configured"); - } - - Vamp::HostExt::ProcessResponse resp; - resp.plugin = req.plugin; - resp.features = req.plugin->getRemainingFeatures(); - - rj = VampJson::fromVampResponse_Finish(resp, m_mapper, serialisation); - - m_mapper.removePlugin(h); - delete req.plugin; - break; - } - - case RRType::NotValid: - rj = VampJson::fromError("invalid request", type); - break; - } - - } catch (const std::exception &e) { - rj = VampJson::fromException(e, type); + case RRType::NotValid: + rj = VampJson::fromError("invalid request", type); + break; } return rj.dump();
--- a/VamPipePluginLibrary.h Mon Sep 19 16:35:05 2016 +0100 +++ b/VamPipePluginLibrary.h Fri Sep 23 14:23:10 2016 +0100 @@ -71,9 +71,11 @@ std::string processRawImpl(int, const float *const *, int, int); Vamp::HostExt::ListResponse listPluginData() const; - Vamp::HostExt::LoadResponse loadPlugin(Vamp::HostExt::LoadRequest r) const; + Vamp::HostExt::LoadResponse loadPlugin(Vamp::HostExt::LoadRequest r, + std::string &err) const; Vamp::HostExt::ConfigurationResponse configurePlugin(Vamp::HostExt:: - ConfigurationRequest r) + ConfigurationRequest r, + std::string &err) const; // map from pluginKey -> adapter