OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/string_util.h" | 5 #include "base/string_util.h" |
6 | 6 |
| 7 #include "build/build_config.h" |
| 8 |
7 #include <ctype.h> | 9 #include <ctype.h> |
8 #include <errno.h> | 10 #include <errno.h> |
9 #include <math.h> | 11 #include <math.h> |
10 #include <stdarg.h> | 12 #include <stdarg.h> |
11 #include <stdio.h> | 13 #include <stdio.h> |
12 #include <stdlib.h> | 14 #include <stdlib.h> |
13 #include <string.h> | 15 #include <string.h> |
14 #include <time.h> | 16 #include <time.h> |
15 #include <wchar.h> | 17 #include <wchar.h> |
16 #include <wctype.h> | 18 #include <wctype.h> |
17 | 19 |
18 #include <algorithm> | 20 #include <algorithm> |
19 #include <vector> | 21 #include <vector> |
20 | 22 |
21 #include "base/basictypes.h" | 23 #include "base/basictypes.h" |
22 #include "base/logging.h" | 24 #include "base/logging.h" |
23 #include "base/singleton.h" | 25 #include "base/singleton.h" |
| 26 #include "third_party/dmg_fp/dmg_fp.h" |
24 | 27 |
25 namespace { | 28 namespace { |
26 | 29 |
27 // Hack to convert any char-like type to its unsigned counterpart. | 30 // Hack to convert any char-like type to its unsigned counterpart. |
28 // For example, it will convert char, signed char and unsigned char to unsigned | 31 // For example, it will convert char, signed char and unsigned char to unsigned |
29 // char. | 32 // char. |
30 template<typename T> | 33 template<typename T> |
31 struct ToUnsigned { | 34 struct ToUnsigned { |
32 typedef T Unsigned; | 35 typedef T Unsigned; |
33 }; | 36 }; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // - a typedef for value_type, the target numeric type. | 82 // - a typedef for value_type, the target numeric type. |
80 // - a static function, convert_func, which dispatches to an appropriate | 83 // - a static function, convert_func, which dispatches to an appropriate |
81 // strtol-like function and returns type value_type. | 84 // strtol-like function and returns type value_type. |
82 // - a static function, valid_func, which validates |input| and returns a bool | 85 // - a static function, valid_func, which validates |input| and returns a bool |
83 // indicating whether it is in proper form. This is used to check for | 86 // indicating whether it is in proper form. This is used to check for |
84 // conditions that convert_func tolerates but should result in | 87 // conditions that convert_func tolerates but should result in |
85 // StringToNumber returning false. For strtol-like funtions, valid_func | 88 // StringToNumber returning false. For strtol-like funtions, valid_func |
86 // should check for leading whitespace. | 89 // should check for leading whitespace. |
87 template<typename StringToNumberTraits> | 90 template<typename StringToNumberTraits> |
88 bool StringToNumber(const typename StringToNumberTraits::string_type& input, | 91 bool StringToNumber(const typename StringToNumberTraits::string_type& input, |
89 typename StringToNumberTraits::value_type* output) { | 92 typename StringToNumberTraits::value_type* output, |
| 93 base::LocaleDependence locale_dependent) { |
90 typedef StringToNumberTraits traits; | 94 typedef StringToNumberTraits traits; |
91 | 95 |
92 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. | 96 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. |
93 typename traits::string_type::value_type* endptr = NULL; | 97 typename traits::string_type::value_type* endptr = NULL; |
94 typename traits::value_type value = traits::convert_func(input.c_str(), | 98 typename traits::value_type value = traits::convert_func(input.c_str(), |
95 &endptr); | 99 &endptr, locale_dependent == base::LOCALE_DEPENDENT); |
96 *output = value; | 100 *output = value; |
97 | 101 |
98 // Cases to return false: | 102 // Cases to return false: |
99 // - If errno is ERANGE, there was an overflow or underflow. | 103 // - If errno is ERANGE, there was an overflow or underflow. |
100 // - If the input string is empty, there was nothing to parse. | 104 // - If the input string is empty, there was nothing to parse. |
101 // - If endptr does not point to the end of the string, there are either | 105 // - If endptr does not point to the end of the string, there are either |
102 // characters remaining in the string after a parsed number, or the string | 106 // characters remaining in the string after a parsed number, or the string |
103 // does not begin with a parseable number. endptr is compared to the | 107 // does not begin with a parseable number. endptr is compared to the |
104 // expected end given the string's stated length to correctly catch cases | 108 // expected end given the string's stated length to correctly catch cases |
105 // where the string contains embedded NUL characters. | 109 // where the string contains embedded NUL characters. |
106 // - valid_func determines that the input is not in preferred form. | 110 // - valid_func determines that the input is not in preferred form. |
107 return errno == 0 && | 111 return errno == 0 && |
108 !input.empty() && | 112 !input.empty() && |
109 input.c_str() + input.length() == endptr && | 113 input.c_str() + input.length() == endptr && |
110 traits::valid_func(input); | 114 traits::valid_func(input); |
111 } | 115 } |
112 | 116 |
113 class StringToLongTraits { | 117 class StringToLongTraits { |
114 public: | 118 public: |
115 typedef std::string string_type; | 119 typedef std::string string_type; |
116 typedef long value_type; | 120 typedef long value_type; |
117 static const int kBase = 10; | 121 static const int kBase = 10; |
118 static inline value_type convert_func(const string_type::value_type* str, | 122 static inline value_type convert_func(const string_type::value_type* str, |
119 string_type::value_type** endptr) { | 123 string_type::value_type** endptr, |
| 124 bool locale_dependent) { |
120 return strtol(str, endptr, kBase); | 125 return strtol(str, endptr, kBase); |
121 } | 126 } |
122 static inline bool valid_func(const string_type& str) { | 127 static inline bool valid_func(const string_type& str) { |
123 return !str.empty() && !isspace(str[0]); | 128 return !str.empty() && !isspace(str[0]); |
124 } | 129 } |
125 }; | 130 }; |
126 | 131 |
127 class WStringToLongTraits { | 132 class WStringToLongTraits { |
128 public: | 133 public: |
129 typedef std::wstring string_type; | 134 typedef std::wstring string_type; |
130 typedef long value_type; | 135 typedef long value_type; |
131 static const int kBase = 10; | 136 static const int kBase = 10; |
132 static inline value_type convert_func(const string_type::value_type* str, | 137 static inline value_type convert_func(const string_type::value_type* str, |
133 string_type::value_type** endptr) { | 138 string_type::value_type** endptr, |
| 139 bool locale_dependent) { |
134 return wcstol(str, endptr, kBase); | 140 return wcstol(str, endptr, kBase); |
135 } | 141 } |
136 static inline bool valid_func(const string_type& str) { | 142 static inline bool valid_func(const string_type& str) { |
137 return !str.empty() && !iswspace(str[0]); | 143 return !str.empty() && !iswspace(str[0]); |
138 } | 144 } |
139 }; | 145 }; |
140 | 146 |
141 class StringToInt64Traits { | 147 class StringToInt64Traits { |
142 public: | 148 public: |
143 typedef std::string string_type; | 149 typedef std::string string_type; |
144 typedef int64 value_type; | 150 typedef int64 value_type; |
145 static const int kBase = 10; | 151 static const int kBase = 10; |
146 static inline value_type convert_func(const string_type::value_type* str, | 152 static inline value_type convert_func(const string_type::value_type* str, |
147 string_type::value_type** endptr) { | 153 string_type::value_type** endptr, |
| 154 bool locale_dependent) { |
148 #ifdef OS_WIN | 155 #ifdef OS_WIN |
149 return _strtoi64(str, endptr, kBase); | 156 return _strtoi64(str, endptr, kBase); |
150 #else // assume OS_POSIX | 157 #else // assume OS_POSIX |
151 return strtoll(str, endptr, kBase); | 158 return strtoll(str, endptr, kBase); |
152 #endif | 159 #endif |
153 } | 160 } |
154 static inline bool valid_func(const string_type& str) { | 161 static inline bool valid_func(const string_type& str) { |
155 return !str.empty() && !isspace(str[0]); | 162 return !str.empty() && !isspace(str[0]); |
156 } | 163 } |
157 }; | 164 }; |
158 | 165 |
159 class WStringToInt64Traits { | 166 class WStringToInt64Traits { |
160 public: | 167 public: |
161 typedef std::wstring string_type; | 168 typedef std::wstring string_type; |
162 typedef int64 value_type; | 169 typedef int64 value_type; |
163 static const int kBase = 10; | 170 static const int kBase = 10; |
164 static inline value_type convert_func(const string_type::value_type* str, | 171 static inline value_type convert_func(const string_type::value_type* str, |
165 string_type::value_type** endptr) { | 172 string_type::value_type** endptr, |
| 173 bool locale_dependent) { |
166 #ifdef OS_WIN | 174 #ifdef OS_WIN |
167 return _wcstoi64(str, endptr, kBase); | 175 return _wcstoi64(str, endptr, kBase); |
168 #else // assume OS_POSIX | 176 #else // assume OS_POSIX |
169 return wcstoll(str, endptr, kBase); | 177 return wcstoll(str, endptr, kBase); |
170 #endif | 178 #endif |
171 } | 179 } |
172 static inline bool valid_func(const string_type& str) { | 180 static inline bool valid_func(const string_type& str) { |
173 return !str.empty() && !iswspace(str[0]); | 181 return !str.empty() && !iswspace(str[0]); |
174 } | 182 } |
175 }; | 183 }; |
176 | 184 |
177 // For the HexString variants, use the unsigned variants like strtoul for | 185 // For the HexString variants, use the unsigned variants like strtoul for |
178 // convert_func so that input like "0x80000000" doesn't result in an overflow. | 186 // convert_func so that input like "0x80000000" doesn't result in an overflow. |
179 | 187 |
180 class HexStringToLongTraits { | 188 class HexStringToLongTraits { |
181 public: | 189 public: |
182 typedef std::string string_type; | 190 typedef std::string string_type; |
183 typedef long value_type; | 191 typedef long value_type; |
184 static const int kBase = 16; | 192 static const int kBase = 16; |
185 static inline value_type convert_func(const string_type::value_type* str, | 193 static inline value_type convert_func(const string_type::value_type* str, |
186 string_type::value_type** endptr) { | 194 string_type::value_type** endptr, |
| 195 bool locale_dependent) { |
187 return strtoul(str, endptr, kBase); | 196 return strtoul(str, endptr, kBase); |
188 } | 197 } |
189 static inline bool valid_func(const string_type& str) { | 198 static inline bool valid_func(const string_type& str) { |
190 return !str.empty() && !isspace(str[0]); | 199 return !str.empty() && !isspace(str[0]); |
191 } | 200 } |
192 }; | 201 }; |
193 | 202 |
194 class HexWStringToLongTraits { | 203 class HexWStringToLongTraits { |
195 public: | 204 public: |
196 typedef std::wstring string_type; | 205 typedef std::wstring string_type; |
197 typedef long value_type; | 206 typedef long value_type; |
198 static const int kBase = 16; | 207 static const int kBase = 16; |
199 static inline value_type convert_func(const string_type::value_type* str, | 208 static inline value_type convert_func(const string_type::value_type* str, |
200 string_type::value_type** endptr) { | 209 string_type::value_type** endptr, |
| 210 bool locale_dependent) { |
201 return wcstoul(str, endptr, kBase); | 211 return wcstoul(str, endptr, kBase); |
202 } | 212 } |
203 static inline bool valid_func(const string_type& str) { | 213 static inline bool valid_func(const string_type& str) { |
204 return !str.empty() && !iswspace(str[0]); | 214 return !str.empty() && !iswspace(str[0]); |
205 } | 215 } |
206 }; | 216 }; |
207 | 217 |
208 class StringToDoubleTraits { | 218 class StringToDoubleTraits { |
209 public: | 219 public: |
210 typedef std::string string_type; | 220 typedef std::string string_type; |
211 typedef double value_type; | 221 typedef double value_type; |
212 static inline value_type convert_func(const string_type::value_type* str, | 222 static inline value_type convert_func(const string_type::value_type* str, |
213 string_type::value_type** endptr) { | 223 string_type::value_type** endptr, |
214 return strtod(str, endptr); | 224 bool locale_dependent) { |
| 225 if (locale_dependent) { |
| 226 return strtod(str, endptr); |
| 227 } else { |
| 228 return dmg_fp::strtod(str, endptr); |
| 229 } |
215 } | 230 } |
216 static inline bool valid_func(const string_type& str) { | 231 static inline bool valid_func(const string_type& str) { |
217 return !str.empty() && !isspace(str[0]); | 232 return !str.empty() && !isspace(str[0]); |
218 } | 233 } |
219 }; | 234 }; |
220 | 235 |
221 class WStringToDoubleTraits { | 236 class WStringToDoubleTraits { |
222 public: | 237 public: |
223 typedef std::wstring string_type; | 238 typedef std::wstring string_type; |
224 typedef double value_type; | 239 typedef double value_type; |
225 static inline value_type convert_func(const string_type::value_type* str, | 240 static inline value_type convert_func(const string_type::value_type* str, |
226 string_type::value_type** endptr) { | 241 string_type::value_type** endptr, |
227 return wcstod(str, endptr); | 242 bool locale_dependent) { |
| 243 if (base::LOCALE_DEPENDENT == locale_dependent) { |
| 244 return wcstod(str, endptr); |
| 245 } else { |
| 246 // We are going to do some interesting things here, just because |
| 247 // dmg_fp::strtod does not like wchar_t. Converting to ASCII should |
| 248 // be fine. |
| 249 |
| 250 // Put endptr at end of input string, so it's not recognized as an error. |
| 251 *endptr = const_cast<string_type::value_type*>(str) + wcslen(str); |
| 252 |
| 253 std::string ascii_string = WideToASCII(std::wstring(str)); |
| 254 return StringToDouble(ascii_string, base::LOCALE_INDEPENDENT); |
| 255 } |
228 } | 256 } |
229 static inline bool valid_func(const string_type& str) { | 257 static inline bool valid_func(const string_type& str) { |
230 return !str.empty() && !iswspace(str[0]); | 258 return !str.empty() && !iswspace(str[0]); |
231 } | 259 } |
232 }; | 260 }; |
233 | 261 |
234 } // namespace | 262 } // namespace |
235 | 263 |
236 | 264 |
237 namespace base { | 265 namespace base { |
(...skipping 28 matching lines...) Expand all Loading... |
266 in_specification = false; | 294 in_specification = false; |
267 } | 295 } |
268 } | 296 } |
269 } | 297 } |
270 | 298 |
271 } | 299 } |
272 | 300 |
273 return true; | 301 return true; |
274 } | 302 } |
275 | 303 |
| 304 std::string DoubleToString(double value, LocaleDependence locale_dependent) { |
| 305 if (LOCALE_DEPENDENT == locale_dependent) { |
| 306 return StringPrintf("%g", value); |
| 307 } else { |
| 308 char buffer[32]; |
| 309 dmg_fp::g_fmt(buffer, value); |
| 310 return std::string(buffer); |
| 311 } |
| 312 } |
| 313 |
| 314 std::wstring DoubleToWString(double value, LocaleDependence locale_dependent) { |
| 315 return ASCIIToWide(DoubleToString(value, locale_dependent)); |
| 316 } |
| 317 |
| 318 bool StringToDouble(const std::string& input, double* output, |
| 319 LocaleDependence locale_dependent) { |
| 320 return StringToNumber<StringToDoubleTraits>(input, output, |
| 321 locale_dependent); |
| 322 } |
| 323 |
| 324 bool StringToDouble(const std::wstring& input, double* output, |
| 325 LocaleDependence locale_dependent) { |
| 326 return StringToNumber<WStringToDoubleTraits>(input, output, |
| 327 locale_dependent); |
| 328 } |
| 329 |
| 330 double StringToDouble(const std::string& value, |
| 331 LocaleDependence locale_dependent) { |
| 332 double result; |
| 333 StringToDouble(value, &result, locale_dependent); |
| 334 return result; |
| 335 } |
| 336 |
| 337 double StringToDouble(const std::wstring& value, |
| 338 LocaleDependence locale_dependent) { |
| 339 double result; |
| 340 StringToDouble(value, &result, locale_dependent); |
| 341 return result; |
| 342 } |
| 343 |
276 } // namespace base | 344 } // namespace base |
277 | 345 |
278 | 346 |
279 const std::string& EmptyString() { | 347 const std::string& EmptyString() { |
280 return *Singleton<std::string>::get(); | 348 return *Singleton<std::string>::get(); |
281 } | 349 } |
282 | 350 |
283 const std::wstring& EmptyWString() { | 351 const std::wstring& EmptyWString() { |
284 return *Singleton<std::wstring>::get(); | 352 return *Singleton<std::wstring>::get(); |
285 } | 353 } |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 inline void StringAppendV(std::string* dst, const char* format, va_list ap) { | 1053 inline void StringAppendV(std::string* dst, const char* format, va_list ap) { |
986 StringAppendVT<char>(dst, format, ap); | 1054 StringAppendVT<char>(dst, format, ap); |
987 } | 1055 } |
988 | 1056 |
989 inline void StringAppendV(std::wstring* dst, | 1057 inline void StringAppendV(std::wstring* dst, |
990 const wchar_t* format, | 1058 const wchar_t* format, |
991 va_list ap) { | 1059 va_list ap) { |
992 StringAppendVT<wchar_t>(dst, format, ap); | 1060 StringAppendVT<wchar_t>(dst, format, ap); |
993 } | 1061 } |
994 | 1062 |
| 1063 bool StringToDouble(const std::string& input, double* output) { |
| 1064 return StringToDouble(input, output, base::LOCALE_DEPENDENT); |
| 1065 } |
| 1066 |
| 1067 bool StringToDouble(const std::wstring& input, double* output) { |
| 1068 return StringToDouble(input, output, base::LOCALE_DEPENDENT); |
| 1069 } |
| 1070 |
| 1071 double StringToDouble(const std::string& value) { |
| 1072 return StringToDouble(value, base::LOCALE_DEPENDENT); |
| 1073 } |
| 1074 |
| 1075 double StringToDouble(const std::wstring& value) { |
| 1076 return StringToDouble(value, base::LOCALE_DEPENDENT); |
| 1077 } |
| 1078 |
995 std::string StringPrintf(const char* format, ...) { | 1079 std::string StringPrintf(const char* format, ...) { |
996 va_list ap; | 1080 va_list ap; |
997 va_start(ap, format); | 1081 va_start(ap, format); |
998 std::string result; | 1082 std::string result; |
999 StringAppendV(&result, format, ap); | 1083 StringAppendV(&result, format, ap); |
1000 va_end(ap); | 1084 va_end(ap); |
1001 return result; | 1085 return result; |
1002 } | 1086 } |
1003 | 1087 |
1004 std::wstring StringPrintf(const wchar_t* format, ...) { | 1088 std::wstring StringPrintf(const wchar_t* format, ...) { |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 } | 1408 } |
1325 | 1409 |
1326 // For the various *ToInt conversions, there are no *ToIntTraits classes to use | 1410 // For the various *ToInt conversions, there are no *ToIntTraits classes to use |
1327 // because there's no such thing as strtoi. Use *ToLongTraits through a cast | 1411 // because there's no such thing as strtoi. Use *ToLongTraits through a cast |
1328 // instead, requiring that long and int are compatible and equal-width. They | 1412 // instead, requiring that long and int are compatible and equal-width. They |
1329 // are on our target platforms. | 1413 // are on our target platforms. |
1330 | 1414 |
1331 bool StringToInt(const std::string& input, int* output) { | 1415 bool StringToInt(const std::string& input, int* output) { |
1332 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1416 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); |
1333 return StringToNumber<StringToLongTraits>(input, | 1417 return StringToNumber<StringToLongTraits>(input, |
1334 reinterpret_cast<long*>(output)); | 1418 reinterpret_cast<long*>(output), |
| 1419 base::LOCALE_DEPENDENT); |
1335 } | 1420 } |
1336 | 1421 |
1337 bool StringToInt(const std::wstring& input, int* output) { | 1422 bool StringToInt(const std::wstring& input, int* output) { |
1338 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1423 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); |
1339 return StringToNumber<WStringToLongTraits>(input, | 1424 return StringToNumber<WStringToLongTraits>(input, |
1340 reinterpret_cast<long*>(output)); | 1425 reinterpret_cast<long*>(output), |
| 1426 base::LOCALE_DEPENDENT); |
1341 } | 1427 } |
1342 | 1428 |
1343 bool StringToInt64(const std::string& input, int64* output) { | 1429 bool StringToInt64(const std::string& input, int64* output) { |
1344 return StringToNumber<StringToInt64Traits>(input, output); | 1430 return StringToNumber<StringToInt64Traits>(input, output, base::LOCALE_DEPENDE
NT); |
1345 } | 1431 } |
1346 | 1432 |
1347 bool StringToInt64(const std::wstring& input, int64* output) { | 1433 bool StringToInt64(const std::wstring& input, int64* output) { |
1348 return StringToNumber<WStringToInt64Traits>(input, output); | 1434 return StringToNumber<WStringToInt64Traits>(input, output, base::LOCALE_DEPEND
ENT); |
1349 } | 1435 } |
1350 | 1436 |
1351 bool HexStringToInt(const std::string& input, int* output) { | 1437 bool HexStringToInt(const std::string& input, int* output) { |
1352 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1438 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); |
1353 return StringToNumber<HexStringToLongTraits>(input, | 1439 return StringToNumber<HexStringToLongTraits>(input, |
1354 reinterpret_cast<long*>(output)); | 1440 reinterpret_cast<long*>(output), |
| 1441 base::LOCALE_DEPENDENT); |
1355 } | 1442 } |
1356 | 1443 |
1357 bool HexStringToInt(const std::wstring& input, int* output) { | 1444 bool HexStringToInt(const std::wstring& input, int* output) { |
1358 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1445 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); |
1359 return StringToNumber<HexWStringToLongTraits>( | 1446 return StringToNumber<HexWStringToLongTraits>( |
1360 input, reinterpret_cast<long*>(output)); | 1447 input, reinterpret_cast<long*>(output), base::LOCALE_DEPENDENT); |
1361 } | |
1362 | |
1363 bool StringToDouble(const std::string& input, double* output) { | |
1364 return StringToNumber<StringToDoubleTraits>(input, output); | |
1365 } | |
1366 | |
1367 bool StringToDouble(const std::wstring& input, double* output) { | |
1368 return StringToNumber<WStringToDoubleTraits>(input, output); | |
1369 } | 1448 } |
1370 | 1449 |
1371 int StringToInt(const std::string& value) { | 1450 int StringToInt(const std::string& value) { |
1372 int result; | 1451 int result; |
1373 StringToInt(value, &result); | 1452 StringToInt(value, &result); |
1374 return result; | 1453 return result; |
1375 } | 1454 } |
1376 | 1455 |
1377 int StringToInt(const std::wstring& value) { | 1456 int StringToInt(const std::wstring& value) { |
1378 int result; | 1457 int result; |
(...skipping 18 matching lines...) Expand all Loading... |
1397 HexStringToInt(value, &result); | 1476 HexStringToInt(value, &result); |
1398 return result; | 1477 return result; |
1399 } | 1478 } |
1400 | 1479 |
1401 int HexStringToInt(const std::wstring& value) { | 1480 int HexStringToInt(const std::wstring& value) { |
1402 int result; | 1481 int result; |
1403 HexStringToInt(value, &result); | 1482 HexStringToInt(value, &result); |
1404 return result; | 1483 return result; |
1405 } | 1484 } |
1406 | 1485 |
1407 double StringToDouble(const std::string& value) { | |
1408 double result; | |
1409 StringToDouble(value, &result); | |
1410 return result; | |
1411 } | |
1412 | |
1413 double StringToDouble(const std::wstring& value) { | |
1414 double result; | |
1415 StringToDouble(value, &result); | |
1416 return result; | |
1417 } | |
1418 | |
1419 // The following code is compatible with the OpenBSD lcpy interface. See: | 1486 // The following code is compatible with the OpenBSD lcpy interface. See: |
1420 // http://www.gratisoft.us/todd/papers/strlcpy.html | 1487 // http://www.gratisoft.us/todd/papers/strlcpy.html |
1421 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c | 1488 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c |
1422 | 1489 |
1423 namespace { | 1490 namespace { |
1424 | 1491 |
1425 template <typename CHAR> | 1492 template <typename CHAR> |
1426 size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) { | 1493 size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) { |
1427 for (size_t i = 0; i < dst_size; ++i) { | 1494 for (size_t i = 0; i < dst_size; ++i) { |
1428 if ((dst[i] = src[i]) == 0) // We hit and copied the terminating NULL. | 1495 if ((dst[i] = src[i]) == 0) // We hit and copied the terminating NULL. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 int rstr_len = (max_len - 3) / 2; | 1543 int rstr_len = (max_len - 3) / 2; |
1477 int lstr_len = rstr_len + ((max_len - 3) % 2); | 1544 int lstr_len = rstr_len + ((max_len - 3) % 2); |
1478 output->assign(input.substr(0, lstr_len) + L"..." + | 1545 output->assign(input.substr(0, lstr_len) + L"..." + |
1479 input.substr(input.length() - rstr_len)); | 1546 input.substr(input.length() - rstr_len)); |
1480 break; | 1547 break; |
1481 } | 1548 } |
1482 } | 1549 } |
1483 | 1550 |
1484 return true; | 1551 return true; |
1485 } | 1552 } |
OLD | NEW |