[libcamera-devel,7/7] libcamera: yaml_parser: Add get() specializations for 16-bit integers
diff mbox series

Message ID 20220616142403.20723-8-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • libcamera: yaml_parser: Add iterator API
Related show

Commit Message

Laurent Pinchart June 16, 2022, 2:24 p.m. UTC
Extend the YamlObject::get() function template to support 16-bit
integers.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/internal/yaml_parser.h |  2 +
 src/libcamera/yaml_parser.cpp            | 61 ++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

Comments

Jacopo Mondi June 17, 2022, 2:18 p.m. UTC | #1
Hi Laurent

On Thu, Jun 16, 2022 at 05:24:03PM +0300, Laurent Pinchart via libcamera-devel wrote:
> Extend the YamlObject::get() function template to support 16-bit
> integers.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Seems in-line with the other specializations

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
   j

> ---
>  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 811be1affcc0..90d348eac74c 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<bool, T> ||
>  			 std::is_same_v<double, T> ||
> +			 std::is_same_v<int16_t, T> ||
> +			 std::is_same_v<uint16_t, T> ||
>  			 std::is_same_v<int32_t, T> ||
>  			 std::is_same_v<uint32_t, T> ||
>  			 std::is_same_v<std::string, T> ||
> diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
> index bd4b501b1422..5c45e44e49c3 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<int16_t>::min() ||
> +	    value > std::numeric_limits<int16_t>::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<uint16_t>::min() ||
> +	    value > std::numeric_limits<uint16_t>::max())
> +		return defaultValue;
> +
> +	setOk(ok, true);
> +	return value;
> +}
> +
>  template<>
>  int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const
>  {
> --
> Regards,
>
> Laurent Pinchart
>
Hanlin Chen June 20, 2022, 12:08 p.m. UTC | #2
Hi Laurent,

Reviewed-by: Han-Lin Chen <hanlinchen@chromium.org>
Thanks.

On Fri, Jun 17, 2022 at 10:18 PM Jacopo Mondi via libcamera-devel
<libcamera-devel@lists.libcamera.org> wrote:
>
> Hi Laurent
>
> On Thu, Jun 16, 2022 at 05:24:03PM +0300, Laurent Pinchart via libcamera-devel wrote:
> > Extend the YamlObject::get() function template to support 16-bit
> > integers.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> Seems in-line with the other specializations
>
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
>
> Thanks
>    j
>
> > ---
> >  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 811be1affcc0..90d348eac74c 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<bool, T> ||
> >                        std::is_same_v<double, T> ||
> > +                      std::is_same_v<int16_t, T> ||
> > +                      std::is_same_v<uint16_t, T> ||
> >                        std::is_same_v<int32_t, T> ||
> >                        std::is_same_v<uint32_t, T> ||
> >                        std::is_same_v<std::string, T> ||
> > diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
> > index bd4b501b1422..5c45e44e49c3 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<int16_t>::min() ||
> > +         value > std::numeric_limits<int16_t>::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<uint16_t>::min() ||
> > +         value > std::numeric_limits<uint16_t>::max())
> > +             return defaultValue;
> > +
> > +     setOk(ok, true);
> > +     return value;
> > +}
> > +
> >  template<>
> >  int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const
> >  {
> > --
> > Regards,
> >
> > Laurent Pinchart
> >

Patch
diff mbox series

diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h
index 811be1affcc0..90d348eac74c 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<bool, T> ||
 			 std::is_same_v<double, T> ||
+			 std::is_same_v<int16_t, T> ||
+			 std::is_same_v<uint16_t, T> ||
 			 std::is_same_v<int32_t, T> ||
 			 std::is_same_v<uint32_t, T> ||
 			 std::is_same_v<std::string, T> ||
diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
index bd4b501b1422..5c45e44e49c3 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<int16_t>::min() ||
+	    value > std::numeric_limits<int16_t>::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<uint16_t>::min() ||
+	    value > std::numeric_limits<uint16_t>::max())
+		return defaultValue;
+
+	setOk(ok, true);
+	return value;
+}
+
 template<>
 int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const
 {