Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ce0de0e authored by Steven Moreland's avatar Steven Moreland Committed by Gerrit Code Review
Browse files

Merge "Add ParseFloat (in parsedouble.h)."

parents 2d3f234f 586ef26f
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -24,15 +24,14 @@
namespace android {
namespace base {

// Parse double value in the string 's' and sets 'out' to that value if it exists.
// Parse floating value in the string 's' and sets 'out' to that value if it exists.
// Optionally allows the caller to define a 'min' and 'max' beyond which
// otherwise valid values will be rejected. Returns boolean success.
static inline bool ParseDouble(const char* s, double* out,
                               double min = std::numeric_limits<double>::lowest(),
                               double max = std::numeric_limits<double>::max()) {
template <typename T, T (*strtox)(const char* str, char** endptr)>
static inline bool ParseFloatingPoint(const char* s, T* out, T min, T max) {
  errno = 0;
  char* end;
  double result = strtod(s, &end);
  T result = strtox(s, &end);
  if (errno != 0 || s == end || *end != '\0') {
    return false;
  }
@@ -45,5 +44,23 @@ static inline bool ParseDouble(const char* s, double* out,
  return true;
}

// Parse double value in the string 's' and sets 'out' to that value if it exists.
// Optionally allows the caller to define a 'min' and 'max' beyond which
// otherwise valid values will be rejected. Returns boolean success.
static inline bool ParseDouble(const char* s, double* out,
                               double min = std::numeric_limits<double>::lowest(),
                               double max = std::numeric_limits<double>::max()) {
  return ParseFloatingPoint<double, strtod>(s, out, min, max);
}

// Parse float value in the string 's' and sets 'out' to that value if it exists.
// Optionally allows the caller to define a 'min' and 'max' beyond which
// otherwise valid values will be rejected. Returns boolean success.
static inline bool ParseFloat(const char* s, float* out,
                              float min = std::numeric_limits<float>::lowest(),
                              float max = std::numeric_limits<float>::max()) {
  return ParseFloatingPoint<float, strtof>(s, out, min, max);
}

}  // namespace base
}  // namespace android
+25 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@

#include <gtest/gtest.h>

TEST(parsedouble, smoke) {
TEST(parsedouble, double_smoke) {
  double d;
  ASSERT_FALSE(android::base::ParseDouble("", &d));
  ASSERT_FALSE(android::base::ParseDouble("x", &d));
@@ -41,3 +41,27 @@ TEST(parsedouble, smoke) {
  ASSERT_FALSE(android::base::ParseDouble("3.0", nullptr, -1.0, 2.0));
  ASSERT_TRUE(android::base::ParseDouble("1.0", nullptr, 0.0, 2.0));
}

TEST(parsedouble, float_smoke) {
  float f;
  ASSERT_FALSE(android::base::ParseFloat("", &f));
  ASSERT_FALSE(android::base::ParseFloat("x", &f));
  ASSERT_FALSE(android::base::ParseFloat("123.4x", &f));

  ASSERT_TRUE(android::base::ParseFloat("123.4", &f));
  ASSERT_FLOAT_EQ(123.4, f);
  ASSERT_TRUE(android::base::ParseFloat("-123.4", &f));
  ASSERT_FLOAT_EQ(-123.4, f);

  ASSERT_TRUE(android::base::ParseFloat("0", &f, 0.0));
  ASSERT_FLOAT_EQ(0.0, f);
  ASSERT_FALSE(android::base::ParseFloat("0", &f, 1e-9));
  ASSERT_FALSE(android::base::ParseFloat("3.0", &f, -1.0, 2.0));
  ASSERT_TRUE(android::base::ParseFloat("1.0", &f, 0.0, 2.0));
  ASSERT_FLOAT_EQ(1.0, f);

  ASSERT_FALSE(android::base::ParseFloat("123.4x", nullptr));
  ASSERT_TRUE(android::base::ParseFloat("-123.4", nullptr));
  ASSERT_FALSE(android::base::ParseFloat("3.0", nullptr, -1.0, 2.0));
  ASSERT_TRUE(android::base::ParseFloat("1.0", nullptr, 0.0, 2.0));
}