sdbus++: support special double values
Enable properties to have default values of special IEEE floating
points: 'NaN', 'infinity' and 'epsilon'.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I7c2daa3c36cde69c2ee06afd75a8d2e77992c6e7
diff --git a/docs/interface.md b/docs/interface.md
index 5137a92..635bfb6 100644
--- a/docs/interface.md
+++ b/docs/interface.md
@@ -85,6 +85,18 @@
* object_path
* signature
+### Special type values
+
+For 'double' types it is possible to express one of the special values:
+ * 'NaN' (case-insensitive)
+ - A quiet-type not-a-number value.
+ * 'Infinity' (case-insensitive)
+ - A positive infinity value.
+ * '-Infinity' (case-insensitive)
+ - A negative infinity value.
+ * 'Epsilon' (case-insensitive)
+ - An epsilon value.
+
### Containers
Container types can also be expressed, but the contained-type should be
expressed within square-brackets `[]`. The following containers are supported:
diff --git a/test/server/Test.interface.yaml b/test/server/Test.interface.yaml
index 30df1f9..ed98eb3 100644
--- a/test/server/Test.interface.yaml
+++ b/test/server/Test.interface.yaml
@@ -22,3 +22,15 @@
type: uint64
- name: ObjectPath
type: object_path
+ - name: DoubleAsNAN
+ type: double
+ default: NaN
+ - name: DoubleAsInf
+ type: double
+ default: Infinity
+ - name: DoubleAsNegInf
+ type: double
+ default: -Infinity
+ - name: DoubleAsEpsilon
+ type: double
+ default: Epsilon
diff --git a/test/server/object.cpp b/test/server/object.cpp
index 8faa668..76e077d 100644
--- a/test/server/object.cpp
+++ b/test/server/object.cpp
@@ -103,3 +103,24 @@
sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _))
.Times(0);
}
+
+TEST_F(Object, DoubleHasDefaultValues)
+{
+ // Simulate the typical usage of a service
+ sdbusplus::server::manager::manager objManager(bus, objPath);
+ bus.request_name(busName);
+
+ EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
+ .Times(1);
+ EXPECT_CALL(sdbusMock,
+ sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
+ .Times(0);
+
+ auto test = std::make_unique<TestInherit>(bus, objPath);
+ EXPECT_TRUE(std::isnan(test->doubleAsNAN()));
+ EXPECT_TRUE(std::isinf(test->doubleAsInf()) &&
+ !std::signbit(test->doubleAsInf()));
+ EXPECT_TRUE(std::isinf(test->doubleAsNegInf()) &&
+ std::signbit(test->doubleAsNegInf()));
+ EXPECT_EQ(std::numeric_limits<double>::epsilon(), test->doubleAsEpsilon());
+}
diff --git a/tools/sdbusplus/property.py b/tools/sdbusplus/property.py
index 6eb952e..490fabf 100644
--- a/tools/sdbusplus/property.py
+++ b/tools/sdbusplus/property.py
@@ -25,6 +25,20 @@
self.typeName.lower() == "string"):
# Wrap string type default values with double-quotes
self.defaultValue = "\"" + self.defaultValue + "\""
+ elif(isinstance(self.defaultValue, str) and
+ self.typeName.lower() == "double"):
+ if self.defaultValue.lower() == "nan":
+ self.defaultValue = \
+ 'std::numeric_limits<double>::quiet_NaN()'
+ elif self.defaultValue.lower() == "infinity":
+ self.defaultValue = \
+ 'std::numeric_limits<double>::infinity()'
+ elif self.defaultValue.lower() == "-infinity":
+ self.defaultValue = \
+ '-std::numeric_limits<double>::infinity()'
+ elif self.defaultValue.lower() == "epsilon":
+ self.defaultValue = \
+ 'std::numeric_limits<double>::epsilon()'
super(Property, self).__init__(**kwargs)
diff --git a/tools/sdbusplus/templates/interface.server.hpp.mako b/tools/sdbusplus/templates/interface.server.hpp.mako
index 90c8418..389b872 100644
--- a/tools/sdbusplus/templates/interface.server.hpp.mako
+++ b/tools/sdbusplus/templates/interface.server.hpp.mako
@@ -1,4 +1,5 @@
#pragma once
+#include <limits>
#include <map>
#include <sdbusplus/sdbus.hpp>
#include <sdbusplus/server.hpp>