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 machineWordAlignmentMask = sizeof(MachineWord) - 1; | |
brettw
2014/09/16 17:14:28
Constant naming: kMachineWord....
mnaganov (inactive)
2014/09/17 15:15:01
Done.
| |
71 | |
72 inline bool IsAlignedToMachineWord(const void* pointer) { | |
73 return !(reinterpret_cast<MachineWord>(pointer) & machineWordAlignmentMask); | |
74 } | |
75 | |
76 template<typename T> inline T* AlignToMachineWord(T* pointer) { | |
77 return reinterpret_cast<T*>(reinterpret_cast<MachineWord>(pointer) & | |
78 ~machineWordAlignmentMask); | |
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()); |
337 } | 385 } |
338 | 386 |
339 bool IsStringASCII(const string16& str) { | 387 bool IsStringASCII(const string16& str) { |
340 return DoIsStringASCII(str); | 388 return DoIsStringASCII(str.data(), str.length()); |
389 } | |
390 | |
391 bool IsStringASCII(const char* src, size_t src_len) { | |
392 return DoIsStringASCII(src, src_len); | |
393 } | |
394 | |
395 bool IsStringASCII(const char16* src, size_t src_len) { | |
396 return DoIsStringASCII(src, src_len); | |
341 } | 397 } |
342 | 398 |
343 bool IsStringUTF8(const std::string& str) { | 399 bool IsStringUTF8(const std::string& str) { |
344 const char *src = str.data(); | 400 const char *src = str.data(); |
345 int32 src_len = static_cast<int32>(str.length()); | 401 int32 src_len = static_cast<int32>(str.length()); |
346 int32 char_index = 0; | 402 int32 char_index = 0; |
347 | 403 |
348 while (char_index < src_len) { | 404 while (char_index < src_len) { |
349 int32 code_point; | 405 int32 code_point; |
350 CBU8_NEXT(src, char_index, src_len, code_point); | 406 CBU8_NEXT(src, char_index, src_len, code_point); |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 } | 939 } |
884 | 940 |
885 } // namespace | 941 } // namespace |
886 | 942 |
887 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { | 943 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { |
888 return lcpyT<char>(dst, src, dst_size); | 944 return lcpyT<char>(dst, src, dst_size); |
889 } | 945 } |
890 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { | 946 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { |
891 return lcpyT<wchar_t>(dst, src, dst_size); | 947 return lcpyT<wchar_t>(dst, src, dst_size); |
892 } | 948 } |
OLD | NEW |