Move off std::sto* function which abort on failure.
Bug: http://b/31403370
Test: builds, boots, libbase tests pass
Change-Id: I89cd7ca3d8f1c8a1bad0ddf3043439449d19a293
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index 7415409..2c8570e 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -21,13 +21,15 @@
#include <stdlib.h>
#include <limits>
+#include <string>
namespace android {
namespace base {
// Parses the unsigned decimal integer in the string 's' and sets 'out' to
// that value. Optionally allows the caller to define a 'max' beyond which
-// otherwise valid values will be rejected. Returns boolean success.
+// otherwise valid values will be rejected. Returns boolean success; 'out'
+// is untouched if parsing fails.
template <typename T>
bool ParseUint(const char* s, T* out,
T max = std::numeric_limits<T>::max()) {
@@ -45,10 +47,17 @@
return true;
}
+// TODO: string_view
+template <typename T>
+bool ParseUint(const std::string& s, T* out,
+ T max = std::numeric_limits<T>::max()) {
+ return ParseUint(s.c_str(), out, max);
+}
+
// Parses the signed decimal integer in the string 's' and sets 'out' to
// that value. Optionally allows the caller to define a 'min' and 'max
// beyond which otherwise valid values will be rejected. Returns boolean
-// success.
+// success; 'out' is untouched if parsing fails.
template <typename T>
bool ParseInt(const char* s, T* out,
T min = std::numeric_limits<T>::min(),
@@ -67,6 +76,14 @@
return true;
}
+// TODO: string_view
+template <typename T>
+bool ParseInt(const std::string& s, T* out,
+ T min = std::numeric_limits<T>::min(),
+ T max = std::numeric_limits<T>::max()) {
+ return ParseInt(s.c_str(), out, min, max);
+}
+
} // namespace base
} // namespace android
diff --git a/base/parseint_test.cpp b/base/parseint_test.cpp
index 6a3ba31..483b1d3 100644
--- a/base/parseint_test.cpp
+++ b/base/parseint_test.cpp
@@ -19,7 +19,7 @@
#include <gtest/gtest.h>
TEST(parseint, signed_smoke) {
- int i;
+ int i = 0;
ASSERT_FALSE(android::base::ParseInt("x", &i));
ASSERT_FALSE(android::base::ParseInt("123x", &i));
@@ -28,7 +28,7 @@
ASSERT_TRUE(android::base::ParseInt("-123", &i));
ASSERT_EQ(-123, i);
- short s;
+ short s = 0;
ASSERT_TRUE(android::base::ParseInt("1234", &s));
ASSERT_EQ(1234, s);
@@ -39,7 +39,7 @@
}
TEST(parseint, unsigned_smoke) {
- unsigned int i;
+ unsigned int i = 0u;
ASSERT_FALSE(android::base::ParseUint("x", &i));
ASSERT_FALSE(android::base::ParseUint("123x", &i));
@@ -47,7 +47,7 @@
ASSERT_EQ(123u, i);
ASSERT_FALSE(android::base::ParseUint("-123", &i));
- unsigned short s;
+ unsigned short s = 0u;
ASSERT_TRUE(android::base::ParseUint("1234", &s));
ASSERT_EQ(1234u, s);
@@ -58,21 +58,41 @@
}
TEST(parseint, no_implicit_octal) {
- int i;
+ int i = 0;
ASSERT_TRUE(android::base::ParseInt("0123", &i));
ASSERT_EQ(123, i);
- unsigned int u;
+ unsigned int u = 0u;
ASSERT_TRUE(android::base::ParseUint("0123", &u));
ASSERT_EQ(123u, u);
}
TEST(parseint, explicit_hex) {
- int i;
+ int i = 0;
ASSERT_TRUE(android::base::ParseInt("0x123", &i));
ASSERT_EQ(0x123, i);
- unsigned int u;
+ unsigned int u = 0u;
ASSERT_TRUE(android::base::ParseUint("0x123", &u));
ASSERT_EQ(0x123u, u);
}
+
+TEST(parseint, string) {
+ int i = 0;
+ ASSERT_TRUE(android::base::ParseInt(std::string("123"), &i));
+ ASSERT_EQ(123, i);
+
+ unsigned int u = 0u;
+ ASSERT_TRUE(android::base::ParseUint(std::string("123"), &u));
+ ASSERT_EQ(123u, u);
+}
+
+TEST(parseint, untouched_on_failure) {
+ int i = 123;
+ ASSERT_FALSE(android::base::ParseInt("456x", &i));
+ ASSERT_EQ(123, i);
+
+ unsigned int u = 123u;
+ ASSERT_FALSE(android::base::ParseInt("456x", &u));
+ ASSERT_EQ(123u, u);
+}
diff --git a/base/properties.cpp b/base/properties.cpp
index fab3005..37daf9a 100644
--- a/base/properties.cpp
+++ b/base/properties.cpp
@@ -52,7 +52,7 @@
T GetIntProperty(const std::string& key, T default_value, T min, T max) {
T result;
std::string value = GetProperty(key, "");
- if (!value.empty() && android::base::ParseInt(value.c_str(), &result, min, max)) return result;
+ if (!value.empty() && android::base::ParseInt(value, &result, min, max)) return result;
return default_value;
}
@@ -60,7 +60,7 @@
T GetUintProperty(const std::string& key, T default_value, T max) {
T result;
std::string value = GetProperty(key, "");
- if (!value.empty() && android::base::ParseUint(value.c_str(), &result, max)) return result;
+ if (!value.empty() && android::base::ParseUint(value, &result, max)) return result;
return default_value;
}