summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'base/include/android-base/parseint.h')
-rw-r--r--base/include/android-base/parseint.h32
1 files changed, 25 insertions, 7 deletions
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index 2c8570ead..1b7cc5fa6 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -19,6 +19,7 @@
19 19
20#include <errno.h> 20#include <errno.h>
21#include <stdlib.h> 21#include <stdlib.h>
22#include <string.h>
22 23
23#include <limits> 24#include <limits>
24#include <string> 25#include <string>
@@ -31,14 +32,20 @@ namespace base {
31// otherwise valid values will be rejected. Returns boolean success; 'out' 32// otherwise valid values will be rejected. Returns boolean success; 'out'
32// is untouched if parsing fails. 33// is untouched if parsing fails.
33template <typename T> 34template <typename T>
34bool ParseUint(const char* s, T* out, 35bool ParseUint(const char* s, T* out, T max = std::numeric_limits<T>::max(),
35 T max = std::numeric_limits<T>::max()) { 36 bool allow_suffixes = false) {
36 int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; 37 int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
37 errno = 0; 38 errno = 0;
38 char* end; 39 char* end;
39 unsigned long long int result = strtoull(s, &end, base); 40 unsigned long long int result = strtoull(s, &end, base);
40 if (errno != 0 || s == end || *end != '\0') { 41 if (errno != 0 || end == s) return false;
41 return false; 42 if (*end != '\0') {
43 const char* suffixes = "bkmgtpe";
44 const char* suffix;
45 if (!allow_suffixes || (suffix = strchr(suffixes, tolower(*end))) == nullptr) return false;
46#if __clang__ // TODO: win32 still builds with GCC :-(
47 if (__builtin_mul_overflow(result, 1ULL << (10 * (suffix - suffixes)), &result)) return false;
48#endif
42 } 49 }
43 if (max < result) { 50 if (max < result) {
44 return false; 51 return false;
@@ -49,9 +56,20 @@ bool ParseUint(const char* s, T* out,
49 56
50// TODO: string_view 57// TODO: string_view
51template <typename T> 58template <typename T>
52bool ParseUint(const std::string& s, T* out, 59bool ParseUint(const std::string& s, T* out, T max = std::numeric_limits<T>::max(),
53 T max = std::numeric_limits<T>::max()) { 60 bool allow_suffixes = false) {
54 return ParseUint(s.c_str(), out, max); 61 return ParseUint(s.c_str(), out, max, allow_suffixes);
62}
63
64template <typename T>
65bool ParseByteCount(const char* s, T* out, T max = std::numeric_limits<T>::max()) {
66 return ParseUint(s, out, max, true);
67}
68
69// TODO: string_view
70template <typename T>
71bool ParseByteCount(const std::string& s, T* out, T max = std::numeric_limits<T>::max()) {
72 return ParseByteCount(s.c_str(), out, max);
55} 73}
56 74
57// Parses the signed decimal integer in the string 's' and sets 'out' to 75// Parses the signed decimal integer in the string 's' and sets 'out' to