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

Side by Side Diff: base/string_util.cc

Issue 11423: Remove the locale parameter from the StringToDouble and (Closed)
Patch Set: more comments 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') | base/third_party/dmg_fp/dmg_fp.h » ('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" 7 #include "build/build_config.h"
8 8
9 #include <ctype.h> 9 #include <ctype.h>
10 #include <errno.h> 10 #include <errno.h>
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 // - a typedef for value_type, the target numeric type. 82 // - a typedef for value_type, the target numeric type.
83 // - a static function, convert_func, which dispatches to an appropriate 83 // - a static function, convert_func, which dispatches to an appropriate
84 // strtol-like function and returns type value_type. 84 // strtol-like function and returns type value_type.
85 // - 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
86 // 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
87 // conditions that convert_func tolerates but should result in 87 // conditions that convert_func tolerates but should result in
88 // StringToNumber returning false. For strtol-like funtions, valid_func 88 // StringToNumber returning false. For strtol-like funtions, valid_func
89 // should check for leading whitespace. 89 // should check for leading whitespace.
90 template<typename StringToNumberTraits> 90 template<typename StringToNumberTraits>
91 bool StringToNumber(const typename StringToNumberTraits::string_type& input, 91 bool StringToNumber(const typename StringToNumberTraits::string_type& input,
92 typename StringToNumberTraits::value_type* output, 92 typename StringToNumberTraits::value_type* output) {
93 base::LocaleDependence locale_dependent) {
94 typedef StringToNumberTraits traits; 93 typedef StringToNumberTraits traits;
95 94
96 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. 95 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows.
97 typename traits::string_type::value_type* endptr = NULL; 96 typename traits::string_type::value_type* endptr = NULL;
98 typename traits::value_type value = traits::convert_func(input.c_str(), 97 typename traits::value_type value = traits::convert_func(input.c_str(),
99 &endptr, locale_dependent == base::LOCALE_DEPENDENT); 98 &endptr);
100 *output = value; 99 *output = value;
101 100
102 // Cases to return false: 101 // Cases to return false:
103 // - If errno is ERANGE, there was an overflow or underflow. 102 // - If errno is ERANGE, there was an overflow or underflow.
104 // - If the input string is empty, there was nothing to parse. 103 // - If the input string is empty, there was nothing to parse.
105 // - If endptr does not point to the end of the string, there are either 104 // - If endptr does not point to the end of the string, there are either
106 // characters remaining in the string after a parsed number, or the string 105 // characters remaining in the string after a parsed number, or the string
107 // does not begin with a parseable number. endptr is compared to the 106 // does not begin with a parseable number. endptr is compared to the
108 // expected end given the string's stated length to correctly catch cases 107 // expected end given the string's stated length to correctly catch cases
109 // where the string contains embedded NUL characters. 108 // where the string contains embedded NUL characters.
110 // - valid_func determines that the input is not in preferred form. 109 // - valid_func determines that the input is not in preferred form.
111 return errno == 0 && 110 return errno == 0 &&
112 !input.empty() && 111 !input.empty() &&
113 input.c_str() + input.length() == endptr && 112 input.c_str() + input.length() == endptr &&
114 traits::valid_func(input); 113 traits::valid_func(input);
115 } 114 }
116 115
117 class StringToLongTraits { 116 class StringToLongTraits {
118 public: 117 public:
119 typedef std::string string_type; 118 typedef std::string string_type;
120 typedef long value_type; 119 typedef long value_type;
121 static const int kBase = 10; 120 static const int kBase = 10;
122 static inline value_type convert_func(const string_type::value_type* str, 121 static inline value_type convert_func(const string_type::value_type* str,
123 string_type::value_type** endptr, 122 string_type::value_type** endptr) {
124 bool locale_dependent) {
125 return strtol(str, endptr, kBase); 123 return strtol(str, endptr, kBase);
126 } 124 }
127 static inline bool valid_func(const string_type& str) { 125 static inline bool valid_func(const string_type& str) {
128 return !str.empty() && !isspace(str[0]); 126 return !str.empty() && !isspace(str[0]);
129 } 127 }
130 }; 128 };
131 129
132 class WStringToLongTraits { 130 class WStringToLongTraits {
133 public: 131 public:
134 typedef std::wstring string_type; 132 typedef std::wstring string_type;
135 typedef long value_type; 133 typedef long value_type;
136 static const int kBase = 10; 134 static const int kBase = 10;
137 static inline value_type convert_func(const string_type::value_type* str, 135 static inline value_type convert_func(const string_type::value_type* str,
138 string_type::value_type** endptr, 136 string_type::value_type** endptr) {
139 bool locale_dependent) {
140 return wcstol(str, endptr, kBase); 137 return wcstol(str, endptr, kBase);
141 } 138 }
142 static inline bool valid_func(const string_type& str) { 139 static inline bool valid_func(const string_type& str) {
143 return !str.empty() && !iswspace(str[0]); 140 return !str.empty() && !iswspace(str[0]);
144 } 141 }
145 }; 142 };
146 143
147 class StringToInt64Traits { 144 class StringToInt64Traits {
148 public: 145 public:
149 typedef std::string string_type; 146 typedef std::string string_type;
150 typedef int64 value_type; 147 typedef int64 value_type;
151 static const int kBase = 10; 148 static const int kBase = 10;
152 static inline value_type convert_func(const string_type::value_type* str, 149 static inline value_type convert_func(const string_type::value_type* str,
153 string_type::value_type** endptr, 150 string_type::value_type** endptr) {
154 bool locale_dependent) {
155 #ifdef OS_WIN 151 #ifdef OS_WIN
156 return _strtoi64(str, endptr, kBase); 152 return _strtoi64(str, endptr, kBase);
157 #else // assume OS_POSIX 153 #else // assume OS_POSIX
158 return strtoll(str, endptr, kBase); 154 return strtoll(str, endptr, kBase);
159 #endif 155 #endif
160 } 156 }
161 static inline bool valid_func(const string_type& str) { 157 static inline bool valid_func(const string_type& str) {
162 return !str.empty() && !isspace(str[0]); 158 return !str.empty() && !isspace(str[0]);
163 } 159 }
164 }; 160 };
165 161
166 class WStringToInt64Traits { 162 class WStringToInt64Traits {
167 public: 163 public:
168 typedef std::wstring string_type; 164 typedef std::wstring string_type;
169 typedef int64 value_type; 165 typedef int64 value_type;
170 static const int kBase = 10; 166 static const int kBase = 10;
171 static inline value_type convert_func(const string_type::value_type* str, 167 static inline value_type convert_func(const string_type::value_type* str,
172 string_type::value_type** endptr, 168 string_type::value_type** endptr) {
173 bool locale_dependent) {
174 #ifdef OS_WIN 169 #ifdef OS_WIN
175 return _wcstoi64(str, endptr, kBase); 170 return _wcstoi64(str, endptr, kBase);
176 #else // assume OS_POSIX 171 #else // assume OS_POSIX
177 return wcstoll(str, endptr, kBase); 172 return wcstoll(str, endptr, kBase);
178 #endif 173 #endif
179 } 174 }
180 static inline bool valid_func(const string_type& str) { 175 static inline bool valid_func(const string_type& str) {
181 return !str.empty() && !iswspace(str[0]); 176 return !str.empty() && !iswspace(str[0]);
182 } 177 }
183 }; 178 };
184 179
185 // For the HexString variants, use the unsigned variants like strtoul for 180 // For the HexString variants, use the unsigned variants like strtoul for
186 // convert_func so that input like "0x80000000" doesn't result in an overflow. 181 // convert_func so that input like "0x80000000" doesn't result in an overflow.
187 182
188 class HexStringToLongTraits { 183 class HexStringToLongTraits {
189 public: 184 public:
190 typedef std::string string_type; 185 typedef std::string string_type;
191 typedef long value_type; 186 typedef long value_type;
192 static const int kBase = 16; 187 static const int kBase = 16;
193 static inline value_type convert_func(const string_type::value_type* str, 188 static inline value_type convert_func(const string_type::value_type* str,
194 string_type::value_type** endptr, 189 string_type::value_type** endptr) {
195 bool locale_dependent) {
196 return strtoul(str, endptr, kBase); 190 return strtoul(str, endptr, kBase);
197 } 191 }
198 static inline bool valid_func(const string_type& str) { 192 static inline bool valid_func(const string_type& str) {
199 return !str.empty() && !isspace(str[0]); 193 return !str.empty() && !isspace(str[0]);
200 } 194 }
201 }; 195 };
202 196
203 class HexWStringToLongTraits { 197 class HexWStringToLongTraits {
204 public: 198 public:
205 typedef std::wstring string_type; 199 typedef std::wstring string_type;
206 typedef long value_type; 200 typedef long value_type;
207 static const int kBase = 16; 201 static const int kBase = 16;
208 static inline value_type convert_func(const string_type::value_type* str, 202 static inline value_type convert_func(const string_type::value_type* str,
209 string_type::value_type** endptr, 203 string_type::value_type** endptr) {
210 bool locale_dependent) {
211 return wcstoul(str, endptr, kBase); 204 return wcstoul(str, endptr, kBase);
212 } 205 }
213 static inline bool valid_func(const string_type& str) { 206 static inline bool valid_func(const string_type& str) {
214 return !str.empty() && !iswspace(str[0]); 207 return !str.empty() && !iswspace(str[0]);
215 } 208 }
216 }; 209 };
217 210
218 class StringToDoubleTraits { 211 class StringToDoubleTraits {
219 public: 212 public:
220 typedef std::string string_type; 213 typedef std::string string_type;
221 typedef double value_type; 214 typedef double value_type;
222 static inline value_type convert_func(const string_type::value_type* str, 215 static inline value_type convert_func(const string_type::value_type* str,
223 string_type::value_type** endptr, 216 string_type::value_type** endptr) {
224 bool locale_dependent) { 217 return dmg_fp::strtod(str, endptr);
225 if (locale_dependent) {
226 return strtod(str, endptr);
227 } else {
228 return dmg_fp::strtod(str, endptr);
229 }
230 } 218 }
231 static inline bool valid_func(const string_type& str) { 219 static inline bool valid_func(const string_type& str) {
232 return !str.empty() && !isspace(str[0]); 220 return !str.empty() && !isspace(str[0]);
233 } 221 }
234 }; 222 };
235 223
236 class WStringToDoubleTraits { 224 class WStringToDoubleTraits {
237 public: 225 public:
238 typedef std::wstring string_type; 226 typedef std::wstring string_type;
239 typedef double value_type; 227 typedef double value_type;
240 static inline value_type convert_func(const string_type::value_type* str, 228 static inline value_type convert_func(const string_type::value_type* str,
241 string_type::value_type** endptr, 229 string_type::value_type** endptr) {
242 bool locale_dependent) { 230 // Because dmg_fp::strtod does not like wchar_t, we convert it to ASCII.
243 if (locale_dependent) { 231 // In theory, this should be safe, but it's possible that wide chars
244 return wcstod(str, endptr); 232 // might get ignored by accident causing something to be parsed when it
245 } else { 233 // shouldn't.
246 // Because dmg_fp::strtod does not like wchar_t, we convert it to ASCII. 234 std::string ascii_string = WideToASCII(std::wstring(str));
247 // In theory, this should be safe, but it's possible that wide chars 235 char* ascii_end = NULL;
248 // might get ignored by accident causing something to be parsed when it 236 value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end);
249 // shouldn't. 237 if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
250 std::string ascii_string = WideToASCII(std::wstring(str)); 238 // Put endptr at end of input string, so it's not recognized as an error.
251 char* ascii_end = NULL; 239 *endptr = const_cast<string_type::value_type*>(str) + wcslen(str);
252 value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end); 240 }
253 if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
254 // Put endptr at end of input string, so it's not recognized as an error .
255 *endptr = const_cast<string_type::value_type*>(str) + wcslen(str);
256 }
257 241
258 return ret; 242 return ret;
259 }
260 } 243 }
261 static inline bool valid_func(const string_type& str) { 244 static inline bool valid_func(const string_type& str) {
262 return !str.empty() && !iswspace(str[0]); 245 return !str.empty() && !iswspace(str[0]);
263 } 246 }
264 }; 247 };
265 248
266 } // namespace 249 } // namespace
267 250
268 251
269 namespace base { 252 namespace base {
(...skipping 28 matching lines...) Expand all
298 in_specification = false; 281 in_specification = false;
299 } 282 }
300 } 283 }
301 } 284 }
302 285
303 } 286 }
304 287
305 return true; 288 return true;
306 } 289 }
307 290
308 std::string DoubleToString(double value, LocaleDependence locale_dependent) {
309 if (LOCALE_DEPENDENT == locale_dependent) {
310 return StringPrintf("%g", value);
311 } else {
312 char buffer[32];
313 dmg_fp::g_fmt(buffer, value);
314 return std::string(buffer);
315 }
316 }
317
318 std::wstring DoubleToWString(double value, LocaleDependence locale_dependent) {
319 return ASCIIToWide(DoubleToString(value, locale_dependent));
320 }
321
322 bool StringToDouble(const std::string& input, double* output,
323 LocaleDependence locale_dependent) {
324 return StringToNumber<StringToDoubleTraits>(input, output,
325 locale_dependent);
326 }
327
328 bool StringToDouble(const std::wstring& input, double* output,
329 LocaleDependence locale_dependent) {
330 return StringToNumber<WStringToDoubleTraits>(input, output,
331 locale_dependent);
332 }
333
334 double StringToDouble(const std::string& value,
335 LocaleDependence locale_dependent) {
336 double result;
337 StringToDouble(value, &result, locale_dependent);
338 return result;
339 }
340
341 double StringToDouble(const std::wstring& value,
342 LocaleDependence locale_dependent) {
343 double result;
344 StringToDouble(value, &result, locale_dependent);
345 return result;
346 }
347 291
348 } // namespace base 292 } // namespace base
349 293
350 294
351 const std::string& EmptyString() { 295 const std::string& EmptyString() {
352 return *Singleton<std::string>::get(); 296 return *Singleton<std::string>::get();
353 } 297 }
354 298
355 const std::wstring& EmptyWString() { 299 const std::wstring& EmptyWString() {
356 return *Singleton<std::wstring>::get(); 300 return *Singleton<std::wstring>::get();
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 } 991 }
1048 std::string Uint64ToString(uint64 value) { 992 std::string Uint64ToString(uint64 value) {
1049 return IntToStringT<std::string, uint64, uint64, false>:: 993 return IntToStringT<std::string, uint64, uint64, false>::
1050 IntToString(value); 994 IntToString(value);
1051 } 995 }
1052 std::wstring Uint64ToWString(uint64 value) { 996 std::wstring Uint64ToWString(uint64 value) {
1053 return IntToStringT<std::wstring, uint64, uint64, false>:: 997 return IntToStringT<std::wstring, uint64, uint64, false>::
1054 IntToString(value); 998 IntToString(value);
1055 } 999 }
1056 1000
1001 std::string DoubleToString(double value) {
1002 // According to g_fmt.cc, it is sufficient to declare a buffer of size 32.
1003 char buffer[32];
1004 dmg_fp::g_fmt(buffer, value);
1005 return std::string(buffer);
1006 }
1007
1008 std::wstring DoubleToWString(double value) {
1009 return ASCIIToWide(DoubleToString(value));
1010 }
1011
1057 inline void StringAppendV(std::string* dst, const char* format, va_list ap) { 1012 inline void StringAppendV(std::string* dst, const char* format, va_list ap) {
1058 StringAppendVT<char>(dst, format, ap); 1013 StringAppendVT<char>(dst, format, ap);
1059 } 1014 }
1060 1015
1061 inline void StringAppendV(std::wstring* dst, 1016 inline void StringAppendV(std::wstring* dst,
1062 const wchar_t* format, 1017 const wchar_t* format,
1063 va_list ap) { 1018 va_list ap) {
1064 StringAppendVT<wchar_t>(dst, format, ap); 1019 StringAppendVT<wchar_t>(dst, format, ap);
1065 } 1020 }
1066 1021
1067 bool StringToDouble(const std::string& input, double* output) {
1068 return StringToDouble(input, output, base::LOCALE_DEPENDENT);
1069 }
1070
1071 bool StringToDouble(const std::wstring& input, double* output) {
1072 return StringToDouble(input, output, base::LOCALE_DEPENDENT);
1073 }
1074
1075 double StringToDouble(const std::string& value) {
1076 return StringToDouble(value, base::LOCALE_DEPENDENT);
1077 }
1078
1079 double StringToDouble(const std::wstring& value) {
1080 return StringToDouble(value, base::LOCALE_DEPENDENT);
1081 }
1082
1083 std::string StringPrintf(const char* format, ...) { 1022 std::string StringPrintf(const char* format, ...) {
1084 va_list ap; 1023 va_list ap;
1085 va_start(ap, format); 1024 va_start(ap, format);
1086 std::string result; 1025 std::string result;
1087 StringAppendV(&result, format, ap); 1026 StringAppendV(&result, format, ap);
1088 va_end(ap); 1027 va_end(ap);
1089 return result; 1028 return result;
1090 } 1029 }
1091 1030
1092 std::wstring StringPrintf(const wchar_t* format, ...) { 1031 std::wstring StringPrintf(const wchar_t* format, ...) {
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } 1351 }
1413 1352
1414 // For the various *ToInt conversions, there are no *ToIntTraits classes to use 1353 // For the various *ToInt conversions, there are no *ToIntTraits classes to use
1415 // because there's no such thing as strtoi. Use *ToLongTraits through a cast 1354 // because there's no such thing as strtoi. Use *ToLongTraits through a cast
1416 // instead, requiring that long and int are compatible and equal-width. They 1355 // instead, requiring that long and int are compatible and equal-width. They
1417 // are on our target platforms. 1356 // are on our target platforms.
1418 1357
1419 bool StringToInt(const std::string& input, int* output) { 1358 bool StringToInt(const std::string& input, int* output) {
1420 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); 1359 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
1421 return StringToNumber<StringToLongTraits>(input, 1360 return StringToNumber<StringToLongTraits>(input,
1422 reinterpret_cast<long*>(output), 1361 reinterpret_cast<long*>(output));
1423 base::LOCALE_DEPENDENT);
1424 } 1362 }
1425 1363
1426 bool StringToInt(const std::wstring& input, int* output) { 1364 bool StringToInt(const std::wstring& input, int* output) {
1427 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); 1365 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
1428 return StringToNumber<WStringToLongTraits>(input, 1366 return StringToNumber<WStringToLongTraits>(input,
1429 reinterpret_cast<long*>(output), 1367 reinterpret_cast<long*>(output));
1430 base::LOCALE_DEPENDENT);
1431 } 1368 }
1432 1369
1433 bool StringToInt64(const std::string& input, int64* output) { 1370 bool StringToInt64(const std::string& input, int64* output) {
1434 return StringToNumber<StringToInt64Traits>(input, output, base::LOCALE_DEPENDE NT); 1371 return StringToNumber<StringToInt64Traits>(input, output);
1435 } 1372 }
1436 1373
1437 bool StringToInt64(const std::wstring& input, int64* output) { 1374 bool StringToInt64(const std::wstring& input, int64* output) {
1438 return StringToNumber<WStringToInt64Traits>(input, output, base::LOCALE_DEPEND ENT); 1375 return StringToNumber<WStringToInt64Traits>(input, output);
1439 } 1376 }
1440 1377
1441 bool HexStringToInt(const std::string& input, int* output) { 1378 bool HexStringToInt(const std::string& input, int* output) {
1442 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); 1379 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
1443 return StringToNumber<HexStringToLongTraits>(input, 1380 return StringToNumber<HexStringToLongTraits>(input,
1444 reinterpret_cast<long*>(output), 1381 reinterpret_cast<long*>(output));
1445 base::LOCALE_DEPENDENT);
1446 } 1382 }
1447 1383
1448 bool HexStringToInt(const std::wstring& input, int* output) { 1384 bool HexStringToInt(const std::wstring& input, int* output) {
1449 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); 1385 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
1450 return StringToNumber<HexWStringToLongTraits>( 1386 return StringToNumber<HexWStringToLongTraits>(
1451 input, reinterpret_cast<long*>(output), base::LOCALE_DEPENDENT); 1387 input, reinterpret_cast<long*>(output));
1452 } 1388 }
1453 1389
1454 int StringToInt(const std::string& value) { 1390 int StringToInt(const std::string& value) {
1455 int result; 1391 int result;
1456 StringToInt(value, &result); 1392 StringToInt(value, &result);
1457 return result; 1393 return result;
1458 } 1394 }
1459 1395
1460 int StringToInt(const std::wstring& value) { 1396 int StringToInt(const std::wstring& value) {
1461 int result; 1397 int result;
(...skipping 18 matching lines...) Expand all
1480 HexStringToInt(value, &result); 1416 HexStringToInt(value, &result);
1481 return result; 1417 return result;
1482 } 1418 }
1483 1419
1484 int HexStringToInt(const std::wstring& value) { 1420 int HexStringToInt(const std::wstring& value) {
1485 int result; 1421 int result;
1486 HexStringToInt(value, &result); 1422 HexStringToInt(value, &result);
1487 return result; 1423 return result;
1488 } 1424 }
1489 1425
1426 bool StringToDouble(const std::string& input, double* output) {
1427 return StringToNumber<StringToDoubleTraits>(input, output);
1428 }
1429
1430 bool StringToDouble(const std::wstring& input, double* output) {
1431 return StringToNumber<WStringToDoubleTraits>(input, output);
1432 }
1433
1434 double StringToDouble(const std::string& value) {
1435 double result;
1436 StringToDouble(value, &result);
1437 return result;
1438 }
1439
1440 double StringToDouble(const std::wstring& value) {
1441 double result;
1442 StringToDouble(value, &result);
1443 return result;
1444 }
1445
1490 // The following code is compatible with the OpenBSD lcpy interface. See: 1446 // The following code is compatible with the OpenBSD lcpy interface. See:
1491 // http://www.gratisoft.us/todd/papers/strlcpy.html 1447 // http://www.gratisoft.us/todd/papers/strlcpy.html
1492 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c 1448 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c
1493 1449
1494 namespace { 1450 namespace {
1495 1451
1496 template <typename CHAR> 1452 template <typename CHAR>
1497 size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) { 1453 size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) {
1498 for (size_t i = 0; i < dst_size; ++i) { 1454 for (size_t i = 0; i < dst_size; ++i) {
1499 if ((dst[i] = src[i]) == 0) // We hit and copied the terminating NULL. 1455 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
1547 int rstr_len = (max_len - 3) / 2; 1503 int rstr_len = (max_len - 3) / 2;
1548 int lstr_len = rstr_len + ((max_len - 3) % 2); 1504 int lstr_len = rstr_len + ((max_len - 3) % 2);
1549 output->assign(input.substr(0, lstr_len) + L"..." + 1505 output->assign(input.substr(0, lstr_len) + L"..." +
1550 input.substr(input.length() - rstr_len)); 1506 input.substr(input.length() - rstr_len));
1551 break; 1507 break;
1552 } 1508 }
1553 } 1509 }
1554 1510
1555 return true; 1511 return true;
1556 } 1512 }
OLDNEW
« no previous file with comments | « base/string_util.h ('k') | base/third_party/dmg_fp/dmg_fp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698