1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00
VILLASnode/lib/signal_data.cpp
Steffen Vogel 7eec1bb753 update Steffens mail address
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
2022-12-16 23:44:07 +01:00

284 lines
4.9 KiB
C++

/** Signal data.
*
* @author Steffen Vogel <post@steffenvogel.de>
* @copyright 2014-2022, Institute for Automation of Complex Power Systems, EONERC
* @license Apache 2.0
*********************************************************************************/
#include <cstring>
#include <cinttypes>
#include <villas/signal_type.hpp>
#include <villas/signal_data.hpp>
using namespace villas::node;
void SignalData::set(enum SignalType type, double val)
{
switch (type) {
case SignalType::BOOLEAN:
this->b = val;
break;
case SignalType::FLOAT:
this->f = val;
break;
case SignalType::INTEGER:
this->i = val;
break;
case SignalType::COMPLEX:
this->z = val;
break;
case SignalType::INVALID:
*this = nan();
break;
}
}
SignalData SignalData::cast(enum SignalType from, enum SignalType to) const
{
SignalData n = *this;
switch (to) {
case SignalType::BOOLEAN:
switch(from) {
case SignalType::INTEGER:
n.b = this->i;
break;
case SignalType::FLOAT:
n.b = this->f;
break;
case SignalType::COMPLEX:
n.b = std::real(this->z);
break;
case SignalType::INVALID:
case SignalType::BOOLEAN:
break;
}
break;
case SignalType::INTEGER:
switch(from) {
case SignalType::BOOLEAN:
n.i = this->b;
break;
case SignalType::FLOAT:
n.i = this->f;
break;
case SignalType::COMPLEX:
n.i = std::real(this->z);
break;
case SignalType::INVALID:
case SignalType::INTEGER:
break;
}
break;
case SignalType::FLOAT:
switch(from) {
case SignalType::BOOLEAN:
n.f = this->b;
break;
case SignalType::INTEGER:
n.f = this->i;
break;
case SignalType::COMPLEX:
n.f = std::real(this->z);
break;
case SignalType::INVALID:
case SignalType::FLOAT:
break;
}
break;
case SignalType::COMPLEX:
switch(from) {
case SignalType::BOOLEAN:
n.z = this->b;
break;
case SignalType::INTEGER:
n.z = this->i;
break;
case SignalType::FLOAT:
n.z = this->f;
break;
case SignalType::INVALID:
case SignalType::COMPLEX:
break;
}
break;
default: { }
}
return n;
}
int SignalData::parseString(enum SignalType type, const char *ptr, char **end)
{
switch (type) {
case SignalType::FLOAT:
this->f = strtod(ptr, end);
break;
case SignalType::INTEGER:
this->i = strtol(ptr, end, 10);
break;
case SignalType::BOOLEAN:
this->b = strtol(ptr, end, 10);
break;
case SignalType::COMPLEX: {
float real, imag = 0;
real = strtod(ptr, end);
if (*end == ptr)
return -1;
ptr = *end;
if (*ptr == 'i' || *ptr == 'j') {
imag = real;
real = 0;
(*end)++;
}
else if (*ptr == '-' || *ptr == '+') {
imag = strtod(ptr, end);
if (*end == ptr)
return -1;
if (**end != 'i' && **end != 'j')
return -1;
(*end)++;
}
this->z = std::complex<float>(real, imag);
break;
}
case SignalType::INVALID:
return -1;
}
return 0;
}
int SignalData::parseJson(enum SignalType type, json_t *json)
{
int ret;
switch (type) {
case SignalType::FLOAT:
if (!json_is_number(json))
return -1;
this->f = json_number_value(json);
break;
case SignalType::INTEGER:
if (!json_is_integer(json))
return -1;
this->i = json_integer_value(json);
break;
case SignalType::BOOLEAN:
if (!json_is_boolean(json))
return -1;
this->b = json_boolean_value(json);
break;
case SignalType::COMPLEX: {
double real, imag;
json_error_t err;
ret = json_unpack_ex(json, &err, 0, "{ s: F, s: F }",
"real", &real,
"imag", &imag
);
if (ret)
return -1;
this->z = std::complex<float>(real, imag);
break;
}
case SignalType::INVALID:
return -2;
}
return 0;
}
json_t * SignalData::toJson(enum SignalType type) const
{
switch (type) {
case SignalType::INTEGER:
return json_integer(this->i);
case SignalType::FLOAT:
return json_real(this->f);
case SignalType::BOOLEAN:
return json_boolean(this->b);
case SignalType::COMPLEX:
return json_pack("{ s: f, s: f }",
"real", std::real(this->z),
"imag", std::imag(this->z)
);
case SignalType::INVALID:
return nullptr;
}
return nullptr;
}
int SignalData::printString(enum SignalType type, char *buf, size_t len, int precision) const
{
switch (type) {
case SignalType::FLOAT:
return snprintf(buf, len, "%.*f", precision, this->f);
case SignalType::INTEGER:
return snprintf(buf, len, "%" PRIi64, this->i);
case SignalType::BOOLEAN:
return snprintf(buf, len, "%u", this->b);
case SignalType::COMPLEX:
return snprintf(buf, len, "%.*f%+.*fi", precision, std::real(this->z), precision, std::imag(this->z));
default:
return snprintf(buf, len, "<?>");
}
}
std::string SignalData::toString(enum SignalType type, int precission) const
{
char buf[128];
printString(type, buf, sizeof(buf), precission);
return buf;
}