diff options
-rw-r--r-- | src/engine/Engine.cpp | 3 | ||||
-rw-r--r-- | src/engine/events/CreatePort.cpp | 14 | ||||
-rw-r--r-- | src/engine/events/CreatePort.hpp | 1 | ||||
-rw-r--r-- | src/serialisation/Parser.cpp | 35 |
4 files changed, 53 insertions, 0 deletions
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 3f65b587..fe9bdd8c 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -197,6 +197,7 @@ Engine::activate() // Add control input Shared::Resource::Properties in_properties(control_properties); in_properties.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); + in_properties.insert(make_pair(uris.lv2_index, 0)); execute_and_delete_event(context, new Events::CreatePort( *this, SharedPtr<Request>(), 0, @@ -205,6 +206,8 @@ Engine::activate() // Add control out Shared::Resource::Properties out_properties(control_properties); out_properties.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort)); + out_properties.insert(make_pair(uris.lv2_index, 1)); + execute_and_delete_event(context, new Events::CreatePort( *this, SharedPtr<Request>(), 0, "/control_out", uris.lv2ev_EventPort, true, out_properties)); diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp index 63ebede2..d2953c86 100644 --- a/src/engine/events/CreatePort.cpp +++ b/src/engine/events/CreatePort.cpp @@ -96,6 +96,14 @@ CreatePort::pre_process() ? _patch->external_ports()->size() : 0; + Shared::Resource::Properties::const_iterator index_i = _properties.find(uris.lv2_index); + if (index_i->second.type() != Atom::INT + || index_i->second.get_int32() != static_cast<int32_t>(old_num_ports)) { + QueuedEvent::pre_process(); + _error = BAD_INDEX; + return; + } + _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(), _data_type, buffer_size, _is_output); if (_patch->parent()) _patch_port->set_property(uris.rdf_instanceOf, _patch_port->meta_uri()); @@ -103,6 +111,8 @@ CreatePort::pre_process() _patch_port->properties().insert(_properties.begin(), _properties.end()); _patch_port->meta().properties().insert(_properties.begin(), _properties.end()); + assert(index_i->second == Atom((int)_patch_port->index())); + if (_patch_port) { if (_is_output) @@ -164,6 +174,10 @@ CreatePort::post_process() _request->respond_ok(); _engine.broadcaster()->send_object(_patch_port, true); break; + case BAD_INDEX: + msg = string("Could not create port ") + _path.str() + " (Illegal index given)"; + _request->respond_error(msg); + break; case UNKNOWN_TYPE: msg = string("Could not create port ") + _path.str() + " (Unknown type)"; _request->respond_error(msg); diff --git a/src/engine/events/CreatePort.hpp b/src/engine/events/CreatePort.hpp index b901dbf4..350a6b93 100644 --- a/src/engine/events/CreatePort.hpp +++ b/src/engine/events/CreatePort.hpp @@ -57,6 +57,7 @@ private: enum ErrorType { NO_ERROR, UNKNOWN_TYPE, + BAD_INDEX, CREATION_FAILED }; diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index d667723e..f59c7263 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -569,7 +569,42 @@ Parser::parse_patch( ports_i->second.insert(make_pair(key, AtomRDF::node_to_atom(model, (*i)["val"]))); } + std::vector<Objects::iterator> ports_by_index(patch_ports.size(), patch_ports.end()); for (Objects::iterator i = patch_ports.begin(); i != patch_ports.end(); ++i) { + Properties::const_iterator index_i = i->second.lower_bound(uris.lv2_index); + if (index_i == i->second.end()) { + error << "Patch port has no index" << endl; + return boost::optional<Raul::Path>(); + } + + if (index_i->second.type() != Atom::INT) { + error << "Patch port index has non-integer type" << endl; + return boost::optional<Raul::Path>(); + } + + const int32_t index = index_i->second.get_int32(); + + ++index_i; + if (index_i != i->second.end() && index_i->first == uris.lv2_index) { + error << "Patch port has multiple indices" << endl; + return boost::optional<Raul::Path>(); + } + + if (index < 0 || static_cast<size_t>(index) >= patch_ports.size()) { + error << "Patch port index out of range" << endl; + return boost::optional<Raul::Path>(); + } + + if (ports_by_index[index] != patch_ports.end()) { + error << "Patch has several ports with index " << index << endl; + return boost::optional<Raul::Path>(); + } + + ports_by_index[index] = i; + } + + for (uint32_t index = 0; index < patch_ports.size(); ++index) { + Objects::iterator i = ports_by_index[index]; Glib::Mutex::Lock lock(world->rdf_world->mutex()); const Path port_path(relative_uri(base_uri, i->first, true)); std::pair<Properties::iterator,Properties::iterator> types_range |