jsonRead: Add floating point support
Add support of reading floating point numbers.
Tested-by: Successfully unpacked doubles
Change-Id: I9cf5e33dbb99367a53013be28b8f905eae2e4518
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index 2eeace1..aa45261 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -78,40 +78,90 @@
template <typename Type>
constexpr bool is_std_array_v = is_std_array<Type>::value;
+template <typename ToType, typename FromType>
+bool checkRange(const FromType* from, const std::string& key,
+ nlohmann::json& jsonValue, crow::Response& res)
+{
+ if (from == nullptr)
+ {
+ BMCWEB_LOG_DEBUG << "Value for key " << key
+ << " was incorrect type: " << __PRETTY_FUNCTION__;
+ messages::propertyValueTypeError(res, jsonValue.dump(), key);
+ return false;
+ }
+
+ if (*from > std::numeric_limits<ToType>::max())
+ {
+ BMCWEB_LOG_DEBUG << "Value for key " << key
+ << " was greater than max: " << __PRETTY_FUNCTION__;
+ messages::propertyValueNotInList(res, jsonValue.dump(), key);
+ return false;
+ }
+ if (*from < std::numeric_limits<ToType>::lowest())
+ {
+ BMCWEB_LOG_DEBUG << "Value for key " << key
+ << " was less than min: " << __PRETTY_FUNCTION__;
+ messages::propertyValueNotInList(res, jsonValue.dump(), key);
+ return false;
+ }
+ if constexpr (std::is_floating_point_v<ToType>)
+ {
+ if (std::isnan(*from))
+ {
+ BMCWEB_LOG_DEBUG << "Value for key " << key << " was NAN";
+ messages::propertyValueNotInList(res, jsonValue.dump(), key);
+ return false;
+ }
+ }
+
+ return true;
+}
+
template <typename Type>
void unpackValue(nlohmann::json& jsonValue, const std::string& key,
crow::Response& res, Type& value)
{
- if constexpr (std::is_arithmetic_v<Type>)
+ if constexpr (std::is_floating_point_v<Type>)
{
- using NumType =
- std::conditional_t<std::is_signed_v<Type>, int64_t, uint64_t>;
+ double helper = 0;
+ double* jsonPtr = jsonValue.get_ptr<double*>();
- NumType* jsonPtr = jsonValue.get_ptr<NumType*>();
if (jsonPtr == nullptr)
{
- BMCWEB_LOG_DEBUG
- << "Value for key " << key
- << " was incorrect type: " << jsonValue.type_name();
- messages::propertyValueTypeError(res, jsonValue.dump(), key);
- return;
+ int64_t* intPtr = jsonValue.get_ptr<int64_t*>();
+ if (intPtr != nullptr)
+ {
+ helper = static_cast<double>(*intPtr);
+ jsonPtr = &helper;
+ }
}
- if (*jsonPtr > std::numeric_limits<Type>::max())
+ if (!checkRange<Type>(jsonPtr, key, jsonValue, res))
{
- BMCWEB_LOG_DEBUG << "Value for key " << key
- << " was out of range: " << jsonValue.type_name();
- messages::propertyValueNotInList(res, jsonValue.dump(), key);
- return;
- }
- if (*jsonPtr < std::numeric_limits<Type>::min())
- {
- BMCWEB_LOG_DEBUG << "Value for key " << key
- << " was out of range: " << jsonValue.type_name();
- messages::propertyValueNotInList(res, jsonValue.dump(), key);
return;
}
value = static_cast<Type>(*jsonPtr);
}
+
+ else if constexpr (std::is_signed_v<Type>)
+ {
+ int64_t* jsonPtr = jsonValue.get_ptr<int64_t*>();
+ if (!checkRange<Type>(jsonPtr, key, jsonValue, res))
+ {
+ return;
+ }
+ value = static_cast<Type>(*jsonPtr);
+ }
+
+ else if constexpr (std::is_unsigned_v<Type>)
+ {
+ uint64_t* jsonPtr = jsonValue.get_ptr<uint64_t*>();
+ if (!checkRange<Type>(jsonPtr, key, jsonValue, res))
+ {
+ return;
+ }
+ value = static_cast<Type>(*jsonPtr);
+ }
+
else if constexpr (is_optional_v<Type>)
{
value.emplace();