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> |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <string.h> | 13 #include <string.h> |
14 #include <time.h> | 14 #include <time.h> |
15 #include <wchar.h> | 15 #include <wchar.h> |
16 #include <wctype.h> | 16 #include <wctype.h> |
17 | 17 |
18 #include <algorithm> | 18 #include <algorithm> |
19 #include <vector> | 19 #include <vector> |
20 | 20 |
21 #include "base/basictypes.h" | 21 #include "base/basictypes.h" |
22 #include "base/logging.h" | 22 #include "base/logging.h" |
23 #include "base/memory/singleton.h" | 23 #include "base/memory/singleton.h" |
24 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
25 #include "base/strings/utf_string_conversion_utils.h" | 25 #include "base/strings/utf_string_conversion_utils.h" |
26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
27 #include "base/third_party/icu/icu_utf.h" | 27 #include "base/third_party/icu/icu_utf.h" |
28 #include "build/build_config.h" | 28 #include "build/build_config.h" |
29 | 29 |
30 // Remove when this entire file is in the base namespace. | 30 namespace base { |
31 using base::char16; | |
32 using base::string16; | |
33 | 31 |
34 namespace { | 32 namespace { |
35 | 33 |
36 // Force the singleton used by EmptyString[16] to be a unique type. This | 34 // Force the singleton used by EmptyString[16] to be a unique type. This |
37 // prevents other code that might accidentally use Singleton<string> from | 35 // prevents other code that might accidentally use Singleton<string> from |
38 // getting our internal one. | 36 // getting our internal one. |
39 struct EmptyStrings { | 37 struct EmptyStrings { |
40 EmptyStrings() {} | 38 EmptyStrings() {} |
41 const std::string s; | 39 const std::string s; |
42 const string16 s16; | 40 const string16 s16; |
(...skipping 30 matching lines...) Expand all Loading... |
73 inline bool IsAlignedToMachineWord(const void* pointer) { | 71 inline bool IsAlignedToMachineWord(const void* pointer) { |
74 return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); | 72 return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); |
75 } | 73 } |
76 | 74 |
77 template<typename T> inline T* AlignToMachineWord(T* pointer) { | 75 template<typename T> inline T* AlignToMachineWord(T* pointer) { |
78 return reinterpret_cast<T*>(reinterpret_cast<MachineWord>(pointer) & | 76 return reinterpret_cast<T*>(reinterpret_cast<MachineWord>(pointer) & |
79 ~kMachineWordAlignmentMask); | 77 ~kMachineWordAlignmentMask); |
80 } | 78 } |
81 | 79 |
82 template<size_t size, typename CharacterType> struct NonASCIIMask; | 80 template<size_t size, typename CharacterType> struct NonASCIIMask; |
83 template<> struct NonASCIIMask<4, base::char16> { | 81 template<> struct NonASCIIMask<4, char16> { |
84 static inline uint32_t value() { return 0xFF80FF80U; } | 82 static inline uint32_t value() { return 0xFF80FF80U; } |
85 }; | 83 }; |
86 template<> struct NonASCIIMask<4, char> { | 84 template<> struct NonASCIIMask<4, char> { |
87 static inline uint32_t value() { return 0x80808080U; } | 85 static inline uint32_t value() { return 0x80808080U; } |
88 }; | 86 }; |
89 template<> struct NonASCIIMask<8, base::char16> { | 87 template<> struct NonASCIIMask<8, char16> { |
90 static inline uint64_t value() { return 0xFF80FF80FF80FF80ULL; } | 88 static inline uint64_t value() { return 0xFF80FF80FF80FF80ULL; } |
91 }; | 89 }; |
92 template<> struct NonASCIIMask<8, char> { | 90 template<> struct NonASCIIMask<8, char> { |
93 static inline uint64_t value() { return 0x8080808080808080ULL; } | 91 static inline uint64_t value() { return 0x8080808080808080ULL; } |
94 }; | 92 }; |
95 #if defined(WCHAR_T_IS_UTF32) | 93 #if defined(WCHAR_T_IS_UTF32) |
96 template<> struct NonASCIIMask<4, wchar_t> { | 94 template<> struct NonASCIIMask<4, wchar_t> { |
97 static inline uint32_t value() { return 0xFFFFFF80U; } | 95 static inline uint32_t value() { return 0xFFFFFF80U; } |
98 }; | 96 }; |
99 template<> struct NonASCIIMask<8, wchar_t> { | 97 template<> struct NonASCIIMask<8, wchar_t> { |
100 static inline uint64_t value() { return 0xFFFFFF80FFFFFF80ULL; } | 98 static inline uint64_t value() { return 0xFFFFFF80FFFFFF80ULL; } |
101 }; | 99 }; |
102 #endif // WCHAR_T_IS_UTF32 | 100 #endif // WCHAR_T_IS_UTF32 |
103 | 101 |
104 // DO NOT USE. http://crbug.com/24917 | 102 // DO NOT USE. http://crbug.com/24917 |
105 // | 103 // |
106 // tolower() will given incorrect results for non-ASCII characters. Use the | 104 // tolower() will given incorrect results for non-ASCII characters. Use the |
107 // ASCII version, base::i18n::ToLower, or base::i18n::FoldCase. This is here | 105 // ASCII version, base::i18n::ToLower, or base::i18n::FoldCase. This is here |
108 // for backwards-compat for StartsWith until such calls can be updated. | 106 // for backwards-compat for StartsWith until such calls can be updated. |
109 struct CaseInsensitiveCompareDeprecated { | 107 struct CaseInsensitiveCompareDeprecated { |
110 public: | 108 public: |
111 bool operator()(char16 x, char16 y) const { | 109 bool operator()(char16 x, char16 y) const { |
112 return tolower(x) == tolower(y); | 110 return tolower(x) == tolower(y); |
113 } | 111 } |
114 }; | 112 }; |
115 | 113 |
116 } // namespace | 114 } // namespace |
117 | 115 |
118 namespace base { | |
119 | |
120 bool IsWprintfFormatPortable(const wchar_t* format) { | 116 bool IsWprintfFormatPortable(const wchar_t* format) { |
121 for (const wchar_t* position = format; *position != '\0'; ++position) { | 117 for (const wchar_t* position = format; *position != '\0'; ++position) { |
122 if (*position == '%') { | 118 if (*position == '%') { |
123 bool in_specification = true; | 119 bool in_specification = true; |
124 bool modifier_l = false; | 120 bool modifier_l = false; |
125 while (in_specification) { | 121 while (in_specification) { |
126 // Eat up characters until reaching a known specifier. | 122 // Eat up characters until reaching a known specifier. |
127 if (*++position == '\0') { | 123 if (*++position == '\0') { |
128 // The format string ended in the middle of a specification. Call | 124 // The format string ended in the middle of a specification. Call |
129 // it portable because no unportable specifications were found. The | 125 // it portable because no unportable specifications were found. The |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 // End of one string hit before finding a different character. Expect the | 168 // End of one string hit before finding a different character. Expect the |
173 // common case to be "strings equal" at this point so check that first. | 169 // common case to be "strings equal" at this point so check that first. |
174 if (a.length() == b.length()) | 170 if (a.length() == b.length()) |
175 return 0; | 171 return 0; |
176 | 172 |
177 if (a.length() < b.length()) | 173 if (a.length() < b.length()) |
178 return -1; | 174 return -1; |
179 return 1; | 175 return 1; |
180 } | 176 } |
181 | 177 |
182 int CompareCaseInsensitiveASCII(base::StringPiece a, base::StringPiece b) { | 178 int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b) { |
183 return CompareCaseInsensitiveASCIIT<std::string>(a, b); | 179 return CompareCaseInsensitiveASCIIT<std::string>(a, b); |
184 } | 180 } |
185 | 181 |
186 int CompareCaseInsensitiveASCII(base::StringPiece16 a, base::StringPiece16 b) { | 182 int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { |
187 return CompareCaseInsensitiveASCIIT<base::string16>(a, b); | 183 return CompareCaseInsensitiveASCIIT<string16>(a, b); |
188 } | 184 } |
189 | 185 |
190 bool EqualsCaseInsensitiveASCII(base::StringPiece a, base::StringPiece b) { | 186 bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { |
191 if (a.length() != b.length()) | 187 if (a.length() != b.length()) |
192 return false; | 188 return false; |
193 return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0; | 189 return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0; |
194 } | 190 } |
195 | 191 |
196 bool EqualsCaseInsensitiveASCII(base::StringPiece16 a, base::StringPiece16 b) { | 192 bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { |
197 if (a.length() != b.length()) | 193 if (a.length() != b.length()) |
198 return false; | 194 return false; |
199 return CompareCaseInsensitiveASCIIT<base::string16>(a, b) == 0; | 195 return CompareCaseInsensitiveASCIIT<string16>(a, b) == 0; |
200 } | 196 } |
201 | 197 |
202 const std::string& EmptyString() { | 198 const std::string& EmptyString() { |
203 return EmptyStrings::GetInstance()->s; | 199 return EmptyStrings::GetInstance()->s; |
204 } | 200 } |
205 | 201 |
206 const string16& EmptyString16() { | 202 const string16& EmptyString16() { |
207 return EmptyStrings::GetInstance()->s16; | 203 return EmptyStrings::GetInstance()->s16; |
208 } | 204 } |
209 | 205 |
(...skipping 11 matching lines...) Expand all Loading... |
221 while (found != STR::npos) { | 217 while (found != STR::npos) { |
222 removed = true; | 218 removed = true; |
223 output->replace(found, 1, replace_with); | 219 output->replace(found, 1, replace_with); |
224 found = output->find_first_of(replace_chars, found + replace_length); | 220 found = output->find_first_of(replace_chars, found + replace_length); |
225 } | 221 } |
226 | 222 |
227 return removed; | 223 return removed; |
228 } | 224 } |
229 | 225 |
230 bool ReplaceChars(const string16& input, | 226 bool ReplaceChars(const string16& input, |
231 const base::StringPiece16& replace_chars, | 227 const StringPiece16& replace_chars, |
232 const string16& replace_with, | 228 const string16& replace_with, |
233 string16* output) { | 229 string16* output) { |
234 return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); | 230 return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); |
235 } | 231 } |
236 | 232 |
237 bool ReplaceChars(const std::string& input, | 233 bool ReplaceChars(const std::string& input, |
238 const base::StringPiece& replace_chars, | 234 const StringPiece& replace_chars, |
239 const std::string& replace_with, | 235 const std::string& replace_with, |
240 std::string* output) { | 236 std::string* output) { |
241 return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); | 237 return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); |
242 } | 238 } |
243 | 239 |
244 bool RemoveChars(const string16& input, | 240 bool RemoveChars(const string16& input, |
245 const base::StringPiece16& remove_chars, | 241 const StringPiece16& remove_chars, |
246 string16* output) { | 242 string16* output) { |
247 return ReplaceChars(input, remove_chars.as_string(), string16(), output); | 243 return ReplaceChars(input, remove_chars.as_string(), string16(), output); |
248 } | 244 } |
249 | 245 |
250 bool RemoveChars(const std::string& input, | 246 bool RemoveChars(const std::string& input, |
251 const base::StringPiece& remove_chars, | 247 const StringPiece& remove_chars, |
252 std::string* output) { | 248 std::string* output) { |
253 return ReplaceChars(input, remove_chars.as_string(), std::string(), output); | 249 return ReplaceChars(input, remove_chars.as_string(), std::string(), output); |
254 } | 250 } |
255 | 251 |
256 template<typename Str> | 252 template<typename Str> |
257 TrimPositions TrimStringT(const Str& input, | 253 TrimPositions TrimStringT(const Str& input, |
258 BasicStringPiece<Str> trim_chars, | 254 BasicStringPiece<Str> trim_chars, |
259 TrimPositions positions, | 255 TrimPositions positions, |
260 Str* output) { | 256 Str* output) { |
261 // Find the edges of leading/trailing whitespace as desired. Need to use | 257 // Find the edges of leading/trailing whitespace as desired. Need to use |
(...skipping 21 matching lines...) Expand all Loading... |
283 *output = | 279 *output = |
284 input.substr(first_good_char, last_good_char - first_good_char + 1); | 280 input.substr(first_good_char, last_good_char - first_good_char + 1); |
285 | 281 |
286 // Return where we trimmed from. | 282 // Return where we trimmed from. |
287 return static_cast<TrimPositions>( | 283 return static_cast<TrimPositions>( |
288 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | | 284 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | |
289 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); | 285 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); |
290 } | 286 } |
291 | 287 |
292 bool TrimString(const string16& input, | 288 bool TrimString(const string16& input, |
293 base::StringPiece16 trim_chars, | 289 StringPiece16 trim_chars, |
294 string16* output) { | 290 string16* output) { |
295 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | 291 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; |
296 } | 292 } |
297 | 293 |
298 bool TrimString(const std::string& input, | 294 bool TrimString(const std::string& input, |
299 base::StringPiece trim_chars, | 295 StringPiece trim_chars, |
300 std::string* output) { | 296 std::string* output) { |
301 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | 297 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; |
302 } | 298 } |
303 | 299 |
304 template<typename Str> | 300 template<typename Str> |
305 BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input, | 301 BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input, |
306 BasicStringPiece<Str> trim_chars, | 302 BasicStringPiece<Str> trim_chars, |
307 TrimPositions positions) { | 303 TrimPositions positions) { |
308 size_t begin = (positions & TRIM_LEADING) ? | 304 size_t begin = (positions & TRIM_LEADING) ? |
309 input.find_first_not_of(trim_chars) : 0; | 305 input.find_first_not_of(trim_chars) : 0; |
310 size_t end = (positions & TRIM_TRAILING) ? | 306 size_t end = (positions & TRIM_TRAILING) ? |
311 input.find_last_not_of(trim_chars) + 1 : input.size(); | 307 input.find_last_not_of(trim_chars) + 1 : input.size(); |
312 return input.substr(begin, end - begin); | 308 return input.substr(begin, end - begin); |
313 } | 309 } |
314 | 310 |
315 StringPiece16 TrimString(StringPiece16 input, | 311 StringPiece16 TrimString(StringPiece16 input, |
316 const base::StringPiece16& trim_chars, | 312 const StringPiece16& trim_chars, |
317 TrimPositions positions) { | 313 TrimPositions positions) { |
318 return TrimStringPieceT(input, trim_chars, positions); | 314 return TrimStringPieceT(input, trim_chars, positions); |
319 } | 315 } |
320 | 316 |
321 StringPiece TrimString(StringPiece input, | 317 StringPiece TrimString(StringPiece input, |
322 const base::StringPiece& trim_chars, | 318 const StringPiece& trim_chars, |
323 TrimPositions positions) { | 319 TrimPositions positions) { |
324 return TrimStringPieceT(input, trim_chars, positions); | 320 return TrimStringPieceT(input, trim_chars, positions); |
325 } | 321 } |
326 | 322 |
327 void TruncateUTF8ToByteSize(const std::string& input, | 323 void TruncateUTF8ToByteSize(const std::string& input, |
328 const size_t byte_size, | 324 const size_t byte_size, |
329 std::string* output) { | 325 std::string* output) { |
330 DCHECK(output); | 326 DCHECK(output); |
331 if (byte_size > input.length()) { | 327 if (byte_size > input.length()) { |
332 *output = input; | 328 *output = input; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 BasicStringPiece<Str> source = str.substr(0, search_for.size()); | 581 BasicStringPiece<Str> source = str.substr(0, search_for.size()); |
586 | 582 |
587 switch (case_sensitivity) { | 583 switch (case_sensitivity) { |
588 case CompareCase::SENSITIVE: | 584 case CompareCase::SENSITIVE: |
589 return source == search_for; | 585 return source == search_for; |
590 | 586 |
591 case CompareCase::INSENSITIVE_ASCII: | 587 case CompareCase::INSENSITIVE_ASCII: |
592 return std::equal( | 588 return std::equal( |
593 search_for.begin(), search_for.end(), | 589 search_for.begin(), search_for.end(), |
594 source.begin(), | 590 source.begin(), |
595 base::CaseInsensitiveCompareASCII<typename Str::value_type>()); | 591 CaseInsensitiveCompareASCII<typename Str::value_type>()); |
596 | 592 |
597 default: | 593 default: |
598 NOTREACHED(); | 594 NOTREACHED(); |
599 return false; | 595 return false; |
600 } | 596 } |
601 } | 597 } |
602 | 598 |
603 bool StartsWith(StringPiece str, | 599 bool StartsWith(StringPiece str, |
604 StringPiece search_for, | 600 StringPiece search_for, |
605 CompareCase case_sensitivity) { | 601 CompareCase case_sensitivity) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 search_for.size()); | 636 search_for.size()); |
641 | 637 |
642 switch (case_sensitivity) { | 638 switch (case_sensitivity) { |
643 case CompareCase::SENSITIVE: | 639 case CompareCase::SENSITIVE: |
644 return source == search_for; | 640 return source == search_for; |
645 | 641 |
646 case CompareCase::INSENSITIVE_ASCII: | 642 case CompareCase::INSENSITIVE_ASCII: |
647 return std::equal( | 643 return std::equal( |
648 source.begin(), source.end(), | 644 source.begin(), source.end(), |
649 search_for.begin(), | 645 search_for.begin(), |
650 base::CaseInsensitiveCompareASCII<typename Str::value_type>()); | 646 CaseInsensitiveCompareASCII<typename Str::value_type>()); |
651 | 647 |
652 default: | 648 default: |
653 NOTREACHED(); | 649 NOTREACHED(); |
654 return false; | 650 return false; |
655 } | 651 } |
656 } | 652 } |
657 | 653 |
658 bool EndsWith(StringPiece str, | 654 bool EndsWith(StringPiece str, |
659 StringPiece search_for, | 655 StringPiece search_for, |
660 CompareCase case_sensitivity) { | 656 CompareCase case_sensitivity) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 DCHECK_GT(length_with_null, 1u); | 869 DCHECK_GT(length_with_null, 1u); |
874 str->reserve(length_with_null); | 870 str->reserve(length_with_null); |
875 str->resize(length_with_null - 1); | 871 str->resize(length_with_null - 1); |
876 return &((*str)[0]); | 872 return &((*str)[0]); |
877 } | 873 } |
878 | 874 |
879 char* WriteInto(std::string* str, size_t length_with_null) { | 875 char* WriteInto(std::string* str, size_t length_with_null) { |
880 return WriteIntoT(str, length_with_null); | 876 return WriteIntoT(str, length_with_null); |
881 } | 877 } |
882 | 878 |
883 char16* WriteInto(base::string16* str, size_t length_with_null) { | 879 char16* WriteInto(string16* str, size_t length_with_null) { |
884 return WriteIntoT(str, length_with_null); | 880 return WriteIntoT(str, length_with_null); |
885 } | 881 } |
886 | 882 |
887 template<typename STR> | 883 template<typename STR> |
888 static STR JoinStringT(const std::vector<STR>& parts, | 884 static STR JoinStringT(const std::vector<STR>& parts, |
889 BasicStringPiece<STR> sep) { | 885 BasicStringPiece<STR> sep) { |
890 if (parts.empty()) | 886 if (parts.empty()) |
891 return STR(); | 887 return STR(); |
892 | 888 |
893 STR result(parts[0]); | 889 STR result(parts[0]); |
(...skipping 11 matching lines...) Expand all Loading... |
905 std::string JoinString(const std::vector<std::string>& parts, | 901 std::string JoinString(const std::vector<std::string>& parts, |
906 StringPiece separator) { | 902 StringPiece separator) { |
907 return JoinStringT(parts, separator); | 903 return JoinStringT(parts, separator); |
908 } | 904 } |
909 | 905 |
910 string16 JoinString(const std::vector<string16>& parts, | 906 string16 JoinString(const std::vector<string16>& parts, |
911 StringPiece16 separator) { | 907 StringPiece16 separator) { |
912 return JoinStringT(parts, separator); | 908 return JoinStringT(parts, separator); |
913 } | 909 } |
914 | 910 |
915 } // namespace base | |
916 | |
917 template<class FormatStringType, class OutStringType> | 911 template<class FormatStringType, class OutStringType> |
918 OutStringType DoReplaceStringPlaceholders(const FormatStringType& format_string, | 912 OutStringType DoReplaceStringPlaceholders( |
919 const std::vector<OutStringType>& subst, std::vector<size_t>* offsets) { | 913 const FormatStringType& format_string, |
| 914 const std::vector<OutStringType>& subst, |
| 915 std::vector<size_t>* offsets) { |
920 size_t substitutions = subst.size(); | 916 size_t substitutions = subst.size(); |
921 | 917 |
922 size_t sub_length = 0; | 918 size_t sub_length = 0; |
923 for (typename std::vector<OutStringType>::const_iterator iter = subst.begin(); | 919 for (const auto& cur : subst) |
924 iter != subst.end(); ++iter) { | 920 sub_length += cur.length(); |
925 sub_length += iter->length(); | |
926 } | |
927 | 921 |
928 OutStringType formatted; | 922 OutStringType formatted; |
929 formatted.reserve(format_string.length() + sub_length); | 923 formatted.reserve(format_string.length() + sub_length); |
930 | 924 |
931 std::vector<ReplacementOffset> r_offsets; | 925 std::vector<ReplacementOffset> r_offsets; |
932 for (typename FormatStringType::const_iterator i = format_string.begin(); | 926 for (auto i = format_string.begin(); i != format_string.end(); ++i) { |
933 i != format_string.end(); ++i) { | |
934 if ('$' == *i) { | 927 if ('$' == *i) { |
935 if (i + 1 != format_string.end()) { | 928 if (i + 1 != format_string.end()) { |
936 ++i; | 929 ++i; |
937 DCHECK('$' == *i || '1' <= *i) << "Invalid placeholder: " << *i; | 930 DCHECK('$' == *i || '1' <= *i) << "Invalid placeholder: " << *i; |
938 if ('$' == *i) { | 931 if ('$' == *i) { |
939 while (i != format_string.end() && '$' == *i) { | 932 while (i != format_string.end() && '$' == *i) { |
940 formatted.push_back('$'); | 933 formatted.push_back('$'); |
941 ++i; | 934 ++i; |
942 } | 935 } |
943 --i; | 936 --i; |
(...skipping 17 matching lines...) Expand all Loading... |
961 } | 954 } |
962 if (index < substitutions) | 955 if (index < substitutions) |
963 formatted.append(subst.at(index)); | 956 formatted.append(subst.at(index)); |
964 } | 957 } |
965 } | 958 } |
966 } else { | 959 } else { |
967 formatted.push_back(*i); | 960 formatted.push_back(*i); |
968 } | 961 } |
969 } | 962 } |
970 if (offsets) { | 963 if (offsets) { |
971 for (std::vector<ReplacementOffset>::const_iterator i = r_offsets.begin(); | 964 for (const auto& cur : r_offsets) |
972 i != r_offsets.end(); ++i) { | 965 offsets->push_back(cur.offset); |
973 offsets->push_back(i->offset); | |
974 } | |
975 } | 966 } |
976 return formatted; | 967 return formatted; |
977 } | 968 } |
978 | 969 |
979 string16 ReplaceStringPlaceholders(const string16& format_string, | 970 string16 ReplaceStringPlaceholders(const string16& format_string, |
980 const std::vector<string16>& subst, | 971 const std::vector<string16>& subst, |
981 std::vector<size_t>* offsets) { | 972 std::vector<size_t>* offsets) { |
982 return DoReplaceStringPlaceholders(format_string, subst, offsets); | 973 return DoReplaceStringPlaceholders(format_string, subst, offsets); |
983 } | 974 } |
984 | 975 |
985 std::string ReplaceStringPlaceholders(const base::StringPiece& format_string, | 976 std::string ReplaceStringPlaceholders(const StringPiece& format_string, |
986 const std::vector<std::string>& subst, | 977 const std::vector<std::string>& subst, |
987 std::vector<size_t>* offsets) { | 978 std::vector<size_t>* offsets) { |
988 return DoReplaceStringPlaceholders(format_string, subst, offsets); | 979 return DoReplaceStringPlaceholders(format_string, subst, offsets); |
989 } | 980 } |
990 | 981 |
991 string16 ReplaceStringPlaceholders(const string16& format_string, | 982 string16 ReplaceStringPlaceholders(const string16& format_string, |
992 const string16& a, | 983 const string16& a, |
993 size_t* offset) { | 984 size_t* offset) { |
994 std::vector<size_t> offsets; | 985 std::vector<size_t> offsets; |
995 std::vector<string16> subst; | 986 std::vector<string16> subst; |
(...skipping 23 matching lines...) Expand all Loading... |
1019 if (dst_size != 0) | 1010 if (dst_size != 0) |
1020 dst[dst_size - 1] = 0; | 1011 dst[dst_size - 1] = 0; |
1021 | 1012 |
1022 // Count the rest of the |src|, and return it's length in characters. | 1013 // Count the rest of the |src|, and return it's length in characters. |
1023 while (src[dst_size]) ++dst_size; | 1014 while (src[dst_size]) ++dst_size; |
1024 return dst_size; | 1015 return dst_size; |
1025 } | 1016 } |
1026 | 1017 |
1027 } // namespace | 1018 } // namespace |
1028 | 1019 |
1029 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { | 1020 size_t strlcpy(char* dst, const char* src, size_t dst_size) { |
1030 return lcpyT<char>(dst, src, dst_size); | 1021 return lcpyT<char>(dst, src, dst_size); |
1031 } | 1022 } |
1032 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { | 1023 size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { |
1033 return lcpyT<wchar_t>(dst, src, dst_size); | 1024 return lcpyT<wchar_t>(dst, src, dst_size); |
1034 } | 1025 } |
| 1026 |
| 1027 } // namespace base |
OLD | NEW |