OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_util.h" | 5 #include "base/strings/string_util.h" |
6 | 6 |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <math.h> | 9 #include <math.h> |
10 #include <stdarg.h> | 10 #include <stdarg.h> |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 | 57 |
58 // Starting position in the string. | 58 // Starting position in the string. |
59 size_t offset; | 59 size_t offset; |
60 }; | 60 }; |
61 | 61 |
62 static bool CompareParameter(const ReplacementOffset& elem1, | 62 static bool CompareParameter(const ReplacementOffset& elem1, |
63 const ReplacementOffset& elem2) { | 63 const ReplacementOffset& elem2) { |
64 return elem1.parameter < elem2.parameter; | 64 return elem1.parameter < elem2.parameter; |
65 } | 65 } |
66 | 66 |
| 67 // Assuming that a pointer is the size of a "machine word", then |
| 68 // uintptr_t is an integer type that is also a machine word. |
| 69 typedef uintptr_t MachineWord; |
| 70 const uintptr_t kMachineWordAlignmentMask = sizeof(MachineWord) - 1; |
| 71 |
| 72 inline bool IsAlignedToMachineWord(const void* pointer) { |
| 73 return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); |
| 74 } |
| 75 |
| 76 template<typename T> inline T* AlignToMachineWord(T* pointer) { |
| 77 return reinterpret_cast<T*>(reinterpret_cast<MachineWord>(pointer) & |
| 78 ~kMachineWordAlignmentMask); |
| 79 } |
| 80 |
| 81 template<size_t size, typename CharacterType> struct NonASCIIMask; |
| 82 template<> struct NonASCIIMask<4, base::char16> { |
| 83 static inline uint32_t value() { return 0xFF80FF80U; } |
| 84 }; |
| 85 template<> struct NonASCIIMask<4, char> { |
| 86 static inline uint32_t value() { return 0x80808080U; } |
| 87 }; |
| 88 template<> struct NonASCIIMask<8, base::char16> { |
| 89 static inline uint64_t value() { return 0xFF80FF80FF80FF80ULL; } |
| 90 }; |
| 91 template<> struct NonASCIIMask<8, char> { |
| 92 static inline uint64_t value() { return 0x8080808080808080ULL; } |
| 93 }; |
| 94 |
67 } // namespace | 95 } // namespace |
68 | 96 |
69 namespace base { | 97 namespace base { |
70 | 98 |
71 bool IsWprintfFormatPortable(const wchar_t* format) { | 99 bool IsWprintfFormatPortable(const wchar_t* format) { |
72 for (const wchar_t* position = format; *position != '\0'; ++position) { | 100 for (const wchar_t* position = format; *position != '\0'; ++position) { |
73 if (*position == '%') { | 101 if (*position == '%') { |
74 bool in_specification = true; | 102 bool in_specification = true; |
75 bool modifier_l = false; | 103 bool modifier_l = false; |
76 while (in_specification) { | 104 while (in_specification) { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 bool ContainsOnlyChars(const StringPiece& input, | 343 bool ContainsOnlyChars(const StringPiece& input, |
316 const StringPiece& characters) { | 344 const StringPiece& characters) { |
317 return input.find_first_not_of(characters) == StringPiece::npos; | 345 return input.find_first_not_of(characters) == StringPiece::npos; |
318 } | 346 } |
319 | 347 |
320 bool ContainsOnlyChars(const StringPiece16& input, | 348 bool ContainsOnlyChars(const StringPiece16& input, |
321 const StringPiece16& characters) { | 349 const StringPiece16& characters) { |
322 return input.find_first_not_of(characters) == StringPiece16::npos; | 350 return input.find_first_not_of(characters) == StringPiece16::npos; |
323 } | 351 } |
324 | 352 |
325 template<class STR> | 353 template <class Char> |
326 static bool DoIsStringASCII(const STR& str) { | 354 inline bool DoIsStringASCII(const Char* characters, size_t length) { |
327 for (size_t i = 0; i < str.length(); i++) { | 355 MachineWord all_char_bits = 0; |
328 typename ToUnsigned<typename STR::value_type>::Unsigned c = str[i]; | 356 const Char* end = characters + length; |
329 if (c > 0x7F) | 357 |
330 return false; | 358 // Prologue: align the input. |
| 359 while (!IsAlignedToMachineWord(characters) && characters != end) { |
| 360 all_char_bits |= *characters; |
| 361 ++characters; |
331 } | 362 } |
332 return true; | 363 |
| 364 // Compare the values of CPU word size. |
| 365 const Char* word_end = AlignToMachineWord(end); |
| 366 const size_t loop_increment = sizeof(MachineWord) / sizeof(Char); |
| 367 while (characters < word_end) { |
| 368 all_char_bits |= *(reinterpret_cast<const MachineWord*>(characters)); |
| 369 characters += loop_increment; |
| 370 } |
| 371 |
| 372 // Process the remaining bytes. |
| 373 while (characters != end) { |
| 374 all_char_bits |= *characters; |
| 375 ++characters; |
| 376 } |
| 377 |
| 378 MachineWord non_ascii_bit_mask = |
| 379 NonASCIIMask<sizeof(MachineWord), Char>::value(); |
| 380 return !(all_char_bits & non_ascii_bit_mask); |
333 } | 381 } |
334 | 382 |
335 bool IsStringASCII(const StringPiece& str) { | 383 bool IsStringASCII(const StringPiece& str) { |
336 return DoIsStringASCII(str); | 384 return DoIsStringASCII(str.data(), str.length()); |
| 385 } |
| 386 |
| 387 bool IsStringASCII(const StringPiece16& str) { |
| 388 return DoIsStringASCII(str.data(), str.length()); |
337 } | 389 } |
338 | 390 |
339 bool IsStringASCII(const string16& str) { | 391 bool IsStringASCII(const string16& str) { |
340 return DoIsStringASCII(str); | 392 return DoIsStringASCII(str.data(), str.length()); |
341 } | 393 } |
342 | 394 |
343 bool IsStringUTF8(const std::string& str) { | 395 bool IsStringUTF8(const std::string& str) { |
344 const char *src = str.data(); | 396 const char *src = str.data(); |
345 int32 src_len = static_cast<int32>(str.length()); | 397 int32 src_len = static_cast<int32>(str.length()); |
346 int32 char_index = 0; | 398 int32 char_index = 0; |
347 | 399 |
348 while (char_index < src_len) { | 400 while (char_index < src_len) { |
349 int32 code_point; | 401 int32 code_point; |
350 CBU8_NEXT(src, char_index, src_len, code_point); | 402 CBU8_NEXT(src, char_index, src_len, code_point); |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 } | 935 } |
884 | 936 |
885 } // namespace | 937 } // namespace |
886 | 938 |
887 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { | 939 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { |
888 return lcpyT<char>(dst, src, dst_size); | 940 return lcpyT<char>(dst, src, dst_size); |
889 } | 941 } |
890 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { | 942 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { |
891 return lcpyT<wchar_t>(dst, src, dst_size); | 943 return lcpyT<wchar_t>(dst, src, dst_size); |
892 } | 944 } |
OLD | NEW |