| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/strings/string_number_conversions.h" | |
| 6 | |
| 7 #include <ctype.h> | |
| 8 #include <errno.h> | |
| 9 #include <stdlib.h> | |
| 10 #include <wctype.h> | |
| 11 | |
| 12 #include <limits> | |
| 13 | |
| 14 #include "base/logging.h" | |
| 15 #include "base/scoped_clear_errno.h" | |
| 16 #include "base/strings/utf_string_conversions.h" | |
| 17 #include "base/third_party/dmg_fp/dmg_fp.h" | |
| 18 | |
| 19 namespace base { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 template <typename STR, typename INT, typename UINT, bool NEG> | |
| 24 struct IntToStringT { | |
| 25 // This is to avoid a compiler warning about unary minus on unsigned type. | |
| 26 // For example, say you had the following code: | |
| 27 // template <typename INT> | |
| 28 // INT abs(INT value) { return value < 0 ? -value : value; } | |
| 29 // Even though if INT is unsigned, it's impossible for value < 0, so the | |
| 30 // unary minus will never be taken, the compiler will still generate a | |
| 31 // warning. We do a little specialization dance... | |
| 32 template <typename INT2, typename UINT2, bool NEG2> | |
| 33 struct ToUnsignedT {}; | |
| 34 | |
| 35 template <typename INT2, typename UINT2> | |
| 36 struct ToUnsignedT<INT2, UINT2, false> { | |
| 37 static UINT2 ToUnsigned(INT2 value) { | |
| 38 return static_cast<UINT2>(value); | |
| 39 } | |
| 40 }; | |
| 41 | |
| 42 template <typename INT2, typename UINT2> | |
| 43 struct ToUnsignedT<INT2, UINT2, true> { | |
| 44 static UINT2 ToUnsigned(INT2 value) { | |
| 45 if (value >= 0) { | |
| 46 return value; | |
| 47 } else { | |
| 48 // Avoid integer overflow when negating INT_MIN. | |
| 49 return static_cast<UINT2>(-(value + 1)) + 1; | |
| 50 } | |
| 51 } | |
| 52 }; | |
| 53 | |
| 54 // This set of templates is very similar to the above templates, but | |
| 55 // for testing whether an integer is negative. | |
| 56 template <typename INT2, bool NEG2> | |
| 57 struct TestNegT {}; | |
| 58 template <typename INT2> | |
| 59 struct TestNegT<INT2, false> { | |
| 60 static bool TestNeg(INT2 value) { | |
| 61 // value is unsigned, and can never be negative. | |
| 62 return false; | |
| 63 } | |
| 64 }; | |
| 65 template <typename INT2> | |
| 66 struct TestNegT<INT2, true> { | |
| 67 static bool TestNeg(INT2 value) { | |
| 68 return value < 0; | |
| 69 } | |
| 70 }; | |
| 71 | |
| 72 static STR IntToString(INT value) { | |
| 73 // log10(2) ~= 0.3 bytes needed per bit or per byte log10(2**8) ~= 2.4. | |
| 74 // So round up to allocate 3 output characters per byte, plus 1 for '-'. | |
| 75 const int kOutputBufSize = 3 * sizeof(INT) + 1; | |
| 76 | |
| 77 // Allocate the whole string right away, we will right back to front, and | |
| 78 // then return the substr of what we ended up using. | |
| 79 STR outbuf(kOutputBufSize, 0); | |
| 80 | |
| 81 bool is_neg = TestNegT<INT, NEG>::TestNeg(value); | |
| 82 // Even though is_neg will never be true when INT is parameterized as | |
| 83 // unsigned, even the presence of the unary operation causes a warning. | |
| 84 UINT res = ToUnsignedT<INT, UINT, NEG>::ToUnsigned(value); | |
| 85 | |
| 86 typename STR::iterator it(outbuf.end()); | |
| 87 do { | |
| 88 --it; | |
| 89 DCHECK(it != outbuf.begin()); | |
| 90 *it = static_cast<typename STR::value_type>((res % 10) + '0'); | |
| 91 res /= 10; | |
| 92 } while (res != 0); | |
| 93 if (is_neg) { | |
| 94 --it; | |
| 95 DCHECK(it != outbuf.begin()); | |
| 96 *it = static_cast<typename STR::value_type>('-'); | |
| 97 } | |
| 98 return STR(it, outbuf.end()); | |
| 99 } | |
| 100 }; | |
| 101 | |
| 102 // Utility to convert a character to a digit in a given base | |
| 103 template<typename CHAR, int BASE, bool BASE_LTE_10> class BaseCharToDigit { | |
| 104 }; | |
| 105 | |
| 106 // Faster specialization for bases <= 10 | |
| 107 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> { | |
| 108 public: | |
| 109 static bool Convert(CHAR c, uint8* digit) { | |
| 110 if (c >= '0' && c < '0' + BASE) { | |
| 111 *digit = static_cast<uint8>(c - '0'); | |
| 112 return true; | |
| 113 } | |
| 114 return false; | |
| 115 } | |
| 116 }; | |
| 117 | |
| 118 // Specialization for bases where 10 < base <= 36 | |
| 119 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> { | |
| 120 public: | |
| 121 static bool Convert(CHAR c, uint8* digit) { | |
| 122 if (c >= '0' && c <= '9') { | |
| 123 *digit = c - '0'; | |
| 124 } else if (c >= 'a' && c < 'a' + BASE - 10) { | |
| 125 *digit = c - 'a' + 10; | |
| 126 } else if (c >= 'A' && c < 'A' + BASE - 10) { | |
| 127 *digit = c - 'A' + 10; | |
| 128 } else { | |
| 129 return false; | |
| 130 } | |
| 131 return true; | |
| 132 } | |
| 133 }; | |
| 134 | |
| 135 template<int BASE, typename CHAR> bool CharToDigit(CHAR c, uint8* digit) { | |
| 136 return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit); | |
| 137 } | |
| 138 | |
| 139 // There is an IsUnicodeWhitespace for wchars defined in string_util.h, but it | |
| 140 // is locale independent, whereas the functions we are replacing were | |
| 141 // locale-dependent. TBD what is desired, but for the moment let's not | |
| 142 // introduce a change in behaviour. | |
| 143 template<typename CHAR> class WhitespaceHelper { | |
| 144 }; | |
| 145 | |
| 146 template<> class WhitespaceHelper<char> { | |
| 147 public: | |
| 148 static bool Invoke(char c) { | |
| 149 return 0 != isspace(static_cast<unsigned char>(c)); | |
| 150 } | |
| 151 }; | |
| 152 | |
| 153 template<> class WhitespaceHelper<char16> { | |
| 154 public: | |
| 155 static bool Invoke(char16 c) { | |
| 156 return 0 != iswspace(c); | |
| 157 } | |
| 158 }; | |
| 159 | |
| 160 template<typename CHAR> bool LocalIsWhitespace(CHAR c) { | |
| 161 return WhitespaceHelper<CHAR>::Invoke(c); | |
| 162 } | |
| 163 | |
| 164 // IteratorRangeToNumberTraits should provide: | |
| 165 // - a typedef for iterator_type, the iterator type used as input. | |
| 166 // - a typedef for value_type, the target numeric type. | |
| 167 // - static functions min, max (returning the minimum and maximum permitted | |
| 168 // values) | |
| 169 // - constant kBase, the base in which to interpret the input | |
| 170 template<typename IteratorRangeToNumberTraits> | |
| 171 class IteratorRangeToNumber { | |
| 172 public: | |
| 173 typedef IteratorRangeToNumberTraits traits; | |
| 174 typedef typename traits::iterator_type const_iterator; | |
| 175 typedef typename traits::value_type value_type; | |
| 176 | |
| 177 // Generalized iterator-range-to-number conversion. | |
| 178 // | |
| 179 static bool Invoke(const_iterator begin, | |
| 180 const_iterator end, | |
| 181 value_type* output) { | |
| 182 bool valid = true; | |
| 183 | |
| 184 while (begin != end && LocalIsWhitespace(*begin)) { | |
| 185 valid = false; | |
| 186 ++begin; | |
| 187 } | |
| 188 | |
| 189 if (begin != end && *begin == '-') { | |
| 190 if (!std::numeric_limits<value_type>::is_signed) { | |
| 191 valid = false; | |
| 192 } else if (!Negative::Invoke(begin + 1, end, output)) { | |
| 193 valid = false; | |
| 194 } | |
| 195 } else { | |
| 196 if (begin != end && *begin == '+') { | |
| 197 ++begin; | |
| 198 } | |
| 199 if (!Positive::Invoke(begin, end, output)) { | |
| 200 valid = false; | |
| 201 } | |
| 202 } | |
| 203 | |
| 204 return valid; | |
| 205 } | |
| 206 | |
| 207 private: | |
| 208 // Sign provides: | |
| 209 // - a static function, CheckBounds, that determines whether the next digit | |
| 210 // causes an overflow/underflow | |
| 211 // - a static function, Increment, that appends the next digit appropriately | |
| 212 // according to the sign of the number being parsed. | |
| 213 template<typename Sign> | |
| 214 class Base { | |
| 215 public: | |
| 216 static bool Invoke(const_iterator begin, const_iterator end, | |
| 217 typename traits::value_type* output) { | |
| 218 *output = 0; | |
| 219 | |
| 220 if (begin == end) { | |
| 221 return false; | |
| 222 } | |
| 223 | |
| 224 // Note: no performance difference was found when using template | |
| 225 // specialization to remove this check in bases other than 16 | |
| 226 if (traits::kBase == 16 && end - begin > 2 && *begin == '0' && | |
| 227 (*(begin + 1) == 'x' || *(begin + 1) == 'X')) { | |
| 228 begin += 2; | |
| 229 } | |
| 230 | |
| 231 for (const_iterator current = begin; current != end; ++current) { | |
| 232 uint8 new_digit = 0; | |
| 233 | |
| 234 if (!CharToDigit<traits::kBase>(*current, &new_digit)) { | |
| 235 return false; | |
| 236 } | |
| 237 | |
| 238 if (current != begin) { | |
| 239 if (!Sign::CheckBounds(output, new_digit)) { | |
| 240 return false; | |
| 241 } | |
| 242 *output *= traits::kBase; | |
| 243 } | |
| 244 | |
| 245 Sign::Increment(new_digit, output); | |
| 246 } | |
| 247 return true; | |
| 248 } | |
| 249 }; | |
| 250 | |
| 251 class Positive : public Base<Positive> { | |
| 252 public: | |
| 253 static bool CheckBounds(value_type* output, uint8 new_digit) { | |
| 254 if (*output > static_cast<value_type>(traits::max() / traits::kBase) || | |
| 255 (*output == static_cast<value_type>(traits::max() / traits::kBase) && | |
| 256 new_digit > traits::max() % traits::kBase)) { | |
| 257 *output = traits::max(); | |
| 258 return false; | |
| 259 } | |
| 260 return true; | |
| 261 } | |
| 262 static void Increment(uint8 increment, value_type* output) { | |
| 263 *output += increment; | |
| 264 } | |
| 265 }; | |
| 266 | |
| 267 class Negative : public Base<Negative> { | |
| 268 public: | |
| 269 static bool CheckBounds(value_type* output, uint8 new_digit) { | |
| 270 if (*output < traits::min() / traits::kBase || | |
| 271 (*output == traits::min() / traits::kBase && | |
| 272 new_digit > 0 - traits::min() % traits::kBase)) { | |
| 273 *output = traits::min(); | |
| 274 return false; | |
| 275 } | |
| 276 return true; | |
| 277 } | |
| 278 static void Increment(uint8 increment, value_type* output) { | |
| 279 *output -= increment; | |
| 280 } | |
| 281 }; | |
| 282 }; | |
| 283 | |
| 284 template<typename ITERATOR, typename VALUE, int BASE> | |
| 285 class BaseIteratorRangeToNumberTraits { | |
| 286 public: | |
| 287 typedef ITERATOR iterator_type; | |
| 288 typedef VALUE value_type; | |
| 289 static value_type min() { | |
| 290 return std::numeric_limits<value_type>::min(); | |
| 291 } | |
| 292 static value_type max() { | |
| 293 return std::numeric_limits<value_type>::max(); | |
| 294 } | |
| 295 static const int kBase = BASE; | |
| 296 }; | |
| 297 | |
| 298 template<typename ITERATOR> | |
| 299 class BaseHexIteratorRangeToIntTraits | |
| 300 : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { | |
| 301 }; | |
| 302 | |
| 303 template<typename ITERATOR> | |
| 304 class BaseHexIteratorRangeToUIntTraits | |
| 305 : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32, 16> { | |
| 306 }; | |
| 307 | |
| 308 template<typename ITERATOR> | |
| 309 class BaseHexIteratorRangeToInt64Traits | |
| 310 : public BaseIteratorRangeToNumberTraits<ITERATOR, int64, 16> { | |
| 311 }; | |
| 312 | |
| 313 template<typename ITERATOR> | |
| 314 class BaseHexIteratorRangeToUInt64Traits | |
| 315 : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64, 16> { | |
| 316 }; | |
| 317 | |
| 318 typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator> | |
| 319 HexIteratorRangeToIntTraits; | |
| 320 | |
| 321 typedef BaseHexIteratorRangeToUIntTraits<StringPiece::const_iterator> | |
| 322 HexIteratorRangeToUIntTraits; | |
| 323 | |
| 324 typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator> | |
| 325 HexIteratorRangeToInt64Traits; | |
| 326 | |
| 327 typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator> | |
| 328 HexIteratorRangeToUInt64Traits; | |
| 329 | |
| 330 template<typename STR> | |
| 331 bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) { | |
| 332 DCHECK_EQ(output->size(), 0u); | |
| 333 size_t count = input.size(); | |
| 334 if (count == 0 || (count % 2) != 0) | |
| 335 return false; | |
| 336 for (uintptr_t i = 0; i < count / 2; ++i) { | |
| 337 uint8 msb = 0; // most significant 4 bits | |
| 338 uint8 lsb = 0; // least significant 4 bits | |
| 339 if (!CharToDigit<16>(input[i * 2], &msb) || | |
| 340 !CharToDigit<16>(input[i * 2 + 1], &lsb)) | |
| 341 return false; | |
| 342 output->push_back((msb << 4) | lsb); | |
| 343 } | |
| 344 return true; | |
| 345 } | |
| 346 | |
| 347 template <typename VALUE, int BASE> | |
| 348 class StringPieceToNumberTraits | |
| 349 : public BaseIteratorRangeToNumberTraits<StringPiece::const_iterator, | |
| 350 VALUE, | |
| 351 BASE> { | |
| 352 }; | |
| 353 | |
| 354 template <typename VALUE> | |
| 355 bool StringToIntImpl(const StringPiece& input, VALUE* output) { | |
| 356 return IteratorRangeToNumber<StringPieceToNumberTraits<VALUE, 10> >::Invoke( | |
| 357 input.begin(), input.end(), output); | |
| 358 } | |
| 359 | |
| 360 template <typename VALUE, int BASE> | |
| 361 class StringPiece16ToNumberTraits | |
| 362 : public BaseIteratorRangeToNumberTraits<StringPiece16::const_iterator, | |
| 363 VALUE, | |
| 364 BASE> { | |
| 365 }; | |
| 366 | |
| 367 template <typename VALUE> | |
| 368 bool String16ToIntImpl(const StringPiece16& input, VALUE* output) { | |
| 369 return IteratorRangeToNumber<StringPiece16ToNumberTraits<VALUE, 10> >::Invoke( | |
| 370 input.begin(), input.end(), output); | |
| 371 } | |
| 372 | |
| 373 } // namespace | |
| 374 | |
| 375 std::string IntToString(int value) { | |
| 376 return IntToStringT<std::string, int, unsigned int, true>:: | |
| 377 IntToString(value); | |
| 378 } | |
| 379 | |
| 380 string16 IntToString16(int value) { | |
| 381 return IntToStringT<string16, int, unsigned int, true>:: | |
| 382 IntToString(value); | |
| 383 } | |
| 384 | |
| 385 std::string UintToString(unsigned int value) { | |
| 386 return IntToStringT<std::string, unsigned int, unsigned int, false>:: | |
| 387 IntToString(value); | |
| 388 } | |
| 389 | |
| 390 string16 UintToString16(unsigned int value) { | |
| 391 return IntToStringT<string16, unsigned int, unsigned int, false>:: | |
| 392 IntToString(value); | |
| 393 } | |
| 394 | |
| 395 std::string Int64ToString(int64 value) { | |
| 396 return IntToStringT<std::string, int64, uint64, true>::IntToString(value); | |
| 397 } | |
| 398 | |
| 399 string16 Int64ToString16(int64 value) { | |
| 400 return IntToStringT<string16, int64, uint64, true>::IntToString(value); | |
| 401 } | |
| 402 | |
| 403 std::string Uint64ToString(uint64 value) { | |
| 404 return IntToStringT<std::string, uint64, uint64, false>::IntToString(value); | |
| 405 } | |
| 406 | |
| 407 string16 Uint64ToString16(uint64 value) { | |
| 408 return IntToStringT<string16, uint64, uint64, false>::IntToString(value); | |
| 409 } | |
| 410 | |
| 411 std::string SizeTToString(size_t value) { | |
| 412 return IntToStringT<std::string, size_t, size_t, false>::IntToString(value); | |
| 413 } | |
| 414 | |
| 415 string16 SizeTToString16(size_t value) { | |
| 416 return IntToStringT<string16, size_t, size_t, false>::IntToString(value); | |
| 417 } | |
| 418 | |
| 419 std::string DoubleToString(double value) { | |
| 420 // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. | |
| 421 char buffer[32]; | |
| 422 dmg_fp::g_fmt(buffer, value); | |
| 423 return std::string(buffer); | |
| 424 } | |
| 425 | |
| 426 bool StringToInt(const StringPiece& input, int* output) { | |
| 427 return StringToIntImpl(input, output); | |
| 428 } | |
| 429 | |
| 430 bool StringToInt(const StringPiece16& input, int* output) { | |
| 431 return String16ToIntImpl(input, output); | |
| 432 } | |
| 433 | |
| 434 bool StringToUint(const StringPiece& input, unsigned* output) { | |
| 435 return StringToIntImpl(input, output); | |
| 436 } | |
| 437 | |
| 438 bool StringToUint(const StringPiece16& input, unsigned* output) { | |
| 439 return String16ToIntImpl(input, output); | |
| 440 } | |
| 441 | |
| 442 bool StringToInt64(const StringPiece& input, int64* output) { | |
| 443 return StringToIntImpl(input, output); | |
| 444 } | |
| 445 | |
| 446 bool StringToInt64(const StringPiece16& input, int64* output) { | |
| 447 return String16ToIntImpl(input, output); | |
| 448 } | |
| 449 | |
| 450 bool StringToUint64(const StringPiece& input, uint64* output) { | |
| 451 return StringToIntImpl(input, output); | |
| 452 } | |
| 453 | |
| 454 bool StringToUint64(const StringPiece16& input, uint64* output) { | |
| 455 return String16ToIntImpl(input, output); | |
| 456 } | |
| 457 | |
| 458 bool StringToSizeT(const StringPiece& input, size_t* output) { | |
| 459 return StringToIntImpl(input, output); | |
| 460 } | |
| 461 | |
| 462 bool StringToSizeT(const StringPiece16& input, size_t* output) { | |
| 463 return String16ToIntImpl(input, output); | |
| 464 } | |
| 465 | |
| 466 bool StringToDouble(const std::string& input, double* output) { | |
| 467 // Thread-safe? It is on at least Mac, Linux, and Windows. | |
| 468 ScopedClearErrno clear_errno; | |
| 469 | |
| 470 char* endptr = NULL; | |
| 471 *output = dmg_fp::strtod(input.c_str(), &endptr); | |
| 472 | |
| 473 // Cases to return false: | |
| 474 // - If errno is ERANGE, there was an overflow or underflow. | |
| 475 // - If the input string is empty, there was nothing to parse. | |
| 476 // - If endptr does not point to the end of the string, there are either | |
| 477 // characters remaining in the string after a parsed number, or the string | |
| 478 // does not begin with a parseable number. endptr is compared to the | |
| 479 // expected end given the string's stated length to correctly catch cases | |
| 480 // where the string contains embedded NUL characters. | |
| 481 // - If the first character is a space, there was leading whitespace | |
| 482 return errno == 0 && | |
| 483 !input.empty() && | |
| 484 input.c_str() + input.length() == endptr && | |
| 485 !isspace(input[0]); | |
| 486 } | |
| 487 | |
| 488 // Note: if you need to add String16ToDouble, first ask yourself if it's | |
| 489 // really necessary. If it is, probably the best implementation here is to | |
| 490 // convert to 8-bit and then use the 8-bit version. | |
| 491 | |
| 492 // Note: if you need to add an iterator range version of StringToDouble, first | |
| 493 // ask yourself if it's really necessary. If it is, probably the best | |
| 494 // implementation here is to instantiate a string and use the string version. | |
| 495 | |
| 496 std::string HexEncode(const void* bytes, size_t size) { | |
| 497 static const char kHexChars[] = "0123456789ABCDEF"; | |
| 498 | |
| 499 // Each input byte creates two output hex characters. | |
| 500 std::string ret(size * 2, '\0'); | |
| 501 | |
| 502 for (size_t i = 0; i < size; ++i) { | |
| 503 char b = reinterpret_cast<const char*>(bytes)[i]; | |
| 504 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; | |
| 505 ret[(i * 2) + 1] = kHexChars[b & 0xf]; | |
| 506 } | |
| 507 return ret; | |
| 508 } | |
| 509 | |
| 510 bool HexStringToInt(const StringPiece& input, int* output) { | |
| 511 return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke( | |
| 512 input.begin(), input.end(), output); | |
| 513 } | |
| 514 | |
| 515 bool HexStringToUInt(const StringPiece& input, uint32* output) { | |
| 516 return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke( | |
| 517 input.begin(), input.end(), output); | |
| 518 } | |
| 519 | |
| 520 bool HexStringToInt64(const StringPiece& input, int64* output) { | |
| 521 return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke( | |
| 522 input.begin(), input.end(), output); | |
| 523 } | |
| 524 | |
| 525 bool HexStringToUInt64(const StringPiece& input, uint64* output) { | |
| 526 return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke( | |
| 527 input.begin(), input.end(), output); | |
| 528 } | |
| 529 | |
| 530 bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { | |
| 531 return HexStringToBytesT(input, output); | |
| 532 } | |
| 533 | |
| 534 } // namespace base | |
| OLD | NEW |