From c7d260c03abdf8963b5b0f2a8af7481ca08d6c1a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 May 2022 01:58:14 +0300 Subject: libcamera: yaml_parser: Add get() specializations for 16-bit integers Extend the YamlObject::get() function template to support 16-bit integers. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Han-Lin Chen --- include/libcamera/internal/yaml_parser.h | 2 ++ src/libcamera/yaml_parser.cpp | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index 7e44723b..064cf443 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -156,6 +156,8 @@ public: typename std::enable_if_t< std::is_same_v || std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index bd4b501b..5c45e44e 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -138,6 +138,67 @@ bool YamlObject::get(const bool &defaultValue, bool *ok) const return defaultValue; } +template<> +int16_t YamlObject::get(const int16_t &defaultValue, bool *ok) const +{ + setOk(ok, false); + + if (type_ != Type::Value) + return defaultValue; + + if (value_ == "") + return defaultValue; + + char *end; + + errno = 0; + int16_t value = std::strtol(value_.c_str(), &end, 10); + + if ('\0' != *end || errno == ERANGE || + value < std::numeric_limits::min() || + value > std::numeric_limits::max()) + return defaultValue; + + setOk(ok, true); + return value; +} + +template<> +uint16_t YamlObject::get(const uint16_t &defaultValue, bool *ok) const +{ + setOk(ok, false); + + if (type_ != Type::Value) + return defaultValue; + + if (value_ == "") + return defaultValue; + + /* + * libyaml parses all scalar values as strings. When a string has + * leading spaces before a minus sign, for example " -10", strtoul + * skips leading spaces, accepts the leading minus sign, and the + * calculated digits are negated as if by unary minus. Rule it out in + * case the user gets a large number when the value is negative. + */ + std::size_t found = value_.find_first_not_of(" \t"); + if (found != std::string::npos && value_[found] == '-') + return defaultValue; + + char *end; + + errno = 0; + uint16_t value = std::strtoul(value_.c_str(), &end, 10); + + if ('\0' != *end || errno == ERANGE || + value < std::numeric_limits::min() || + value > std::numeric_limits::max()) + return defaultValue; + + setOk(ok, true); + return value; +} + template<> int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const { -- cgit v1.2.1