Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

Added support for negative NaN in Tango properties. #371

Merged
merged 2 commits into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 72 additions & 42 deletions cpp_test_suite/new_tests/cxx_nan_inf_in_prop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ class NanInfInPropSuite: public CxxTest::TestSuite
vector<T> array_val;
array_val.push_back(T(1.2));
if(std::numeric_limits<T>::has_quiet_NaN)
array_val.push_back(std::numeric_limits<T>::quiet_NaN());
{
array_val.push_back(std::numeric_limits<T>::quiet_NaN());
array_val.push_back(-std::numeric_limits<T>::quiet_NaN());
}
array_val.push_back(T(3.4));
if(std::numeric_limits<T>::has_infinity)
{
Expand All @@ -141,7 +144,7 @@ class NanInfInPropSuite: public CxxTest::TestSuite
// Extract as T array:
size_t expected_size = 3;
if(std::numeric_limits<T>::has_quiet_NaN)
expected_size += 1;
expected_size += 2;
if(std::numeric_limits<T>::has_infinity)
expected_size += 2;
vector<T> read_array_val;
Expand All @@ -153,6 +156,9 @@ class NanInfInPropSuite: public CxxTest::TestSuite
if(std::numeric_limits<T>::has_quiet_NaN)
{
TS_ASSERT(std::isnan(read_array_val[index]));
index++;
// -NaN is extracted as NaN
TS_ASSERT(std::isnan(read_array_val[index]));
index++;
}
TS_ASSERT_EQUALS(read_array_val[index],T(3.4));
Expand All @@ -175,6 +181,47 @@ class NanInfInPropSuite: public CxxTest::TestSuite
TS_ASSERT(!(db_data_r[0] >> long_array_val));
}
}

void NaN_in_scalar_property(const string & prop_value)
{
//
// if your code modifies the default (device) configuration, append the following line straight after
CxxTest::TangoPrinter::restore_set("NanInfScalarProp_restore_point");

// Write NaNInfArrayProperty device property
Tango::DbData db_data_r;

// Write NaNInfScalarProperty device property
set_property("NaNInfScalarProperty", prop_value.c_str());

// Read NaNInfScalarProperty device property
string prop_name = "NaNInfScalarProperty";
TS_ASSERT_THROWS_NOTHING(device1->get_property(prop_name,db_data_r));
// Extract as a string:
string string_scalar_val;
TS_ASSERT(db_data_r[0] >> string_scalar_val);
TS_ASSERT_EQUALS(string_scalar_val,prop_value);

// Extract as float:
Tango::DevFloat float_val;
TS_ASSERT(db_data_r[0] >> float_val);
TS_ASSERT(std::isnan(float_val));

// Extract as double:
Tango::DevDouble double_val;
TS_ASSERT(db_data_r[0] >> double_val);
TS_ASSERT(std::isnan(double_val));

// Extract as short
Tango::DevShort short_val;
TS_ASSERT(!(db_data_r[0] >> short_val));

// Restore the default configuration
TS_ASSERT_THROWS_NOTHING(device1->delete_property(prop_name));
// if the test suite fails here, thanks to the restore point, the test suite TearDown method will restore the defaults
// after you set back the default configuration, append the following line
CxxTest::TangoPrinter::restore_unset("NanInfScalarProp_restore_point");
}
//
// Tests -------------------------------------------------------
//
Expand All @@ -197,6 +244,8 @@ class NanInfInPropSuite: public CxxTest::TestSuite
str_val.push_back("nan");
str_val.push_back("-iNf");
str_val.push_back("-9.78");
str_val.push_back("-NaN");
str_val.push_back("-89101112.1314");

Tango::DbDatum db_datum("NaNInfArrayProperty");
TS_ASSERT_THROWS_NOTHING(db_datum << str_val);
Expand All @@ -211,19 +260,21 @@ class NanInfInPropSuite: public CxxTest::TestSuite
// Extract as a string array:
vector<string> string_array_val;
TS_ASSERT(db_data_r[0] >> string_array_val);
TS_ASSERT_EQUALS(string_array_val.size(),(size_t) 7);
TS_ASSERT_EQUALS(string_array_val.size(),(size_t) 9);
TS_ASSERT_EQUALS(string_array_val[0],"1.2");
TS_ASSERT_EQUALS(string_array_val[1],"NaN");
TS_ASSERT_EQUALS(string_array_val[2],"3.4");
TS_ASSERT_EQUALS(string_array_val[3],"inf");
TS_ASSERT_EQUALS(string_array_val[4],"nan");
TS_ASSERT_EQUALS(string_array_val[5],"-iNf");
TS_ASSERT_EQUALS(string_array_val[6],"-9.78");
TS_ASSERT_EQUALS(string_array_val[7],"-NaN");
TS_ASSERT_EQUALS(string_array_val[8],"-89101112.1314");

// Extract as a float array:
vector<Tango::DevFloat> float_array_val;
TS_ASSERT(db_data_r[0] >> float_array_val);
TS_ASSERT_EQUALS(float_array_val.size(),(size_t) 7);
TS_ASSERT_EQUALS(float_array_val.size(),(size_t) 9);
TS_ASSERT_EQUALS(float_array_val[0],Tango::DevFloat(1.2));
TS_ASSERT(std::isnan(float_array_val[1]));
TS_ASSERT_EQUALS(float_array_val[2],Tango::DevFloat(3.4));
Expand All @@ -232,11 +283,14 @@ class NanInfInPropSuite: public CxxTest::TestSuite
TS_ASSERT(std::isinf(float_array_val[5]));
TS_ASSERT_LESS_THAN(float_array_val[5],0);
TS_ASSERT_EQUALS(float_array_val[6],Tango::DevFloat(-9.78));
TS_ASSERT(std::isnan(float_array_val[7]));
TS_ASSERT_EQUALS(float_array_val[8],Tango::DevFloat(-89101112.1314));


// Extract as a double array:
vector<Tango::DevDouble> double_array_val;
TS_ASSERT(db_data_r[0] >> double_array_val);
TS_ASSERT_EQUALS(double_array_val.size(),(size_t) 7);
TS_ASSERT_EQUALS(double_array_val.size(),(size_t) 9);
TS_ASSERT_EQUALS(double_array_val[0],Tango::DevDouble(1.2));
TS_ASSERT(std::isnan(double_array_val[1]));
TS_ASSERT_EQUALS(double_array_val[2],Tango::DevDouble(3.4));
Expand All @@ -245,10 +299,12 @@ class NanInfInPropSuite: public CxxTest::TestSuite
TS_ASSERT(std::isinf(double_array_val[5]));
TS_ASSERT_LESS_THAN(double_array_val[5],0);
TS_ASSERT_EQUALS(double_array_val[6],Tango::DevDouble(-9.78));
TS_ASSERT(std::isnan(double_array_val[7]));
TS_ASSERT_EQUALS(double_array_val[8],Tango::DevDouble(-89101112.1314));

// Extract as long array:
vector<Tango::DevLong> long_array_val;
TS_ASSERT(!(db_data_r[0] >> long_array_val));
TS_ASSERT(not (db_data_r[0] >> long_array_val));

// Restore the default configuration
TS_ASSERT_THROWS_NOTHING(device1->delete_property(prop_name));
Expand Down Expand Up @@ -294,43 +350,17 @@ class NanInfInPropSuite: public CxxTest::TestSuite
// test NaN in scalar property
void test_NaN_in_scalar_property()
{
//
// if your code modifies the default (device) configuration, append the following line straight after
CxxTest::TangoPrinter::restore_set("NanInfScalarProp_restore_point");

// Write NaNInfArrayProperty device property
Tango::DbData db_data_r;

// Write NaNInfScalarProperty device property
set_property("NaNInfScalarProperty", "NaN");

// Read NaNInfScalarProperty device property
string prop_name = "NaNInfScalarProperty";
TS_ASSERT_THROWS_NOTHING(device1->get_property(prop_name,db_data_r));
// Extract as a string:
string string_scalar_val;
TS_ASSERT(db_data_r[0] >> string_scalar_val);
TS_ASSERT_EQUALS(string_scalar_val,"NaN");

// Extract as float:
Tango::DevFloat float_val;
TS_ASSERT(db_data_r[0] >> float_val);
TS_ASSERT(std::isnan(float_val));

// Extract as double:
Tango::DevDouble double_val;
TS_ASSERT(db_data_r[0] >> double_val);
TS_ASSERT(std::isnan(double_val));

// Extract as short
Tango::DevShort short_val;
TS_ASSERT(!(db_data_r[0] >> short_val));
NaN_in_scalar_property("NaN");
NaN_in_scalar_property("nan");
NaN_in_scalar_property("Nan");
}

// Restore the default configuration
TS_ASSERT_THROWS_NOTHING(device1->delete_property(prop_name));
// if the test suite fails here, thanks to the restore point, the test suite TearDown method will restore the defaults
// after you set back the default configuration, append the following line
CxxTest::TangoPrinter::restore_unset("NanInfScalarProp_restore_point");
// test -NaN in scalar property
void test_Negative_NaN_in_scalar_property()
{
NaN_in_scalar_property("-NaN");
NaN_in_scalar_property("-nan");
NaN_in_scalar_property("-naN");
}

// test infinity in scalar property
Expand Down
12 changes: 8 additions & 4 deletions cppapi/client/dbapi_datum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,8 @@ bool DbDatum::operator >> (float& datum)
istream >> datum;
if (!istream)
{
if(TG_strcasecmp("nan",value_string[0].c_str()) == 0)
if ((TG_strcasecmp("nan",value_string[0].c_str()) == 0) ||
(TG_strcasecmp("-nan",value_string[0].c_str()) == 0))
{
datum = std::numeric_limits<float>::quiet_NaN();
}
Expand Down Expand Up @@ -742,7 +743,8 @@ bool DbDatum::operator >> (double& datum)
istream >> std::setprecision(TANGO_FLOAT_PRECISION) >> datum;
if (!istream)
{
if(TG_strcasecmp("nan",value_string[0].c_str()) == 0)
if ((TG_strcasecmp("nan",value_string[0].c_str()) == 0) ||
(TG_strcasecmp("-nan",value_string[0].c_str()) == 0))
{
datum = std::numeric_limits<double>::quiet_NaN();
}
Expand Down Expand Up @@ -1370,7 +1372,8 @@ bool DbDatum::operator >> (vector<float>& datum)
iostream >> datum[i];
if (!iostream)
{
if(TG_strcasecmp("nan",value_string[i].c_str()) == 0)
if ((TG_strcasecmp("nan",value_string[i].c_str()) == 0) ||
(TG_strcasecmp("-nan",value_string[i].c_str()) == 0))
{
datum[i] = std::numeric_limits<float>::quiet_NaN();
} else if (TG_strcasecmp("-inf",value_string[i].c_str()) == 0)
Expand Down Expand Up @@ -1457,7 +1460,8 @@ bool DbDatum::operator >> (vector<double>& datum)
iostream >> std::setprecision(TANGO_FLOAT_PRECISION) >> datum[i];
if (!iostream)
{
if(TG_strcasecmp("nan",value_string[i].c_str()) == 0)
if ((TG_strcasecmp("nan",value_string[i].c_str()) == 0) ||
(TG_strcasecmp("-nan",value_string[i].c_str()) == 0))
{
datum[i] = std::numeric_limits<double>::quiet_NaN();
} else if (TG_strcasecmp("-inf",value_string[i].c_str()) == 0)
Expand Down