OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_number_conversions.h" | 5 #include "base/string_number_conversions.h" |
6 | 6 |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <wctype.h> | 10 #include <wctype.h> |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 typedef VALUE value_type; | 285 typedef VALUE value_type; |
286 static value_type min() { | 286 static value_type min() { |
287 return std::numeric_limits<value_type>::min(); | 287 return std::numeric_limits<value_type>::min(); |
288 } | 288 } |
289 static value_type max() { | 289 static value_type max() { |
290 return std::numeric_limits<value_type>::max(); | 290 return std::numeric_limits<value_type>::max(); |
291 } | 291 } |
292 static const int kBase = BASE; | 292 static const int kBase = BASE; |
293 }; | 293 }; |
294 | 294 |
295 typedef BaseIteratorRangeToNumberTraits<std::string::const_iterator, int, 10> | |
296 IteratorRangeToIntTraits; | |
297 typedef BaseIteratorRangeToNumberTraits<string16::const_iterator, int, 10> | |
298 WideIteratorRangeToIntTraits; | |
299 typedef BaseIteratorRangeToNumberTraits<std::string::const_iterator, int64, 10> | |
300 IteratorRangeToInt64Traits; | |
301 typedef BaseIteratorRangeToNumberTraits<string16::const_iterator, int64, 10> | |
302 WideIteratorRangeToInt64Traits; | |
303 | |
304 typedef BaseIteratorRangeToNumberTraits<const char*, int, 10> | |
305 CharBufferToIntTraits; | |
306 typedef BaseIteratorRangeToNumberTraits<const char16*, int, 10> | |
307 WideCharBufferToIntTraits; | |
308 typedef BaseIteratorRangeToNumberTraits<const char*, int64, 10> | |
309 CharBufferToInt64Traits; | |
310 typedef BaseIteratorRangeToNumberTraits<const char16*, int64, 10> | |
311 WideCharBufferToInt64Traits; | |
312 | |
313 template<typename ITERATOR> | 295 template<typename ITERATOR> |
314 class BaseHexIteratorRangeToIntTraits | 296 class BaseHexIteratorRangeToIntTraits |
315 : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { | 297 : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { |
316 public: | 298 public: |
317 // Allow parsing of 0xFFFFFFFF, which is technically an overflow | 299 // Allow parsing of 0xFFFFFFFF, which is technically an overflow |
318 static unsigned int max() { | 300 static unsigned int max() { |
319 return std::numeric_limits<unsigned int>::max(); | 301 return std::numeric_limits<unsigned int>::max(); |
320 } | 302 } |
321 }; | 303 }; |
322 | 304 |
323 typedef BaseHexIteratorRangeToIntTraits<std::string::const_iterator> | 305 typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator> |
324 HexIteratorRangeToIntTraits; | 306 HexIteratorRangeToIntTraits; |
325 typedef BaseHexIteratorRangeToIntTraits<const char*> | |
326 HexCharBufferToIntTraits; | |
327 | 307 |
328 template<typename STR> | 308 template<typename STR> |
329 bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) { | 309 bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) { |
330 DCHECK_EQ(output->size(), 0u); | 310 DCHECK_EQ(output->size(), 0u); |
331 size_t count = input.size(); | 311 size_t count = input.size(); |
332 if (count == 0 || (count % 2) != 0) | 312 if (count == 0 || (count % 2) != 0) |
333 return false; | 313 return false; |
334 for (uintptr_t i = 0; i < count / 2; ++i) { | 314 for (uintptr_t i = 0; i < count / 2; ++i) { |
335 uint8 msb = 0; // most significant 4 bits | 315 uint8 msb = 0; // most significant 4 bits |
336 uint8 lsb = 0; // least significant 4 bits | 316 uint8 lsb = 0; // least significant 4 bits |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 IntToString(value); | 363 IntToString(value); |
384 } | 364 } |
385 | 365 |
386 std::string DoubleToString(double value) { | 366 std::string DoubleToString(double value) { |
387 // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. | 367 // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. |
388 char buffer[32]; | 368 char buffer[32]; |
389 dmg_fp::g_fmt(buffer, value); | 369 dmg_fp::g_fmt(buffer, value); |
390 return std::string(buffer); | 370 return std::string(buffer); |
391 } | 371 } |
392 | 372 |
393 bool StringToInt(const std::string& input, int* output) { | 373 namespace { |
394 return IteratorRangeToNumber<IteratorRangeToIntTraits>::Invoke(input.begin(), | 374 |
395 input.end(), | 375 template <typename VALUE, int BASE> |
396 output); | 376 class StringPieceToNumberTraits |
377 : public BaseIteratorRangeToNumberTraits<StringPiece::const_iterator, | |
378 VALUE, BASE> | |
erikwright (departed)
2011/12/14 05:29:57
Sorry, didn't look closely enough at this.
BASE s
| |
379 {}; | |
380 | |
381 template <typename VALUE> | |
382 bool StringToIntImpl(const StringPiece& input, VALUE* output) { | |
383 return IteratorRangeToNumber<StringPieceToNumberTraits<VALUE, 10> >::Invoke( | |
384 input.begin(), input.end(), output); | |
397 } | 385 } |
398 | 386 |
399 bool StringToInt(std::string::const_iterator begin, | 387 template <typename VALUE, int BASE> |
400 std::string::const_iterator end, | 388 class StringPiece16ToNumberTraits |
401 int* output) { | 389 : public BaseIteratorRangeToNumberTraits<StringPiece16::const_iterator, |
402 return IteratorRangeToNumber<IteratorRangeToIntTraits>::Invoke(begin, | 390 VALUE, BASE> |
erikwright (departed)
2011/12/14 05:29:57
Same.
| |
403 end, | 391 {}; |
404 output); | 392 |
393 template <typename VALUE> | |
394 bool String16ToIntImpl(const StringPiece16& input, VALUE* output) { | |
395 return IteratorRangeToNumber<StringPiece16ToNumberTraits<VALUE, 10> >::Invoke( | |
396 input.begin(), input.end(), output); | |
405 } | 397 } |
406 | 398 |
407 #if !defined(STD_STRING_ITERATOR_IS_CHAR_POINTER) | 399 } // namespace |
408 bool StringToInt(const char* begin, const char* end, int* output) { | |
409 return IteratorRangeToNumber<CharBufferToIntTraits>::Invoke(begin, | |
410 end, | |
411 output); | |
412 } | |
413 #endif | |
414 | 400 |
415 bool StringToInt(const string16& input, int* output) { | 401 bool StringToInt(const StringPiece& input, int* output) { |
416 return IteratorRangeToNumber<WideIteratorRangeToIntTraits>::Invoke( | 402 return StringToIntImpl(input, output); |
417 input.begin(), input.end(), output); | |
418 } | 403 } |
419 | 404 |
420 bool StringToInt(string16::const_iterator begin, | 405 bool StringToInt(const StringPiece16& input, int* output) { |
421 string16::const_iterator end, | 406 return String16ToIntImpl(input, output); |
422 int* output) { | |
423 return IteratorRangeToNumber<WideIteratorRangeToIntTraits>::Invoke(begin, | |
424 end, | |
425 output); | |
426 } | 407 } |
427 | 408 |
428 #if !defined(BASE_STRING16_ITERATOR_IS_CHAR16_POINTER) | 409 bool StringToInt64(const StringPiece& input, int64* output) { |
429 bool StringToInt(const char16* begin, const char16* end, int* output) { | 410 return StringToIntImpl(input, output); |
430 return IteratorRangeToNumber<WideCharBufferToIntTraits>::Invoke(begin, | |
431 end, | |
432 output); | |
433 } | |
434 #endif | |
435 | |
436 bool StringToInt64(const std::string& input, int64* output) { | |
437 return IteratorRangeToNumber<IteratorRangeToInt64Traits>::Invoke( | |
438 input.begin(), input.end(), output); | |
439 } | 411 } |
440 | 412 |
441 bool StringToInt64(std::string::const_iterator begin, | 413 bool StringToInt64(const StringPiece16& input, int64* output) { |
442 std::string::const_iterator end, | 414 return String16ToIntImpl(input, output); |
443 int64* output) { | |
444 return IteratorRangeToNumber<IteratorRangeToInt64Traits>::Invoke(begin, | |
445 end, | |
446 output); | |
447 } | 415 } |
448 | 416 |
449 #if !defined(STD_STRING_ITERATOR_IS_CHAR_POINTER) | |
450 bool StringToInt64(const char* begin, const char* end, int64* output) { | |
451 return IteratorRangeToNumber<CharBufferToInt64Traits>::Invoke(begin, | |
452 end, | |
453 output); | |
454 } | |
455 #endif | |
456 | |
457 bool StringToInt64(const string16& input, int64* output) { | |
458 return IteratorRangeToNumber<WideIteratorRangeToInt64Traits>::Invoke( | |
459 input.begin(), input.end(), output); | |
460 } | |
461 | |
462 bool StringToInt64(string16::const_iterator begin, | |
463 string16::const_iterator end, | |
464 int64* output) { | |
465 return IteratorRangeToNumber<WideIteratorRangeToInt64Traits>::Invoke(begin, | |
466 end, | |
467 output); | |
468 } | |
469 | |
470 #if !defined(BASE_STRING16_ITERATOR_IS_CHAR16_POINTER) | |
471 bool StringToInt64(const char16* begin, const char16* end, int64* output) { | |
472 return IteratorRangeToNumber<WideCharBufferToInt64Traits>::Invoke(begin, | |
473 end, | |
474 output); | |
475 } | |
476 #endif | |
477 | |
478 bool StringToDouble(const std::string& input, double* output) { | 417 bool StringToDouble(const std::string& input, double* output) { |
479 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. | 418 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. |
480 char* endptr = NULL; | 419 char* endptr = NULL; |
481 *output = dmg_fp::strtod(input.c_str(), &endptr); | 420 *output = dmg_fp::strtod(input.c_str(), &endptr); |
482 | 421 |
483 // Cases to return false: | 422 // Cases to return false: |
484 // - If errno is ERANGE, there was an overflow or underflow. | 423 // - If errno is ERANGE, there was an overflow or underflow. |
485 // - If the input string is empty, there was nothing to parse. | 424 // - If the input string is empty, there was nothing to parse. |
486 // - If endptr does not point to the end of the string, there are either | 425 // - If endptr does not point to the end of the string, there are either |
487 // characters remaining in the string after a parsed number, or the string | 426 // characters remaining in the string after a parsed number, or the string |
(...skipping 22 matching lines...) Expand all Loading... | |
510 std::string ret(size * 2, '\0'); | 449 std::string ret(size * 2, '\0'); |
511 | 450 |
512 for (size_t i = 0; i < size; ++i) { | 451 for (size_t i = 0; i < size; ++i) { |
513 char b = reinterpret_cast<const char*>(bytes)[i]; | 452 char b = reinterpret_cast<const char*>(bytes)[i]; |
514 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; | 453 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; |
515 ret[(i * 2) + 1] = kHexChars[b & 0xf]; | 454 ret[(i * 2) + 1] = kHexChars[b & 0xf]; |
516 } | 455 } |
517 return ret; | 456 return ret; |
518 } | 457 } |
519 | 458 |
520 bool HexStringToInt(const std::string& input, int* output) { | 459 bool HexStringToInt(const StringPiece& input, int* output) { |
521 return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke( | 460 return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke( |
522 input.begin(), input.end(), output); | 461 input.begin(), input.end(), output); |
523 } | 462 } |
524 | 463 |
525 bool HexStringToInt(std::string::const_iterator begin, | |
526 std::string::const_iterator end, | |
527 int* output) { | |
528 return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke(begin, | |
529 end, | |
530 output); | |
531 } | |
532 | |
533 #if !defined(STD_STRING_ITERATOR_IS_CHAR_POINTER) | |
534 bool HexStringToInt(const char* begin, const char* end, int* output) { | |
535 return IteratorRangeToNumber<HexCharBufferToIntTraits>::Invoke(begin, | |
536 end, | |
537 output); | |
538 } | |
539 #endif | |
540 | |
541 bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { | 464 bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { |
542 return HexStringToBytesT(input, output); | 465 return HexStringToBytesT(input, output); |
543 } | 466 } |
544 | 467 |
545 } // namespace base | 468 } // namespace base |
OLD | NEW |