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