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

Commit 586ef26f authored by Steven Moreland's avatar Steven Moreland
Browse files

Add ParseFloat (in parsedouble.h).

Bug: 110758329 # for using here
Test: libbase_test (added float_smoke)
Change-Id: I640f85655567c707cbee625ca9c88db2ab91da66
parent 1b8981e9
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));
}