From 00b2b5f8d54b05932ea2cb1ef03248ae9faa8405 Mon Sep 17 00:00:00 2001 From: Owen Green Date: Wed, 13 May 2020 22:40:04 +0100 Subject: [PATCH] Better argument validation for RT inputs --- include/FluidSCWrapper.hpp | 82 ++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/include/FluidSCWrapper.hpp b/include/FluidSCWrapper.hpp index fa971ad..932ffb7 100644 --- a/include/FluidSCWrapper.hpp +++ b/include/FluidSCWrapper.hpp @@ -15,6 +15,7 @@ under the European Union’s Horizon 2020 research and innovation programme #include #include #include +#include #include #include #include @@ -87,6 +88,74 @@ class RealTime : public SCUnit using HostVector = FluidTensorView; using ParamSetType = typename Client::ParamSetType; + template + struct doExpectedCount; + + template + struct doExpectedCount + { + static void count(const T& d,FloatControlsIter& c,Result& status) + { + if(!status.ok()) return; + + if(c.remain()) + { + index statedSize = d.fixedSize; + + if(c.remain() < statedSize) + status = {Result::Status::kError,"Ran out of arguments at ", d.name}; + + //fastforward + for(index i=0; i < statedSize; ++i) c.next(); + + } + } + }; + + template + struct doExpectedCount + { + static void count(const T& d,FloatControlsIter& c,Result& status) + { + if(!status.ok()) return; + + if(c.remain()) + { + index statedSize = static_cast(c.next()); + + if(c.remain() < statedSize) + status = {Result::Status::kError,"Ran out of arguments at ", d.name}; + + //fastforward + for(index i=0; i < statedSize; ++i) c.next(); + + } + } + }; + + + template + struct ExpectedCount{ + void operator ()(const T& descriptor,FloatControlsIter& c, Result& status) + { + doExpectedCount::value>::count(descriptor,c,status); + } + }; + + Result expectedSize(FloatControlsIter& controls) + { + if(controls.size() < Client::getParameterDescriptors().count()) + { + return {Result::Status::kError,"Fewer parameters than exepected. Got ", controls.size(), "expect at least", Client::getParameterDescriptors().count()}; + } + + Result countScan; + Client::getParameterDescriptors().template iterate( + std::forward(mControlsIterator), + std::forward(countScan)); + return countScan; + } + public: static index ControlOffset(Unit* unit) { return unit->mSpecialIndex + 1; } @@ -121,20 +190,19 @@ public: !(client.audioChannelsOut() > 0 && client.controlChannelsOut() > 0) && "Client can't have both audio and control outputs"); - // If we don't the number of arguments we expect, the language side code is - // probably the wrong version set plugin to no-op, squawk, and bail; - if (static_cast(this)->mControlsIterator.size() != Client::getParameterDescriptors().count()) + Result r; + if(!(r = expectedSize(mControlsIterator)).ok()) { mCalcFunc = Wrapper::getInterfaceTable()->fClearUnitOutputs; std::cout << "ERROR: " << Wrapper::getName() - << " wrong number of arguments. Expected " - << Client::getParameterDescriptors().count() << ", got " - << static_cast(this)->mControlsIterator.size() - << ". Your .sc file and binary plugin might be different versions." + << " wrong number of arguments." + << r.message() << std::endl; return; } + + mControlsIterator.reset(mInBuf + mSpecialIndex + 1); client.sampleRate(fullSampleRate()); mInputConnections.reserve(asUnsigned(client.audioChannelsIn()));