23 #include <visiontransfer/parametervalue.h> 24 #include <visiontransfer/conversionhelpers.h> 29 using namespace internal;
31 std::string ParameterValue::sanitizeString(
const std::string& s,
unsigned int maxLength ) {
32 std::ostringstream ss;
33 const std::string whitelist(
"-+_,.:@/ ");
35 for (
const char c: s) {
36 if (std::isalnum(c) || whitelist.find(c) != std::string::npos) {
41 if (++len > maxLength)
break;
46 ParameterValue::ParameterValue()
47 : numVal(0.0), type(TYPE_UNDEFINED) {
50 ParameterValue& ParameterValue::setType(ParameterType t) {
55 ParameterValue& ParameterValue::setTensorShape(
const std::vector<unsigned int>& shape) {
56 unsigned int dims = (
unsigned int) shape.size();
58 throw std::runtime_error(
"Cannot create a zero-dimensional tensor");
61 for (
unsigned int i=0; i<dims; ++i) {
65 throw std::runtime_error(
"Cannot create a tensor with effective size 0");
67 tensorNumElements = elems;
69 tensorData.reserve(elems);
73 bool ParameterValue::isDefined()
const {
74 return (type!=TYPE_UNDEFINED);
76 bool ParameterValue::isUndefined()
const {
77 return (type==TYPE_UNDEFINED);
79 bool ParameterValue::isTensor()
const {
80 return type==TYPE_TENSOR;
82 bool ParameterValue::isScalar()
const {
85 bool ParameterValue::isCommand()
const {
86 return type==TYPE_COMMAND;
89 unsigned int ParameterValue::getTensorDimension()
const {
90 return (
unsigned int) tensorShape.size();
93 std::vector<unsigned int> ParameterValue::getTensorShape()
const {
101 ParameterValue& ParameterValue::setTensorData(
const std::vector<double>& data) {
102 if (data.size() != tensorNumElements)
throw std::runtime_error(
"ParameterValue::setTensorData(): wrong number of elements");
104 setType(ParameterType::TYPE_TENSOR);
107 std::ostringstream os;
108 for (
unsigned int i=0; i<getTensorNumElements(); ++i) {
112 stringVal = os.str();
116 unsigned int ParameterValue::getTensorNumElements()
const {
117 return tensorNumElements;
120 unsigned int ParameterValue::getTensorCurrentDataSize()
const {
121 return (
unsigned int) tensorData.size();
128 switch (this->type) {
132 case TYPE_SAFESTRING:
138 numVal = (t==0) ? 0 : 1;
139 stringVal = (t==0) ?
"false" :
"true";
143 throw std::runtime_error(
"Cannot assign a raw scalar to a tensor parameter");
145 throw std::runtime_error(
"Cannot assign a value to an undefined parameter");
150 double& ParameterValue::tensorElementAt(
unsigned int x) {
155 if (tensorShape.size()==0)
throw std::runtime_error(
"ParameterValue::tensorElementAt(): not a tensor");
156 if (x>=tensorNumElements)
throw std::runtime_error(
"ParameterValue::tensorElementAt(): access out of bounds");
157 return tensorData[x];
159 double& ParameterValue::tensorElementAt(
unsigned int y,
unsigned int x) {
160 if (tensorShape.size()!=2)
throw std::runtime_error(
"ParameterValue::tensorElementAt(): not a tensor of dimension 2");
161 if (y>=tensorShape[0] || x>=tensorShape[1])
throw std::runtime_error(
"ParameterValue::tensorElementAt(): access out of bounds");
162 return tensorData[y*tensorShape[1] + x];
164 double& ParameterValue::tensorElementAt(
unsigned int z,
unsigned int y,
unsigned int x) {
165 if (tensorShape.size()!=3)
throw std::runtime_error(
"ParameterValue::tensorElementAt(): not a tensor of dimension 3");
166 if (z>=tensorShape[0] || y>=tensorShape[1] || x>=tensorShape[2])
throw std::runtime_error(
"ParameterValue::tensorElementAt(): access out of bounds");
167 return tensorData[z*tensorShape[1]*tensorShape[2] + y*tensorShape[2] + x];
174 switch (this->type) {
181 case TYPE_SAFESTRING:
184 numVal = (t==
false) ? 0 : 1;
185 stringVal = (t==
false) ?
"false" :
"true";
189 throw std::runtime_error(
"Cannot assign a raw scalar to a tensor parameter");
191 throw std::runtime_error(
"Cannot assign a value to an undefined parameter");
198 switch (this->type) {
201 case TYPE_SAFESTRING:
211 numVal = (t==0) ? 0 : 1;
212 stringVal = (t==0) ?
"false" :
"true";
216 throw std::runtime_error(
"Cannot assign a raw scalar to a tensor parameter");
218 throw std::runtime_error(
"Cannot assign a value to an undefined parameter");
226 switch (this->type) {
228 case TYPE_SAFESTRING:
230 stringVal = sanitizeString(t);
231 numVal = atof(stringVal.c_str());
246 if (!std::strncmp(
"true", t, 4) || !std::strncmp(
"True", t, 4)) {
249 numVal = atol(t)==0 ? 0 : 1;
251 stringVal = (numVal==0.0) ?
"false" :
"true";
255 throw std::runtime_error(
"Cannot assign a raw scalar to a tensor parameter");
257 throw std::runtime_error(
"Cannot assign a value to an undefined parameter");
264 return setValue<const char*>(t.c_str());
268 return setValue<const char*>(t.c_str());
273 int ParameterValue::getValue()
const {
274 switch (this->type) {
275 case TYPE_INT:
case TYPE_DOUBLE:
case TYPE_BOOL:
278 case TYPE_SAFESTRING:
283 throw std::runtime_error(
"Attempted to get tensor parameter as scalar- undefined value");
290 double ParameterValue::getValue()
const {
291 switch (this->type) {
292 case TYPE_INT:
case TYPE_DOUBLE:
case TYPE_BOOL:
293 return (
double) numVal;
295 case TYPE_SAFESTRING:
297 return (
double) numVal;
300 throw std::runtime_error(
"Attempted to get tensor parameter as scalar- undefined value");
307 bool ParameterValue::getValue()
const {
308 switch (this->type) {
309 case TYPE_INT:
case TYPE_DOUBLE:
case TYPE_BOOL:
310 return (
bool) numVal;
312 case TYPE_SAFESTRING:
314 return (
bool) numVal;
317 throw std::runtime_error(
"Attempted to get tensor parameter as scalar- undefined value");
324 std::string ParameterValue::getValue()
const {
325 switch (this->type) {
326 case TYPE_INT:
case TYPE_DOUBLE:
case TYPE_BOOL:
330 case TYPE_STRING:
case TYPE_SAFESTRING:
case TYPE_COMMAND:
340 const char* ParameterValue::getValue()
const {
341 switch (this->type) {
342 case TYPE_INT:
case TYPE_DOUBLE:
case TYPE_BOOL:
346 case TYPE_STRING:
case TYPE_SAFESTRING:
case TYPE_COMMAND:
347 return stringVal.c_str();
std::vector< double > getTensorData() const
Return a copy of the internal tensor data.
static std::string anyToString(T val)
Converts any type to a string.