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

Side by Side Diff: base/string_util.cc

Issue 11002: Make unit_tests pass with pt_BR.UTF-8 locale. (Closed)
Patch Set: all platforms Created 12 years, 1 month 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
« no previous file with comments | « base/string_util.h ('k') | build/SConscript.main » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/string_util.h" 5 #include "base/string_util.h"
6 6
7 #include "build/build_config.h"
8
7 #include <ctype.h> 9 #include <ctype.h>
8 #include <errno.h> 10 #include <errno.h>
9 #include <math.h> 11 #include <math.h>
10 #include <stdarg.h> 12 #include <stdarg.h>
11 #include <stdio.h> 13 #include <stdio.h>
12 #include <stdlib.h> 14 #include <stdlib.h>
13 #include <string.h> 15 #include <string.h>
14 #include <time.h> 16 #include <time.h>
15 #include <wchar.h> 17 #include <wchar.h>
16 #include <wctype.h> 18 #include <wctype.h>
17 19
18 #include <algorithm> 20 #include <algorithm>
19 #include <vector> 21 #include <vector>
20 22
21 #include "base/basictypes.h" 23 #include "base/basictypes.h"
22 #include "base/logging.h" 24 #include "base/logging.h"
23 #include "base/singleton.h" 25 #include "base/singleton.h"
26 #include "third_party/dmg_fp/dmg_fp.h"
24 27
25 namespace { 28 namespace {
26 29
27 // Hack to convert any char-like type to its unsigned counterpart. 30 // Hack to convert any char-like type to its unsigned counterpart.
28 // For example, it will convert char, signed char and unsigned char to unsigned 31 // For example, it will convert char, signed char and unsigned char to unsigned
29 // char. 32 // char.
30 template<typename T> 33 template<typename T>
31 struct ToUnsigned { 34 struct ToUnsigned {
32 typedef T Unsigned; 35 typedef T Unsigned;
33 }; 36 };
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // - a typedef for value_type, the target numeric type. 82 // - a typedef for value_type, the target numeric type.
80 // - a static function, convert_func, which dispatches to an appropriate 83 // - a static function, convert_func, which dispatches to an appropriate
81 // strtol-like function and returns type value_type. 84 // strtol-like function and returns type value_type.
82 // - a static function, valid_func, which validates |input| and returns a bool 85 // - a static function, valid_func, which validates |input| and returns a bool
83 // indicating whether it is in proper form. This is used to check for 86 // indicating whether it is in proper form. This is used to check for
84 // conditions that convert_func tolerates but should result in 87 // conditions that convert_func tolerates but should result in
85 // StringToNumber returning false. For strtol-like funtions, valid_func 88 // StringToNumber returning false. For strtol-like funtions, valid_func
86 // should check for leading whitespace. 89 // should check for leading whitespace.
87 template<typename StringToNumberTraits> 90 template<typename StringToNumberTraits>
88 bool StringToNumber(const typename StringToNumberTraits::string_type& input, 91 bool StringToNumber(const typename StringToNumberTraits::string_type& input,
89 typename StringToNumberTraits::value_type* output) { 92 typename StringToNumberTraits::value_type* output,
93 base::LocaleDependence locale_dependent) {
90 typedef StringToNumberTraits traits; 94 typedef StringToNumberTraits traits;
91 95
92 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. 96 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows.
93 typename traits::string_type::value_type* endptr = NULL; 97 typename traits::string_type::value_type* endptr = NULL;
94 typename traits::value_type value = traits::convert_func(input.c_str(), 98 typename traits::value_type value = traits::convert_func(input.c_str(),
95 &endptr); 99 &endptr, locale_dependent == base::LOCALE_DEPENDENT);
96 *output = value; 100 *output = value;
97 101
98 // Cases to return false: 102 // Cases to return false:
99 // - If errno is ERANGE, there was an overflow or underflow. 103 // - If errno is ERANGE, there was an overflow or underflow.
100 // - If the input string is empty, there was nothing to parse. 104 // - If the input string is empty, there was nothing to parse.
101 // - If endptr does not point to the end of the string, there are either 105 // - If endptr does not point to the end of the string, there are either
102 // characters remaining in the string after a parsed number, or the string 106 // characters remaining in the string after a parsed number, or the string
103 // does not begin with a parseable number. endptr is compared to the 107 // does not begin with a parseable number. endptr is compared to the
104 // expected end given the string's stated length to correctly catch cases 108 // expected end given the string's stated length to correctly catch cases
105 // where the string contains embedded NUL characters. 109 // where the string contains embedded NUL characters.
106 // - valid_func determines that the input is not in preferred form. 110 // - valid_func determines that the input is not in preferred form.
107 return errno == 0 && 111 return errno == 0 &&
108 !input.empty() && 112 !input.empty() &&
109 input.c_str() + input.length() == endptr && 113 input.c_str() + input.length() == endptr &&
110 traits::valid_func(input); 114 traits::valid_func(input);
111 } 115 }
112 116
113 class StringToLongTraits { 117 class StringToLongTraits {
114 public: 118 public:
115 typedef std::string string_type; 119 typedef std::string string_type;
116 typedef long value_type; 120 typedef long value_type;
117 static const int kBase = 10; 121 static const int kBase = 10;
118 static inline value_type convert_func(const string_type::value_type* str, 122 static inline value_type convert_func(const string_type::value_type* str,
119 string_type::value_type** endptr) { 123 string_type::value_type** endptr,
124 bool locale_dependent) {
120 return strtol(str, endptr, kBase); 125 return strtol(str, endptr, kBase);
121 } 126 }
122 static inline bool valid_func(const string_type& str) { 127 static inline bool valid_func(const string_type& str) {
123 return !str.empty() && !isspace(str[0]); 128 return !str.empty() && !isspace(str[0]);
124 } 129 }
125 }; 130 };
126 131
127 class WStringToLongTraits { 132 class WStringToLongTraits {
128 public: 133 public:
129 typedef std::wstring string_type; 134 typedef std::wstring string_type;
130 typedef long value_type; 135 typedef long value_type;
131 static const int kBase = 10; 136 static const int kBase = 10;
132 static inline value_type convert_func(const string_type::value_type* str, 137 static inline value_type convert_func(const string_type::value_type* str,
133 string_type::value_type** endptr) { 138 string_type::value_type** endptr,
139 bool locale_dependent) {
134 return wcstol(str, endptr, kBase); 140 return wcstol(str, endptr, kBase);
135 } 141 }
136 static inline bool valid_func(const string_type& str) { 142 static inline bool valid_func(const string_type& str) {
137 return !str.empty() && !iswspace(str[0]); 143 return !str.empty() && !iswspace(str[0]);
138 } 144 }
139 }; 145 };
140 146
141 class StringToInt64Traits { 147 class StringToInt64Traits {
142 public: 148 public:
143 typedef std::string string_type; 149 typedef std::string string_type;
144 typedef int64 value_type; 150 typedef int64 value_type;
145 static const int kBase = 10; 151 static const int kBase = 10;
146 static inline value_type convert_func(const string_type::value_type* str, 152 static inline value_type convert_func(const string_type::value_type* str,
147 string_type::value_type** endptr) { 153 string_type::value_type** endptr,
154 bool locale_dependent) {
148 #ifdef OS_WIN 155 #ifdef OS_WIN
149 return _strtoi64(str, endptr, kBase); 156 return _strtoi64(str, endptr, kBase);
150 #else // assume OS_POSIX 157 #else // assume OS_POSIX
151 return strtoll(str, endptr, kBase); 158 return strtoll(str, endptr, kBase);
152 #endif 159 #endif
153 } 160 }
154 static inline bool valid_func(const string_type& str) { 161 static inline bool valid_func(const string_type& str) {
155 return !str.empty() && !isspace(str[0]); 162 return !str.empty() && !isspace(str[0]);
156 } 163 }
157 }; 164 };
158 165
159 class WStringToInt64Traits { 166 class WStringToInt64Traits {
160 public: 167 public:
161 typedef std::wstring string_type; 168 typedef std::wstring string_type;
162 typedef int64 value_type; 169 typedef int64 value_type;
163 static const int kBase = 10; 170 static const int kBase = 10;
164 static inline value_type convert_func(const string_type::value_type* str, 171 static inline value_type convert_func(const string_type::value_type* str,
165 string_type::value_type** endptr) { 172 string_type::value_type** endptr,
173 bool locale_dependent) {
166 #ifdef OS_WIN 174 #ifdef OS_WIN
167 return _wcstoi64(str, endptr, kBase); 175 return _wcstoi64(str, endptr, kBase);
168 #else // assume OS_POSIX 176 #else // assume OS_POSIX
169 return wcstoll(str, endptr, kBase); 177 return wcstoll(str, endptr, kBase);
170 #endif 178 #endif
171 } 179 }
172 static inline bool valid_func(const string_type& str) { 180 static inline bool valid_func(const string_type& str) {
173 return !str.empty() && !iswspace(str[0]); 181 return !str.empty() && !iswspace(str[0]);
174 } 182 }
175 }; 183 };
176 184
177 // For the HexString variants, use the unsigned variants like strtoul for 185 // For the HexString variants, use the unsigned variants like strtoul for
178 // convert_func so that input like "0x80000000" doesn't result in an overflow. 186 // convert_func so that input like "0x80000000" doesn't result in an overflow.
179 187
180 class HexStringToLongTraits { 188 class HexStringToLongTraits {
181 public: 189 public:
182 typedef std::string string_type; 190 typedef std::string string_type;
183 typedef long value_type; 191 typedef long value_type;
184 static const int kBase = 16; 192 static const int kBase = 16;
185 static inline value_type convert_func(const string_type::value_type* str, 193 static inline value_type convert_func(const string_type::value_type* str,
186 string_type::value_type** endptr) { 194 string_type::value_type** endptr,
195 bool locale_dependent) {
187 return strtoul(str, endptr, kBase); 196 return strtoul(str, endptr, kBase);
188 } 197 }
189 static inline bool valid_func(const string_type& str) { 198 static inline bool valid_func(const string_type& str) {
190 return !str.empty() && !isspace(str[0]); 199 return !str.empty() && !isspace(str[0]);
191 } 200 }
192 }; 201 };
193 202
194 class HexWStringToLongTraits { 203 class HexWStringToLongTraits {
195 public: 204 public:
196 typedef std::wstring string_type; 205 typedef std::wstring string_type;
197 typedef long value_type; 206 typedef long value_type;
198 static const int kBase = 16; 207 static const int kBase = 16;
199 static inline value_type convert_func(const string_type::value_type* str, 208 static inline value_type convert_func(const string_type::value_type* str,
200 string_type::value_type** endptr) { 209 string_type::value_type** endptr,
210 bool locale_dependent) {
201 return wcstoul(str, endptr, kBase); 211 return wcstoul(str, endptr, kBase);
202 } 212 }
203 static inline bool valid_func(const string_type& str) { 213 static inline bool valid_func(const string_type& str) {
204 return !str.empty() && !iswspace(str[0]); 214 return !str.empty() && !iswspace(str[0]);
205 } 215 }
206 }; 216 };
207 217
208 class StringToDoubleTraits { 218 class StringToDoubleTraits {
209 public: 219 public:
210 typedef std::string string_type; 220 typedef std::string string_type;
211 typedef double value_type; 221 typedef double value_type;
212 static inline value_type convert_func(const string_type::value_type* str, 222 static inline value_type convert_func(const string_type::value_type* str,
213 string_type::value_type** endptr) { 223 string_type::value_type** endptr,
214 return strtod(str, endptr); 224 bool locale_dependent) {
225 if (locale_dependent) {
226 return strtod(str, endptr);
227 } else {
228 return dmg_fp::strtod(str, endptr);
229 }
215 } 230 }
216 static inline bool valid_func(const string_type& str) { 231 static inline bool valid_func(const string_type& str) {
217 return !str.empty() && !isspace(str[0]); 232 return !str.empty() && !isspace(str[0]);
218 } 233 }
219 }; 234 };
220 235
221 class WStringToDoubleTraits { 236 class WStringToDoubleTraits {
222 public: 237 public:
223 typedef std::wstring string_type; 238 typedef std::wstring string_type;
224 typedef double value_type; 239 typedef double value_type;
225 static inline value_type convert_func(const string_type::value_type* str, 240 static inline value_type convert_func(const string_type::value_type* str,
226 string_type::value_type** endptr) { 241 string_type::value_type** endptr,
227 return wcstod(str, endptr); 242 bool locale_dependent) {
243 if (base::LOCALE_DEPENDENT == locale_dependent) {
244 return wcstod(str, endptr);
245 } else {
246 // We are going to do some interesting things here, just because
247 // dmg_fp::strtod does not like wchar_t. Converting to ASCII should
248 // be fine.
249
250 // Put endptr at end of input string, so it's not recognized as an error.
251 *endptr = const_cast<string_type::value_type*>(str) + wcslen(str);
252
253 std::string ascii_string = WideToASCII(std::wstring(str));
254 return StringToDouble(ascii_string, base::LOCALE_INDEPENDENT);
255 }
228 } 256 }
229 static inline bool valid_func(const string_type& str) { 257 static inline bool valid_func(const string_type& str) {
230 return !str.empty() && !iswspace(str[0]); 258 return !str.empty() && !iswspace(str[0]);
231 } 259 }
232 }; 260 };
233 261
234 } // namespace 262 } // namespace
235 263
236 264
237 namespace base { 265 namespace base {
(...skipping 28 matching lines...) Expand all
266 in_specification = false; 294 in_specification = false;
267 } 295 }
268 } 296 }
269 } 297 }
270 298
271 } 299 }
272 300
273 return true; 301 return true;
274 } 302 }
275 303
304 std::string DoubleToString(double value, LocaleDependence locale_dependent) {
305 if (LOCALE_DEPENDENT == locale_dependent) {
306 return StringPrintf("%g", value);
307 } else {
308 char buffer[32];
309 dmg_fp::g_fmt(buffer, value);
310 return std::string(buffer);
311 }
312 }
313
314 std::wstring DoubleToWString(double value, LocaleDependence locale_dependent) {
315 return ASCIIToWide(DoubleToString(value, locale_dependent));
316 }
317
318 bool StringToDouble(const std::string& input, double* output,
319 LocaleDependence locale_dependent) {
320 return StringToNumber<StringToDoubleTraits>(input, output,
321 locale_dependent);
322 }
323
324 bool StringToDouble(const std::wstring& input, double* output,
325 LocaleDependence locale_dependent) {
326 return StringToNumber<WStringToDoubleTraits>(input, output,
327 locale_dependent);
328 }
329
330 double StringToDouble(const std::string& value,
331 LocaleDependence locale_dependent) {
332 double result;
333 StringToDouble(value, &result, locale_dependent);
334 return result;
335 }
336
337 double StringToDouble(const std::wstring& value,
338 LocaleDependence locale_dependent) {
339 double result;
340 StringToDouble(value, &result, locale_dependent);
341 return result;
342 }
343
276 } // namespace base 344 } // namespace base
277 345
278 346
279 const std::string& EmptyString() { 347 const std::string& EmptyString() {
280 return *Singleton<std::string>::get(); 348 return *Singleton<std::string>::get();
281 } 349 }
282 350
283 const std::wstring& EmptyWString() { 351 const std::wstring& EmptyWString() {
284 return *Singleton<std::wstring>::get(); 352 return *Singleton<std::wstring>::get();
285 } 353 }
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 inline void StringAppendV(std::string* dst, const char* format, va_list ap) { 1053 inline void StringAppendV(std::string* dst, const char* format, va_list ap) {
986 StringAppendVT<char>(dst, format, ap); 1054 StringAppendVT<char>(dst, format, ap);
987 } 1055 }
988 1056
989 inline void StringAppendV(std::wstring* dst, 1057 inline void StringAppendV(std::wstring* dst,
990 const wchar_t* format, 1058 const wchar_t* format,
991 va_list ap) { 1059 va_list ap) {
992 StringAppendVT<wchar_t>(dst, format, ap); 1060 StringAppendVT<wchar_t>(dst, format, ap);
993 } 1061 }
994 1062
1063 bool StringToDouble(const std::string& input, double* output) {
1064 return StringToDouble(input, output, base::LOCALE_DEPENDENT);
1065 }
1066
1067 bool StringToDouble(const std::wstring& input, double* output) {
1068 return StringToDouble(input, output, base::LOCALE_DEPENDENT);
1069 }
1070
1071 double StringToDouble(const std::string& value) {
1072 return StringToDouble(value, base::LOCALE_DEPENDENT);
1073 }
1074
1075 double StringToDouble(const std::wstring& value) {
1076 return StringToDouble(value, base::LOCALE_DEPENDENT);
1077 }
1078
995 std::string StringPrintf(const char* format, ...) { 1079 std::string StringPrintf(const char* format, ...) {
996 va_list ap; 1080 va_list ap;
997 va_start(ap, format); 1081 va_start(ap, format);
998 std::string result; 1082 std::string result;
999 StringAppendV(&result, format, ap); 1083 StringAppendV(&result, format, ap);
1000 va_end(ap); 1084 va_end(ap);
1001 return result; 1085 return result;
1002 } 1086 }
1003 1087
1004 std::wstring StringPrintf(const wchar_t* format, ...) { 1088 std::wstring StringPrintf(const wchar_t* format, ...) {
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 } 1408 }
1325 1409
1326 // For the various *ToInt conversions, there are no *ToIntTraits classes to use 1410 // For the various *ToInt conversions, there are no *ToIntTraits classes to use
1327 // because there's no such thing as strtoi. Use *ToLongTraits through a cast 1411 // because there's no such thing as strtoi. Use *ToLongTraits through a cast
1328 // instead, requiring that long and int are compatible and equal-width. They 1412 // instead, requiring that long and int are compatible and equal-width. They
1329 // are on our target platforms. 1413 // are on our target platforms.
1330 1414
1331 bool StringToInt(const std::string& input, int* output) { 1415 bool StringToInt(const std::string& input, int* output) {
1332 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); 1416 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
1333 return StringToNumber<StringToLongTraits>(input, 1417 return StringToNumber<StringToLongTraits>(input,
1334 reinterpret_cast<long*>(output)); 1418 reinterpret_cast<long*>(output),
1419 base::LOCALE_DEPENDENT);
1335 } 1420 }
1336 1421
1337 bool StringToInt(const std::wstring& input, int* output) { 1422 bool StringToInt(const std::wstring& input, int* output) {
1338 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); 1423 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
1339 return StringToNumber<WStringToLongTraits>(input, 1424 return StringToNumber<WStringToLongTraits>(input,
1340 reinterpret_cast<long*>(output)); 1425 reinterpret_cast<long*>(output),
1426 base::LOCALE_DEPENDENT);
1341 } 1427 }
1342 1428
1343 bool StringToInt64(const std::string& input, int64* output) { 1429 bool StringToInt64(const std::string& input, int64* output) {
1344 return StringToNumber<StringToInt64Traits>(input, output); 1430 return StringToNumber<StringToInt64Traits>(input, output, base::LOCALE_DEPENDE NT);
1345 } 1431 }
1346 1432
1347 bool StringToInt64(const std::wstring& input, int64* output) { 1433 bool StringToInt64(const std::wstring& input, int64* output) {
1348 return StringToNumber<WStringToInt64Traits>(input, output); 1434 return StringToNumber<WStringToInt64Traits>(input, output, base::LOCALE_DEPEND ENT);
1349 } 1435 }
1350 1436
1351 bool HexStringToInt(const std::string& input, int* output) { 1437 bool HexStringToInt(const std::string& input, int* output) {
1352 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); 1438 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
1353 return StringToNumber<HexStringToLongTraits>(input, 1439 return StringToNumber<HexStringToLongTraits>(input,
1354 reinterpret_cast<long*>(output)); 1440 reinterpret_cast<long*>(output),
1441 base::LOCALE_DEPENDENT);
1355 } 1442 }
1356 1443
1357 bool HexStringToInt(const std::wstring& input, int* output) { 1444 bool HexStringToInt(const std::wstring& input, int* output) {
1358 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); 1445 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
1359 return StringToNumber<HexWStringToLongTraits>( 1446 return StringToNumber<HexWStringToLongTraits>(
1360 input, reinterpret_cast<long*>(output)); 1447 input, reinterpret_cast<long*>(output), base::LOCALE_DEPENDENT);
1361 }
1362
1363 bool StringToDouble(const std::string& input, double* output) {
1364 return StringToNumber<StringToDoubleTraits>(input, output);
1365 }
1366
1367 bool StringToDouble(const std::wstring& input, double* output) {
1368 return StringToNumber<WStringToDoubleTraits>(input, output);
1369 } 1448 }
1370 1449
1371 int StringToInt(const std::string& value) { 1450 int StringToInt(const std::string& value) {
1372 int result; 1451 int result;
1373 StringToInt(value, &result); 1452 StringToInt(value, &result);
1374 return result; 1453 return result;
1375 } 1454 }
1376 1455
1377 int StringToInt(const std::wstring& value) { 1456 int StringToInt(const std::wstring& value) {
1378 int result; 1457 int result;
(...skipping 18 matching lines...) Expand all
1397 HexStringToInt(value, &result); 1476 HexStringToInt(value, &result);
1398 return result; 1477 return result;
1399 } 1478 }
1400 1479
1401 int HexStringToInt(const std::wstring& value) { 1480 int HexStringToInt(const std::wstring& value) {
1402 int result; 1481 int result;
1403 HexStringToInt(value, &result); 1482 HexStringToInt(value, &result);
1404 return result; 1483 return result;
1405 } 1484 }
1406 1485
1407 double StringToDouble(const std::string& value) {
1408 double result;
1409 StringToDouble(value, &result);
1410 return result;
1411 }
1412
1413 double StringToDouble(const std::wstring& value) {
1414 double result;
1415 StringToDouble(value, &result);
1416 return result;
1417 }
1418
1419 // The following code is compatible with the OpenBSD lcpy interface. See: 1486 // The following code is compatible with the OpenBSD lcpy interface. See:
1420 // http://www.gratisoft.us/todd/papers/strlcpy.html 1487 // http://www.gratisoft.us/todd/papers/strlcpy.html
1421 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c 1488 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c
1422 1489
1423 namespace { 1490 namespace {
1424 1491
1425 template <typename CHAR> 1492 template <typename CHAR>
1426 size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) { 1493 size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) {
1427 for (size_t i = 0; i < dst_size; ++i) { 1494 for (size_t i = 0; i < dst_size; ++i) {
1428 if ((dst[i] = src[i]) == 0) // We hit and copied the terminating NULL. 1495 if ((dst[i] = src[i]) == 0) // We hit and copied the terminating NULL.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 int rstr_len = (max_len - 3) / 2; 1543 int rstr_len = (max_len - 3) / 2;
1477 int lstr_len = rstr_len + ((max_len - 3) % 2); 1544 int lstr_len = rstr_len + ((max_len - 3) % 2);
1478 output->assign(input.substr(0, lstr_len) + L"..." + 1545 output->assign(input.substr(0, lstr_len) + L"..." +
1479 input.substr(input.length() - rstr_len)); 1546 input.substr(input.length() - rstr_len));
1480 break; 1547 break;
1481 } 1548 }
1482 } 1549 }
1483 1550
1484 return true; 1551 return true;
1485 } 1552 }
OLDNEW
« no previous file with comments | « base/string_util.h ('k') | build/SConscript.main » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698