PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/external/chromium_org/base/strings/string_number_conversions.cc

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