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 // Overloaded function to append one string onto the end of another. Having a |
| 68 // separate overload for |source| as both string and StringPiece allows for more |
| 69 // efficient usage from functions templated to work with either type (avoiding a |
| 70 // redundant call to the BasicStringPiece constructor in both cases). |
| 71 template <typename string_type> |
| 72 inline void AppendToString(string_type* target, const string_type& source) { |
| 73 target->append(source); |
| 74 } |
| 75 |
| 76 template <typename string_type> |
| 77 inline void AppendToString(string_type* target, |
| 78 const BasicStringPiece<string_type>& source) { |
| 79 source.AppendToString(target); |
| 80 } |
| 81 |
67 // Assuming that a pointer is the size of a "machine word", then | 82 // 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. | 83 // uintptr_t is an integer type that is also a machine word. |
69 typedef uintptr_t MachineWord; | 84 typedef uintptr_t MachineWord; |
70 const uintptr_t kMachineWordAlignmentMask = sizeof(MachineWord) - 1; | 85 const uintptr_t kMachineWordAlignmentMask = sizeof(MachineWord) - 1; |
71 | 86 |
72 inline bool IsAlignedToMachineWord(const void* pointer) { | 87 inline bool IsAlignedToMachineWord(const void* pointer) { |
73 return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); | 88 return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); |
74 } | 89 } |
75 | 90 |
76 template<typename T> inline T* AlignToMachineWord(T* pointer) { | 91 template<typename T> inline T* AlignToMachineWord(T* pointer) { |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 } | 861 } |
847 | 862 |
848 char* WriteInto(std::string* str, size_t length_with_null) { | 863 char* WriteInto(std::string* str, size_t length_with_null) { |
849 return WriteIntoT(str, length_with_null); | 864 return WriteIntoT(str, length_with_null); |
850 } | 865 } |
851 | 866 |
852 char16* WriteInto(string16* str, size_t length_with_null) { | 867 char16* WriteInto(string16* str, size_t length_with_null) { |
853 return WriteIntoT(str, length_with_null); | 868 return WriteIntoT(str, length_with_null); |
854 } | 869 } |
855 | 870 |
856 template<typename STR> | 871 // Generic version for all JoinString overloads. |list_type| must be a sequence |
857 static STR JoinStringT(const std::vector<STR>& parts, | 872 // (std::vector or std::initializer_list) of strings/StringPieces (std::string, |
858 BasicStringPiece<STR> sep) { | 873 // string16, StringPiece or StringPiece16). |string_type| is either std::string |
859 if (parts.empty()) | 874 // or string16. |
860 return STR(); | 875 template <typename list_type, typename string_type> |
| 876 static string_type JoinStringT(const list_type& parts, |
| 877 BasicStringPiece<string_type> sep) { |
| 878 auto iter = parts.begin(); |
| 879 // Early-exit to avoid bad access to the first element. |
| 880 if (iter == parts.end()) |
| 881 return string_type(); |
861 | 882 |
862 STR result(parts[0]); | 883 // Begin constructing the result from the first element. |
863 auto iter = parts.begin(); | 884 string_type result(iter->data(), iter->size()); |
864 ++iter; | 885 ++iter; |
865 | 886 |
866 for (; iter != parts.end(); ++iter) { | 887 for (; iter != parts.end(); ++iter) { |
867 sep.AppendToString(&result); | 888 sep.AppendToString(&result); |
868 result += *iter; | 889 // Using the overloaded AppendToString allows this template function to work |
| 890 // on both strings and StringPieces without creating an intermediate |
| 891 // StringPiece object. |
| 892 AppendToString(&result, *iter); |
869 } | 893 } |
870 | 894 |
871 return result; | 895 return result; |
872 } | 896 } |
873 | 897 |
874 std::string JoinString(const std::vector<std::string>& parts, | 898 std::string JoinString(const std::vector<std::string>& parts, |
875 StringPiece separator) { | 899 StringPiece separator) { |
876 return JoinStringT(parts, separator); | 900 return JoinStringT(parts, separator); |
877 } | 901 } |
878 | 902 |
879 string16 JoinString(const std::vector<string16>& parts, | 903 string16 JoinString(const std::vector<string16>& parts, |
880 StringPiece16 separator) { | 904 StringPiece16 separator) { |
881 return JoinStringT(parts, separator); | 905 return JoinStringT(parts, separator); |
882 } | 906 } |
883 | 907 |
| 908 std::string JoinString(const std::vector<StringPiece>& parts, |
| 909 StringPiece separator) { |
| 910 return JoinStringT(parts, separator); |
| 911 } |
| 912 |
| 913 string16 JoinString(const std::vector<StringPiece16>& parts, |
| 914 StringPiece16 separator) { |
| 915 return JoinStringT(parts, separator); |
| 916 } |
| 917 |
| 918 std::string JoinString(std::initializer_list<StringPiece> parts, |
| 919 StringPiece separator) { |
| 920 return JoinStringT(parts, separator); |
| 921 } |
| 922 |
| 923 string16 JoinString(std::initializer_list<StringPiece16> parts, |
| 924 StringPiece16 separator) { |
| 925 return JoinStringT(parts, separator); |
| 926 } |
| 927 |
884 template<class FormatStringType, class OutStringType> | 928 template<class FormatStringType, class OutStringType> |
885 OutStringType DoReplaceStringPlaceholders( | 929 OutStringType DoReplaceStringPlaceholders( |
886 const FormatStringType& format_string, | 930 const FormatStringType& format_string, |
887 const std::vector<OutStringType>& subst, | 931 const std::vector<OutStringType>& subst, |
888 std::vector<size_t>* offsets) { | 932 std::vector<size_t>* offsets) { |
889 size_t substitutions = subst.size(); | 933 size_t substitutions = subst.size(); |
890 DCHECK_LT(substitutions, 10U); | 934 DCHECK_LT(substitutions, 10U); |
891 | 935 |
892 size_t sub_length = 0; | 936 size_t sub_length = 0; |
893 for (const auto& cur : subst) | 937 for (const auto& cur : subst) |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 } // namespace | 1032 } // namespace |
989 | 1033 |
990 size_t strlcpy(char* dst, const char* src, size_t dst_size) { | 1034 size_t strlcpy(char* dst, const char* src, size_t dst_size) { |
991 return lcpyT<char>(dst, src, dst_size); | 1035 return lcpyT<char>(dst, src, dst_size); |
992 } | 1036 } |
993 size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { | 1037 size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { |
994 return lcpyT<wchar_t>(dst, src, dst_size); | 1038 return lcpyT<wchar_t>(dst, src, dst_size); |
995 } | 1039 } |
996 | 1040 |
997 } // namespace base | 1041 } // namespace base |
OLD | NEW |