Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: base/strings/string_number_conversions.cc

Issue 1548993002: Switch to standard integer types in base/strings/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/strings/string_number_conversions.h" 5 #include "base/strings/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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 } 56 }
57 }; 57 };
58 58
59 // Utility to convert a character to a digit in a given base 59 // Utility to convert a character to a digit in a given base
60 template<typename CHAR, int BASE, bool BASE_LTE_10> class BaseCharToDigit { 60 template<typename CHAR, int BASE, bool BASE_LTE_10> class BaseCharToDigit {
61 }; 61 };
62 62
63 // Faster specialization for bases <= 10 63 // Faster specialization for bases <= 10
64 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> { 64 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> {
65 public: 65 public:
66 static bool Convert(CHAR c, uint8* digit) { 66 static bool Convert(CHAR c, uint8_t* digit) {
67 if (c >= '0' && c < '0' + BASE) { 67 if (c >= '0' && c < '0' + BASE) {
68 *digit = static_cast<uint8>(c - '0'); 68 *digit = static_cast<uint8_t>(c - '0');
69 return true; 69 return true;
70 } 70 }
71 return false; 71 return false;
72 } 72 }
73 }; 73 };
74 74
75 // Specialization for bases where 10 < base <= 36 75 // Specialization for bases where 10 < base <= 36
76 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> { 76 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> {
77 public: 77 public:
78 static bool Convert(CHAR c, uint8* digit) { 78 static bool Convert(CHAR c, uint8_t* digit) {
79 if (c >= '0' && c <= '9') { 79 if (c >= '0' && c <= '9') {
80 *digit = c - '0'; 80 *digit = c - '0';
81 } else if (c >= 'a' && c < 'a' + BASE - 10) { 81 } else if (c >= 'a' && c < 'a' + BASE - 10) {
82 *digit = c - 'a' + 10; 82 *digit = c - 'a' + 10;
83 } else if (c >= 'A' && c < 'A' + BASE - 10) { 83 } else if (c >= 'A' && c < 'A' + BASE - 10) {
84 *digit = c - 'A' + 10; 84 *digit = c - 'A' + 10;
85 } else { 85 } else {
86 return false; 86 return false;
87 } 87 }
88 return true; 88 return true;
89 } 89 }
90 }; 90 };
91 91
92 template<int BASE, typename CHAR> bool CharToDigit(CHAR c, uint8* digit) { 92 template <int BASE, typename CHAR>
93 bool CharToDigit(CHAR c, uint8_t* digit) {
93 return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit); 94 return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit);
94 } 95 }
95 96
96 // There is an IsUnicodeWhitespace for wchars defined in string_util.h, but it 97 // There is an IsUnicodeWhitespace for wchars defined in string_util.h, but it
97 // is locale independent, whereas the functions we are replacing were 98 // is locale independent, whereas the functions we are replacing were
98 // locale-dependent. TBD what is desired, but for the moment let's not 99 // locale-dependent. TBD what is desired, but for the moment let's not
99 // introduce a change in behaviour. 100 // introduce a change in behaviour.
100 template<typename CHAR> class WhitespaceHelper { 101 template<typename CHAR> class WhitespaceHelper {
101 }; 102 };
102 103
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 180 }
180 181
181 // Note: no performance difference was found when using template 182 // Note: no performance difference was found when using template
182 // specialization to remove this check in bases other than 16 183 // specialization to remove this check in bases other than 16
183 if (traits::kBase == 16 && end - begin > 2 && *begin == '0' && 184 if (traits::kBase == 16 && end - begin > 2 && *begin == '0' &&
184 (*(begin + 1) == 'x' || *(begin + 1) == 'X')) { 185 (*(begin + 1) == 'x' || *(begin + 1) == 'X')) {
185 begin += 2; 186 begin += 2;
186 } 187 }
187 188
188 for (const_iterator current = begin; current != end; ++current) { 189 for (const_iterator current = begin; current != end; ++current) {
189 uint8 new_digit = 0; 190 uint8_t new_digit = 0;
190 191
191 if (!CharToDigit<traits::kBase>(*current, &new_digit)) { 192 if (!CharToDigit<traits::kBase>(*current, &new_digit)) {
192 return false; 193 return false;
193 } 194 }
194 195
195 if (current != begin) { 196 if (current != begin) {
196 if (!Sign::CheckBounds(output, new_digit)) { 197 if (!Sign::CheckBounds(output, new_digit)) {
197 return false; 198 return false;
198 } 199 }
199 *output *= traits::kBase; 200 *output *= traits::kBase;
200 } 201 }
201 202
202 Sign::Increment(new_digit, output); 203 Sign::Increment(new_digit, output);
203 } 204 }
204 return true; 205 return true;
205 } 206 }
206 }; 207 };
207 208
208 class Positive : public Base<Positive> { 209 class Positive : public Base<Positive> {
209 public: 210 public:
210 static bool CheckBounds(value_type* output, uint8 new_digit) { 211 static bool CheckBounds(value_type* output, uint8_t new_digit) {
211 if (*output > static_cast<value_type>(traits::max() / traits::kBase) || 212 if (*output > static_cast<value_type>(traits::max() / traits::kBase) ||
212 (*output == static_cast<value_type>(traits::max() / traits::kBase) && 213 (*output == static_cast<value_type>(traits::max() / traits::kBase) &&
213 new_digit > traits::max() % traits::kBase)) { 214 new_digit > traits::max() % traits::kBase)) {
214 *output = traits::max(); 215 *output = traits::max();
215 return false; 216 return false;
216 } 217 }
217 return true; 218 return true;
218 } 219 }
219 static void Increment(uint8 increment, value_type* output) { 220 static void Increment(uint8_t increment, value_type* output) {
220 *output += increment; 221 *output += increment;
221 } 222 }
222 }; 223 };
223 224
224 class Negative : public Base<Negative> { 225 class Negative : public Base<Negative> {
225 public: 226 public:
226 static bool CheckBounds(value_type* output, uint8 new_digit) { 227 static bool CheckBounds(value_type* output, uint8_t new_digit) {
227 if (*output < traits::min() / traits::kBase || 228 if (*output < traits::min() / traits::kBase ||
228 (*output == traits::min() / traits::kBase && 229 (*output == traits::min() / traits::kBase &&
229 new_digit > 0 - traits::min() % traits::kBase)) { 230 new_digit > 0 - traits::min() % traits::kBase)) {
230 *output = traits::min(); 231 *output = traits::min();
231 return false; 232 return false;
232 } 233 }
233 return true; 234 return true;
234 } 235 }
235 static void Increment(uint8 increment, value_type* output) { 236 static void Increment(uint8_t increment, value_type* output) {
236 *output -= increment; 237 *output -= increment;
237 } 238 }
238 }; 239 };
239 }; 240 };
240 241
241 template<typename ITERATOR, typename VALUE, int BASE> 242 template<typename ITERATOR, typename VALUE, int BASE>
242 class BaseIteratorRangeToNumberTraits { 243 class BaseIteratorRangeToNumberTraits {
243 public: 244 public:
244 typedef ITERATOR iterator_type; 245 typedef ITERATOR iterator_type;
245 typedef VALUE value_type; 246 typedef VALUE value_type;
246 static value_type min() { 247 static value_type min() {
247 return std::numeric_limits<value_type>::min(); 248 return std::numeric_limits<value_type>::min();
248 } 249 }
249 static value_type max() { 250 static value_type max() {
250 return std::numeric_limits<value_type>::max(); 251 return std::numeric_limits<value_type>::max();
251 } 252 }
252 static const int kBase = BASE; 253 static const int kBase = BASE;
253 }; 254 };
254 255
255 template<typename ITERATOR> 256 template<typename ITERATOR>
256 class BaseHexIteratorRangeToIntTraits 257 class BaseHexIteratorRangeToIntTraits
257 : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { 258 : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> {
258 }; 259 };
259 260
260 template<typename ITERATOR> 261 template <typename ITERATOR>
261 class BaseHexIteratorRangeToUIntTraits 262 class BaseHexIteratorRangeToUIntTraits
262 : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32, 16> { 263 : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32_t, 16> {};
263 };
264 264
265 template<typename ITERATOR> 265 template <typename ITERATOR>
266 class BaseHexIteratorRangeToInt64Traits 266 class BaseHexIteratorRangeToInt64Traits
267 : public BaseIteratorRangeToNumberTraits<ITERATOR, int64, 16> { 267 : public BaseIteratorRangeToNumberTraits<ITERATOR, int64_t, 16> {};
268 };
269 268
270 template<typename ITERATOR> 269 template <typename ITERATOR>
271 class BaseHexIteratorRangeToUInt64Traits 270 class BaseHexIteratorRangeToUInt64Traits
272 : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64, 16> { 271 : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64_t, 16> {};
273 };
274 272
275 typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator> 273 typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator>
276 HexIteratorRangeToIntTraits; 274 HexIteratorRangeToIntTraits;
277 275
278 typedef BaseHexIteratorRangeToUIntTraits<StringPiece::const_iterator> 276 typedef BaseHexIteratorRangeToUIntTraits<StringPiece::const_iterator>
279 HexIteratorRangeToUIntTraits; 277 HexIteratorRangeToUIntTraits;
280 278
281 typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator> 279 typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator>
282 HexIteratorRangeToInt64Traits; 280 HexIteratorRangeToInt64Traits;
283 281
284 typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator> 282 typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator>
285 HexIteratorRangeToUInt64Traits; 283 HexIteratorRangeToUInt64Traits;
286 284
287 template<typename STR> 285 template <typename STR>
288 bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) { 286 bool HexStringToBytesT(const STR& input, std::vector<uint8_t>* output) {
289 DCHECK_EQ(output->size(), 0u); 287 DCHECK_EQ(output->size(), 0u);
290 size_t count = input.size(); 288 size_t count = input.size();
291 if (count == 0 || (count % 2) != 0) 289 if (count == 0 || (count % 2) != 0)
292 return false; 290 return false;
293 for (uintptr_t i = 0; i < count / 2; ++i) { 291 for (uintptr_t i = 0; i < count / 2; ++i) {
294 uint8 msb = 0; // most significant 4 bits 292 uint8_t msb = 0; // most significant 4 bits
295 uint8 lsb = 0; // least significant 4 bits 293 uint8_t lsb = 0; // least significant 4 bits
296 if (!CharToDigit<16>(input[i * 2], &msb) || 294 if (!CharToDigit<16>(input[i * 2], &msb) ||
297 !CharToDigit<16>(input[i * 2 + 1], &lsb)) 295 !CharToDigit<16>(input[i * 2 + 1], &lsb))
298 return false; 296 return false;
299 output->push_back((msb << 4) | lsb); 297 output->push_back((msb << 4) | lsb);
300 } 298 }
301 return true; 299 return true;
302 } 300 }
303 301
304 template <typename VALUE, int BASE> 302 template <typename VALUE, int BASE>
305 class StringPieceToNumberTraits 303 class StringPieceToNumberTraits
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 } 336 }
339 337
340 std::string UintToString(unsigned int value) { 338 std::string UintToString(unsigned int value) {
341 return IntToStringT<std::string, unsigned int>::IntToString(value); 339 return IntToStringT<std::string, unsigned int>::IntToString(value);
342 } 340 }
343 341
344 string16 UintToString16(unsigned int value) { 342 string16 UintToString16(unsigned int value) {
345 return IntToStringT<string16, unsigned int>::IntToString(value); 343 return IntToStringT<string16, unsigned int>::IntToString(value);
346 } 344 }
347 345
348 std::string Int64ToString(int64 value) { 346 std::string Int64ToString(int64_t value) {
349 return IntToStringT<std::string, int64>::IntToString(value); 347 return IntToStringT<std::string, int64_t>::IntToString(value);
350 } 348 }
351 349
352 string16 Int64ToString16(int64 value) { 350 string16 Int64ToString16(int64_t value) {
353 return IntToStringT<string16, int64>::IntToString(value); 351 return IntToStringT<string16, int64_t>::IntToString(value);
354 } 352 }
355 353
356 std::string Uint64ToString(uint64 value) { 354 std::string Uint64ToString(uint64_t value) {
357 return IntToStringT<std::string, uint64>::IntToString(value); 355 return IntToStringT<std::string, uint64_t>::IntToString(value);
358 } 356 }
359 357
360 string16 Uint64ToString16(uint64 value) { 358 string16 Uint64ToString16(uint64_t value) {
361 return IntToStringT<string16, uint64>::IntToString(value); 359 return IntToStringT<string16, uint64_t>::IntToString(value);
362 } 360 }
363 361
364 std::string SizeTToString(size_t value) { 362 std::string SizeTToString(size_t value) {
365 return IntToStringT<std::string, size_t>::IntToString(value); 363 return IntToStringT<std::string, size_t>::IntToString(value);
366 } 364 }
367 365
368 string16 SizeTToString16(size_t value) { 366 string16 SizeTToString16(size_t value) {
369 return IntToStringT<string16, size_t>::IntToString(value); 367 return IntToStringT<string16, size_t>::IntToString(value);
370 } 368 }
371 369
(...skipping 13 matching lines...) Expand all
385 } 383 }
386 384
387 bool StringToUint(const StringPiece& input, unsigned* output) { 385 bool StringToUint(const StringPiece& input, unsigned* output) {
388 return StringToIntImpl(input, output); 386 return StringToIntImpl(input, output);
389 } 387 }
390 388
391 bool StringToUint(const StringPiece16& input, unsigned* output) { 389 bool StringToUint(const StringPiece16& input, unsigned* output) {
392 return String16ToIntImpl(input, output); 390 return String16ToIntImpl(input, output);
393 } 391 }
394 392
395 bool StringToInt64(const StringPiece& input, int64* output) { 393 bool StringToInt64(const StringPiece& input, int64_t* output) {
396 return StringToIntImpl(input, output); 394 return StringToIntImpl(input, output);
397 } 395 }
398 396
399 bool StringToInt64(const StringPiece16& input, int64* output) { 397 bool StringToInt64(const StringPiece16& input, int64_t* output) {
400 return String16ToIntImpl(input, output); 398 return String16ToIntImpl(input, output);
401 } 399 }
402 400
403 bool StringToUint64(const StringPiece& input, uint64* output) { 401 bool StringToUint64(const StringPiece& input, uint64_t* output) {
404 return StringToIntImpl(input, output); 402 return StringToIntImpl(input, output);
405 } 403 }
406 404
407 bool StringToUint64(const StringPiece16& input, uint64* output) { 405 bool StringToUint64(const StringPiece16& input, uint64_t* output) {
408 return String16ToIntImpl(input, output); 406 return String16ToIntImpl(input, output);
409 } 407 }
410 408
411 bool StringToSizeT(const StringPiece& input, size_t* output) { 409 bool StringToSizeT(const StringPiece& input, size_t* output) {
412 return StringToIntImpl(input, output); 410 return StringToIntImpl(input, output);
413 } 411 }
414 412
415 bool StringToSizeT(const StringPiece16& input, size_t* output) { 413 bool StringToSizeT(const StringPiece16& input, size_t* output) {
416 return String16ToIntImpl(input, output); 414 return String16ToIntImpl(input, output);
417 } 415 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 ret[(i * 2) + 1] = kHexChars[b & 0xf]; 456 ret[(i * 2) + 1] = kHexChars[b & 0xf];
459 } 457 }
460 return ret; 458 return ret;
461 } 459 }
462 460
463 bool HexStringToInt(const StringPiece& input, int* output) { 461 bool HexStringToInt(const StringPiece& input, int* output) {
464 return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke( 462 return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke(
465 input.begin(), input.end(), output); 463 input.begin(), input.end(), output);
466 } 464 }
467 465
468 bool HexStringToUInt(const StringPiece& input, uint32* output) { 466 bool HexStringToUInt(const StringPiece& input, uint32_t* output) {
469 return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke( 467 return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke(
470 input.begin(), input.end(), output); 468 input.begin(), input.end(), output);
471 } 469 }
472 470
473 bool HexStringToInt64(const StringPiece& input, int64* output) { 471 bool HexStringToInt64(const StringPiece& input, int64_t* output) {
474 return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke( 472 return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke(
475 input.begin(), input.end(), output); 473 input.begin(), input.end(), output);
476 } 474 }
477 475
478 bool HexStringToUInt64(const StringPiece& input, uint64* output) { 476 bool HexStringToUInt64(const StringPiece& input, uint64_t* output) {
479 return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke( 477 return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke(
480 input.begin(), input.end(), output); 478 input.begin(), input.end(), output);
481 } 479 }
482 480
483 bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { 481 bool HexStringToBytes(const std::string& input, std::vector<uint8_t>* output) {
484 return HexStringToBytesT(input, output); 482 return HexStringToBytesT(input, output);
485 } 483 }
486 484
487 } // namespace base 485 } // namespace base
OLDNEW
« no previous file with comments | « base/strings/string_number_conversions.h ('k') | base/strings/string_number_conversions_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698