Add ParseFloat (in parsedouble.h).

Bug: 110758329 # for using here
Test: libbase_test (added float_smoke)
Change-Id: I640f85655567c707cbee625ca9c88db2ab91da66
This commit is contained in:
Steven Moreland 2018-08-08 16:45:49 -07:00
parent 1b8981e972
commit 586ef26f74
2 changed files with 47 additions and 6 deletions

View file

@ -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

View file

@ -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));
}