Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/ipc/chromium/src/base/string_util.cc
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
4
// Use of this source code is governed by a BSD-style license that can be
5
// found in the LICENSE file.
6
7
#include "base/string_util.h"
8
9
#include "build/build_config.h"
10
11
#include <ctype.h>
12
#include <errno.h>
13
#include <math.h>
14
#include <stdarg.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <time.h>
19
#include <wchar.h>
20
#include <wctype.h>
21
22
#include <algorithm>
23
#include <vector>
24
25
#include "base/basictypes.h"
26
#include "base/logging.h"
27
#include "base/singleton.h"
28
29
namespace {
30
31
// Hack to convert any char-like type to its unsigned counterpart.
32
// For example, it will convert char, signed char and unsigned char to unsigned
33
// char.
34
template<typename T>
35
struct ToUnsigned {
36
  typedef T Unsigned;
37
};
38
39
template<>
40
struct ToUnsigned<char> {
41
  typedef unsigned char Unsigned;
42
};
43
template<>
44
struct ToUnsigned<signed char> {
45
  typedef unsigned char Unsigned;
46
};
47
template<>
48
struct ToUnsigned<wchar_t> {
49
#if defined(WCHAR_T_IS_UTF16)
50
  typedef unsigned short Unsigned;
51
#elif defined(WCHAR_T_IS_UTF32)
52
  typedef uint32_t Unsigned;
53
#endif
54
};
55
template<>
56
struct ToUnsigned<short> {
57
  typedef unsigned short Unsigned;
58
};
59
60
// Generalized string-to-number conversion.
61
//
62
// StringToNumberTraits should provide:
63
//  - a typedef for string_type, the STL string type used as input.
64
//  - a typedef for value_type, the target numeric type.
65
//  - a static function, convert_func, which dispatches to an appropriate
66
//    strtol-like function and returns type value_type.
67
//  - a static function, valid_func, which validates |input| and returns a bool
68
//    indicating whether it is in proper form.  This is used to check for
69
//    conditions that convert_func tolerates but should result in
70
//    StringToNumber returning false.  For strtol-like funtions, valid_func
71
//    should check for leading whitespace.
72
template<typename StringToNumberTraits>
73
bool StringToNumber(const typename StringToNumberTraits::string_type& input,
74
0
                    typename StringToNumberTraits::value_type* output) {
75
0
  typedef StringToNumberTraits traits;
76
0
77
0
  errno = 0;  // Thread-safe?  It is on at least Mac, Linux, and Windows.
78
0
  typename traits::string_type::value_type* endptr = NULL;
79
0
  typename traits::value_type value = traits::convert_func(input.c_str(),
80
0
                                                           &endptr);
81
0
  *output = value;
82
0
83
0
  // Cases to return false:
84
0
  //  - If errno is ERANGE, there was an overflow or underflow.
85
0
  //  - If the input string is empty, there was nothing to parse.
86
0
  //  - If endptr does not point to the end of the string, there are either
87
0
  //    characters remaining in the string after a parsed number, or the string
88
0
  //    does not begin with a parseable number.  endptr is compared to the
89
0
  //    expected end given the string's stated length to correctly catch cases
90
0
  //    where the string contains embedded NUL characters.
91
0
  //  - valid_func determines that the input is not in preferred form.
92
0
  return errno == 0 &&
93
0
         !input.empty() &&
94
0
         input.c_str() + input.length() == endptr &&
95
0
         traits::valid_func(input);
96
0
}
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool (anonymous namespace)::StringToNumber<(anonymous namespace)::StringToLongTraits>((anonymous namespace)::StringToLongTraits::string_type const&, (anonymous namespace)::StringToLongTraits::value_type*)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool (anonymous namespace)::StringToNumber<(anonymous namespace)::String16ToLongTraits>((anonymous namespace)::String16ToLongTraits::string_type const&, (anonymous namespace)::String16ToLongTraits::value_type*)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool (anonymous namespace)::StringToNumber<(anonymous namespace)::StringToInt64Traits>((anonymous namespace)::StringToInt64Traits::string_type const&, (anonymous namespace)::StringToInt64Traits::value_type*)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool (anonymous namespace)::StringToNumber<(anonymous namespace)::String16ToInt64Traits>((anonymous namespace)::String16ToInt64Traits::string_type const&, (anonymous namespace)::String16ToInt64Traits::value_type*)
97
98
class StringToLongTraits {
99
 public:
100
  typedef std::string string_type;
101
  typedef long value_type;
102
  static const int kBase = 10;
103
  static inline value_type convert_func(const string_type::value_type* str,
104
0
                                        string_type::value_type** endptr) {
105
0
    return strtol(str, endptr, kBase);
106
0
  }
107
0
  static inline bool valid_func(const string_type& str) {
108
0
    return !str.empty() && !isspace(str[0]);
109
0
  }
110
};
111
112
class String16ToLongTraits {
113
 public:
114
  typedef string16 string_type;
115
  typedef long value_type;
116
  static const int kBase = 10;
117
  static inline value_type convert_func(const string_type::value_type* str,
118
0
                                        string_type::value_type** endptr) {
119
#if defined(WCHAR_T_IS_UTF16)
120
    return wcstol(str, endptr, kBase);
121
#elif defined(WCHAR_T_IS_UTF32)
122
    std::string ascii_string = UTF16ToASCII(string16(str));
123
0
    char* ascii_end = NULL;
124
0
    value_type ret = strtol(ascii_string.c_str(), &ascii_end, kBase);
125
0
    if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
126
0
      *endptr =
127
0
          const_cast<string_type::value_type*>(str) + ascii_string.length();
128
0
    }
129
0
    return ret;
130
0
#endif
131
0
  }
132
0
  static inline bool valid_func(const string_type& str) {
133
0
    return !str.empty() && !iswspace(str[0]);
134
0
  }
135
};
136
137
class StringToInt64Traits {
138
 public:
139
  typedef std::string string_type;
140
  typedef int64_t value_type;
141
  static const int kBase = 10;
142
  static inline value_type convert_func(const string_type::value_type* str,
143
0
                                        string_type::value_type** endptr) {
144
#ifdef OS_WIN
145
    return _strtoi64(str, endptr, kBase);
146
#else  // assume OS_POSIX
147
    return strtoll(str, endptr, kBase);
148
0
#endif
149
0
  }
150
0
  static inline bool valid_func(const string_type& str) {
151
0
    return !str.empty() && !isspace(str[0]);
152
0
  }
153
};
154
155
class String16ToInt64Traits {
156
 public:
157
  typedef string16 string_type;
158
  typedef int64_t value_type;
159
  static const int kBase = 10;
160
  static inline value_type convert_func(const string_type::value_type* str,
161
0
                                        string_type::value_type** endptr) {
162
#ifdef OS_WIN
163
    return _wcstoi64(str, endptr, kBase);
164
#else  // assume OS_POSIX
165
    std::string ascii_string = UTF16ToASCII(string16(str));
166
0
    char* ascii_end = NULL;
167
0
    value_type ret = strtoll(ascii_string.c_str(), &ascii_end, kBase);
168
0
    if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
169
0
      *endptr =
170
0
          const_cast<string_type::value_type*>(str) + ascii_string.length();
171
0
    }
172
0
    return ret;
173
0
#endif
174
0
  }
175
0
  static inline bool valid_func(const string_type& str) {
176
0
    return !str.empty() && !iswspace(str[0]);
177
0
  }
178
};
179
180
}  // namespace
181
182
183
namespace base {
184
185
0
bool IsWprintfFormatPortable(const wchar_t* format) {
186
0
  for (const wchar_t* position = format; *position != '\0'; ++position) {
187
0
188
0
    if (*position == '%') {
189
0
      bool in_specification = true;
190
0
      bool modifier_l = false;
191
0
      while (in_specification) {
192
0
        // Eat up characters until reaching a known specifier.
193
0
        if (*++position == '\0') {
194
0
          // The format string ended in the middle of a specification.  Call
195
0
          // it portable because no unportable specifications were found.  The
196
0
          // string is equally broken on all platforms.
197
0
          return true;
198
0
        }
199
0
200
0
        if (*position == 'l') {
201
0
          // 'l' is the only thing that can save the 's' and 'c' specifiers.
202
0
          modifier_l = true;
203
0
        } else if (((*position == 's' || *position == 'c') && !modifier_l) ||
204
0
                   *position == 'S' || *position == 'C' || *position == 'F' ||
205
0
                   *position == 'D' || *position == 'O' || *position == 'U') {
206
0
          // Not portable.
207
0
          return false;
208
0
        }
209
0
210
0
        if (wcschr(L"diouxXeEfgGaAcspn%", *position)) {
211
0
          // Portable, keep scanning the rest of the format string.
212
0
          in_specification = false;
213
0
        }
214
0
      }
215
0
    }
216
0
217
0
  }
218
0
219
0
  return true;
220
0
}
221
222
223
}  // namespace base
224
225
static const wchar_t kWhitespaceWide[] = {
226
  0x0009,  // <control-0009> to <control-000D>
227
  0x000A,
228
  0x000B,
229
  0x000C,
230
  0x000D,
231
  0x0020,  // Space
232
  0x0085,  // <control-0085>
233
  0x00A0,  // No-Break Space
234
  0x1680,  // Ogham Space Mark
235
  0x180E,  // Mongolian Vowel Separator
236
  0x2000,  // En Quad to Hair Space
237
  0x2001,
238
  0x2002,
239
  0x2003,
240
  0x2004,
241
  0x2005,
242
  0x2006,
243
  0x2007,
244
  0x2008,
245
  0x2009,
246
  0x200A,
247
  0x200C,  // Zero Width Non-Joiner
248
  0x2028,  // Line Separator
249
  0x2029,  // Paragraph Separator
250
  0x202F,  // Narrow No-Break Space
251
  0x205F,  // Medium Mathematical Space
252
  0x3000,  // Ideographic Space
253
  0
254
};
255
static const char kWhitespaceASCII[] = {
256
  0x09,    // <control-0009> to <control-000D>
257
  0x0A,
258
  0x0B,
259
  0x0C,
260
  0x0D,
261
  0x20,    // Space
262
  0
263
};
264
265
template<typename STR>
266
TrimPositions TrimStringT(const STR& input,
267
                          const typename STR::value_type trim_chars[],
268
                          TrimPositions positions,
269
0
                          STR* output) {
270
0
  // Find the edges of leading/trailing whitespace as desired.
271
0
  const typename STR::size_type last_char = input.length() - 1;
272
0
  const typename STR::size_type first_good_char = (positions & TRIM_LEADING) ?
273
0
      input.find_first_not_of(trim_chars) : 0;
274
0
  const typename STR::size_type last_good_char = (positions & TRIM_TRAILING) ?
275
0
      input.find_last_not_of(trim_chars) : last_char;
276
0
277
0
  // When the string was all whitespace, report that we stripped off whitespace
278
0
  // from whichever position the caller was interested in.  For empty input, we
279
0
  // stripped no whitespace, but we still need to clear |output|.
280
0
  if (input.empty() ||
281
0
      (first_good_char == STR::npos) || (last_good_char == STR::npos)) {
282
0
    bool input_was_empty = input.empty();  // in case output == &input
283
0
    output->clear();
284
0
    return input_was_empty ? TRIM_NONE : positions;
285
0
  }
286
0
287
0
  // Trim the whitespace.
288
0
  *output =
289
0
      input.substr(first_good_char, last_good_char - first_good_char + 1);
290
0
291
0
  // Return where we trimmed from.
292
0
  return static_cast<TrimPositions>(
293
0
      ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) |
294
0
      ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING));
295
0
}
Unexecuted instantiation: TrimPositions TrimStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::value_type const*, TrimPositions, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >*)
Unexecuted instantiation: TrimPositions TrimStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::value_type const*, TrimPositions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
296
297
TrimPositions TrimWhitespace(const std::wstring& input,
298
                             TrimPositions positions,
299
0
                             std::wstring* output) {
300
0
  return TrimStringT(input, kWhitespaceWide, positions, output);
301
0
}
302
303
TrimPositions TrimWhitespaceASCII(const std::string& input,
304
                                  TrimPositions positions,
305
0
                                  std::string* output) {
306
0
  return TrimStringT(input, kWhitespaceASCII, positions, output);
307
0
}
308
309
// This function is only for backward-compatibility.
310
// To be removed when all callers are updated.
311
TrimPositions TrimWhitespace(const std::string& input,
312
                             TrimPositions positions,
313
0
                             std::string* output) {
314
0
  return TrimWhitespaceASCII(input, positions, output);
315
0
}
316
317
0
std::string WideToASCII(const std::wstring& wide) {
318
0
  DCHECK(IsStringASCII(wide));
319
0
  return std::string(wide.begin(), wide.end());
320
0
}
321
322
0
std::wstring ASCIIToWide(const std::string& ascii) {
323
0
  DCHECK(IsStringASCII(ascii));
324
0
  return std::wstring(ascii.begin(), ascii.end());
325
0
}
326
327
0
std::string UTF16ToASCII(const string16& utf16) {
328
0
  DCHECK(IsStringASCII(utf16));
329
0
  return std::string(utf16.begin(), utf16.end());
330
0
}
331
332
0
string16 ASCIIToUTF16(const std::string& ascii) {
333
0
  DCHECK(IsStringASCII(ascii));
334
0
  return string16(ascii.begin(), ascii.end());
335
0
}
336
337
template<class STR>
338
0
static bool DoIsStringASCII(const STR& str) {
339
0
  for (size_t i = 0; i < str.length(); i++) {
340
0
    typename ToUnsigned<typename STR::value_type>::Unsigned c = str[i];
341
0
    if (c > 0x7F)
342
0
      return false;
343
0
  }
344
0
  return true;
345
0
}
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool DoIsStringASCII<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool DoIsStringASCII<std::__1::basic_string<unsigned short, base::string16_char_traits, std::__1::allocator<unsigned short> > >(std::__1::basic_string<unsigned short, base::string16_char_traits, std::__1::allocator<unsigned short> > const&)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:bool DoIsStringASCII<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
346
347
0
bool IsStringASCII(const std::wstring& str) {
348
0
  return DoIsStringASCII(str);
349
0
}
350
351
#if !defined(WCHAR_T_IS_UTF16)
352
0
bool IsStringASCII(const string16& str) {
353
0
  return DoIsStringASCII(str);
354
0
}
355
#endif
356
357
0
bool IsStringASCII(const std::string& str) {
358
0
  return DoIsStringASCII(str);
359
0
}
360
361
// Overloaded wrappers around vsnprintf and vswprintf. The buf_size parameter
362
// is the size of the buffer. These return the number of characters in the
363
// formatted string excluding the NUL terminator. If the buffer is not
364
// large enough to accommodate the formatted string without truncation, they
365
// return the number of characters that would be in the fully-formatted string
366
// (vsnprintf, and vswprintf on Windows), or -1 (vswprintf on POSIX platforms).
367
inline int vsnprintfT(char* buffer,
368
                      size_t buf_size,
369
                      const char* format,
370
0
                      va_list argptr) {
371
0
  return base::vsnprintf(buffer, buf_size, format, argptr);
372
0
}
373
374
inline int vsnprintfT(wchar_t* buffer,
375
                      size_t buf_size,
376
                      const wchar_t* format,
377
0
                      va_list argptr) {
378
0
  return base::vswprintf(buffer, buf_size, format, argptr);
379
0
}
380
381
// Templatized backend for StringPrintF/StringAppendF. This does not finalize
382
// the va_list, the caller is expected to do that.
383
template <class StringType>
384
static void StringAppendVT(StringType* dst,
385
                           const typename StringType::value_type* format,
386
0
                           va_list ap) {
387
0
  // First try with a small fixed size buffer.
388
0
  // This buffer size should be kept in sync with StringUtilTest.GrowBoundary
389
0
  // and StringUtilTest.StringPrintfBounds.
390
0
  typename StringType::value_type stack_buf[1024];
391
0
392
0
  va_list backup_ap;
393
0
  base_va_copy(backup_ap, ap);
394
0
395
0
#if !defined(OS_WIN)
396
0
  errno = 0;
397
0
#endif
398
0
  int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, backup_ap);
399
0
  va_end(backup_ap);
400
0
401
0
  if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) {
402
0
    // It fit.
403
0
    dst->append(stack_buf, result);
404
0
    return;
405
0
  }
406
0
407
0
  // Repeatedly increase buffer size until it fits.
408
0
  int mem_length = arraysize(stack_buf);
409
0
  while (true) {
410
0
    if (result < 0) {
411
0
#if !defined(OS_WIN)
412
0
      // On Windows, vsnprintfT always returns the number of characters in a
413
0
      // fully-formatted string, so if we reach this point, something else is
414
0
      // wrong and no amount of buffer-doubling is going to fix it.
415
0
      if (errno != 0 && errno != EOVERFLOW)
416
0
#endif
417
0
      {
418
0
        // If an error other than overflow occurred, it's never going to work.
419
0
        DLOG(WARNING) << "Unable to printf the requested string due to error.";
420
0
        return;
421
0
      }
422
0
      // Try doubling the buffer size.
423
0
      mem_length *= 2;
424
0
    } else {
425
0
      // We need exactly "result + 1" characters.
426
0
      mem_length = result + 1;
427
0
    }
428
0
429
0
    if (mem_length > 32 * 1024 * 1024) {
430
0
      // That should be plenty, don't try anything larger.  This protects
431
0
      // against huge allocations when using vsnprintfT implementations that
432
0
      // return -1 for reasons other than overflow without setting errno.
433
0
      DLOG(WARNING) << "Unable to printf the requested string due to size.";
434
0
      return;
435
0
    }
436
0
437
0
    std::vector<typename StringType::value_type> mem_buf(mem_length);
438
0
439
0
    // Restore the va_list before we use it again.
440
0
    base_va_copy(backup_ap, ap);
441
0
442
0
    result = vsnprintfT(&mem_buf[0], mem_length, format, ap);
443
0
    va_end(backup_ap);
444
0
445
0
    if ((result >= 0) && (result < mem_length)) {
446
0
      // It fit.
447
0
      dst->append(&mem_buf[0], result);
448
0
      return;
449
0
    }
450
0
  }
451
0
}
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:void StringAppendVT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::value_type const*, __va_list_tag*)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:void StringAppendVT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >*, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::value_type const*, __va_list_tag*)
452
453
namespace {
454
455
template <typename STR, typename INT, typename UINT, bool NEG>
456
struct IntToStringT {
457
458
  // This is to avoid a compiler warning about unary minus on unsigned type.
459
  // For example, say you had the following code:
460
  //   template <typename INT>
461
  //   INT abs(INT value) { return value < 0 ? -value : value; }
462
  // Even though if INT is unsigned, it's impossible for value < 0, so the
463
  // unary minus will never be taken, the compiler will still generate a
464
  // warning.  We do a little specialization dance...
465
  template <typename INT2, typename UINT2, bool NEG2>
466
  struct ToUnsignedT { };
467
468
  template <typename INT2, typename UINT2>
469
  struct ToUnsignedT<INT2, UINT2, false> {
470
0
    static UINT2 ToUnsigned(INT2 value) {
471
0
      return static_cast<UINT2>(value);
472
0
    }
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned int, unsigned int, false>::ToUnsignedT<unsigned int, unsigned int, false>::ToUnsigned(unsigned int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned int, unsigned int, false>::ToUnsignedT<unsigned int, unsigned int, false>::ToUnsigned(unsigned int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long, unsigned long, false>::ToUnsignedT<unsigned long, unsigned long, false>::ToUnsigned(unsigned long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long, unsigned long, false>::ToUnsignedT<unsigned long, unsigned long, false>::ToUnsigned(unsigned long)
473
  };
474
475
  template <typename INT2, typename UINT2>
476
  struct ToUnsignedT<INT2, UINT2, true> {
477
0
    static UINT2 ToUnsigned(INT2 value) {
478
0
      return static_cast<UINT2>(value < 0 ? -value : value);
479
0
    }
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, unsigned int, true>::ToUnsignedT<int, unsigned int, true>::ToUnsigned(int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int, unsigned int, true>::ToUnsignedT<int, unsigned int, true>::ToUnsigned(int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long, unsigned long, true>::ToUnsignedT<long, unsigned long, true>::ToUnsigned(long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long, unsigned long, true>::ToUnsignedT<long, unsigned long, true>::ToUnsigned(long)
480
  };
481
482
  // This set of templates is very similar to the above templates, but
483
  // for testing whether an integer is negative.
484
  template <typename INT2, bool NEG2>
485
  struct TestNegT {};
486
  template <typename INT2>
487
  struct TestNegT<INT2, false> {
488
0
    static bool TestNeg(INT2 value) {
489
0
      // value is unsigned, and can never be negative.
490
0
      return false;
491
0
    }
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned int, unsigned int, false>::TestNegT<unsigned int, false>::TestNeg(unsigned int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned int, unsigned int, false>::TestNegT<unsigned int, false>::TestNeg(unsigned int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long, unsigned long, false>::TestNegT<unsigned long, false>::TestNeg(unsigned long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long, unsigned long, false>::TestNegT<unsigned long, false>::TestNeg(unsigned long)
492
  };
493
  template <typename INT2>
494
  struct TestNegT<INT2, true> {
495
0
    static bool TestNeg(INT2 value) {
496
0
      return value < 0;
497
0
    }
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, unsigned int, true>::TestNegT<int, true>::TestNeg(int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int, unsigned int, true>::TestNegT<int, true>::TestNeg(int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long, unsigned long, true>::TestNegT<long, true>::TestNeg(long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long, unsigned long, true>::TestNegT<long, true>::TestNeg(long)
498
  };
499
500
0
  static STR IntToString(INT value) {
501
0
    // log10(2) ~= 0.3 bytes needed per bit or per byte log10(2**8) ~= 2.4.
502
0
    // So round up to allocate 3 output characters per byte, plus 1 for '-'.
503
0
    const int kOutputBufSize = 3 * sizeof(INT) + 1;
504
0
505
0
    // Allocate the whole string right away, we will right back to front, and
506
0
    // then return the substr of what we ended up using.
507
0
    STR outbuf(kOutputBufSize, 0);
508
0
509
0
    bool is_neg = TestNegT<INT, NEG>::TestNeg(value);
510
0
    // Even though is_neg will never be true when INT is parameterized as
511
0
    // unsigned, even the presence of the unary operation causes a warning.
512
0
    UINT res = ToUnsignedT<INT, UINT, NEG>::ToUnsigned(value);
513
0
514
0
    for (typename STR::iterator it = outbuf.end();;) {
515
0
      --it;
516
0
      DCHECK(it != outbuf.begin());
517
0
      *it = static_cast<typename STR::value_type>((res % 10) + '0');
518
0
      res /= 10;
519
0
520
0
      // We're done..
521
0
      if (res == 0) {
522
0
        if (is_neg) {
523
0
          --it;
524
0
          DCHECK(it != outbuf.begin());
525
0
          *it = static_cast<typename STR::value_type>('-');
526
0
        }
527
0
        return STR(it, outbuf.end());
528
0
      }
529
0
    }
530
0
    NOTREACHED();
531
0
    return STR();
532
0
  }
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, unsigned int, true>::IntToString(int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int, unsigned int, true>::IntToString(int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned int, unsigned int, false>::IntToString(unsigned int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned int, unsigned int, false>::IntToString(unsigned int)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long, unsigned long, true>::IntToString(long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long, unsigned long, true>::IntToString(long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long, unsigned long, false>::IntToString(unsigned long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:(anonymous namespace)::IntToStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long, unsigned long, false>::IntToString(unsigned long)
533
};
534
535
}
536
537
0
std::string IntToString(int value) {
538
0
  return IntToStringT<std::string, int, unsigned int, true>::
539
0
      IntToString(value);
540
0
}
541
0
std::wstring IntToWString(int value) {
542
0
  return IntToStringT<std::wstring, int, unsigned int, true>::
543
0
      IntToString(value);
544
0
}
545
0
std::string UintToString(unsigned int value) {
546
0
  return IntToStringT<std::string, unsigned int, unsigned int, false>::
547
0
      IntToString(value);
548
0
}
549
0
std::wstring UintToWString(unsigned int value) {
550
0
  return IntToStringT<std::wstring, unsigned int, unsigned int, false>::
551
0
      IntToString(value);
552
0
}
553
0
std::string Int64ToString(int64_t value) {
554
0
  return IntToStringT<std::string, int64_t, uint64_t, true>::
555
0
      IntToString(value);
556
0
}
557
0
std::wstring Int64ToWString(int64_t value) {
558
0
  return IntToStringT<std::wstring, int64_t, uint64_t, true>::
559
0
      IntToString(value);
560
0
}
561
0
std::string Uint64ToString(uint64_t value) {
562
0
  return IntToStringT<std::string, uint64_t, uint64_t, false>::
563
0
      IntToString(value);
564
0
}
565
0
std::wstring Uint64ToWString(uint64_t value) {
566
0
  return IntToStringT<std::wstring, uint64_t, uint64_t, false>::
567
0
      IntToString(value);
568
0
}
569
570
// Lower-level routine that takes a va_list and appends to a specified
571
// string.  All other routines are just convenience wrappers around it.
572
0
static void StringAppendV(std::string* dst, const char* format, va_list ap) {
573
0
  StringAppendVT(dst, format, ap);
574
0
}
575
576
0
static void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap) {
577
0
  StringAppendVT(dst, format, ap);
578
0
}
579
580
0
std::string StringPrintf(const char* format, ...) {
581
0
  va_list ap;
582
0
  va_start(ap, format);
583
0
  std::string result;
584
0
  StringAppendV(&result, format, ap);
585
0
  va_end(ap);
586
0
  return result;
587
0
}
588
589
0
std::wstring StringPrintf(const wchar_t* format, ...) {
590
0
  va_list ap;
591
0
  va_start(ap, format);
592
0
  std::wstring result;
593
0
  StringAppendV(&result, format, ap);
594
0
  va_end(ap);
595
0
  return result;
596
0
}
597
598
0
const std::string& SStringPrintf(std::string* dst, const char* format, ...) {
599
0
  va_list ap;
600
0
  va_start(ap, format);
601
0
  dst->clear();
602
0
  StringAppendV(dst, format, ap);
603
0
  va_end(ap);
604
0
  return *dst;
605
0
}
606
607
const std::wstring& SStringPrintf(std::wstring* dst,
608
0
                                  const wchar_t* format, ...) {
609
0
  va_list ap;
610
0
  va_start(ap, format);
611
0
  dst->clear();
612
0
  StringAppendV(dst, format, ap);
613
0
  va_end(ap);
614
0
  return *dst;
615
0
}
616
617
0
void StringAppendF(std::string* dst, const char* format, ...) {
618
0
  va_list ap;
619
0
  va_start(ap, format);
620
0
  StringAppendV(dst, format, ap);
621
0
  va_end(ap);
622
0
}
623
624
0
void StringAppendF(std::wstring* dst, const wchar_t* format, ...) {
625
0
  va_list ap;
626
0
  va_start(ap, format);
627
0
  StringAppendV(dst, format, ap);
628
0
  va_end(ap);
629
0
}
630
631
template<typename STR>
632
static void SplitStringT(const STR& str,
633
                         const typename STR::value_type s,
634
                         bool trim_whitespace,
635
0
                         std::vector<STR>* r) {
636
0
  size_t last = 0;
637
0
  size_t i;
638
0
  size_t c = str.size();
639
0
  for (i = 0; i <= c; ++i) {
640
0
    if (i == c || str[i] == s) {
641
0
      size_t len = i - last;
642
0
      STR tmp = str.substr(last, len);
643
0
      if (trim_whitespace) {
644
0
        STR t_tmp;
645
0
        TrimWhitespace(tmp, TRIM_ALL, &t_tmp);
646
0
        r->push_back(t_tmp);
647
0
      } else {
648
0
        r->push_back(tmp);
649
0
      }
650
0
      last = i + 1;
651
0
    }
652
0
  }
653
0
}
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:void SplitStringT<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::value_type, bool, std::__1::vector<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::allocator<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > > >*)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:void SplitStringT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::value_type, bool, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*)
654
655
void SplitString(const std::wstring& str,
656
                 wchar_t s,
657
0
                 std::vector<std::wstring>* r) {
658
0
  SplitStringT(str, s, true, r);
659
0
}
660
661
void SplitString(const std::string& str,
662
                 char s,
663
0
                 std::vector<std::string>* r) {
664
0
  SplitStringT(str, s, true, r);
665
0
}
666
667
// For the various *ToInt conversions, there are no *ToIntTraits classes to use
668
// because there's no such thing as strtoi.  Use *ToLongTraits through a cast
669
// instead, requiring that long and int are compatible and equal-width.  They
670
// are on our target platforms.
671
672
// XXX Sigh.
673
674
#if !defined(ARCH_CPU_64_BITS)
675
bool StringToInt(const std::string& input, int* output) {
676
  COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
677
  return StringToNumber<StringToLongTraits>(input,
678
                                            reinterpret_cast<long*>(output));
679
}
680
681
bool StringToInt(const string16& input, int* output) {
682
  COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
683
  return StringToNumber<String16ToLongTraits>(input,
684
                                              reinterpret_cast<long*>(output));
685
}
686
687
#else
688
0
bool StringToInt(const std::string& input, int* output) {
689
0
  long tmp;
690
0
  bool ok = StringToNumber<StringToLongTraits>(input, &tmp);
691
0
  if (!ok || tmp > kint32max) {
692
0
    return false;
693
0
  }
694
0
  *output = static_cast<int>(tmp);
695
0
  return true;
696
0
}
697
698
0
bool StringToInt(const string16& input, int* output) {
699
0
  long tmp;
700
0
  bool ok = StringToNumber<String16ToLongTraits>(input, &tmp);
701
0
  if (!ok || tmp > kint32max) {
702
0
    return false;
703
0
  }
704
0
  *output = static_cast<int>(tmp);
705
0
  return true;
706
0
}
707
#endif //  !defined(ARCH_CPU_64_BITS)
708
709
0
bool StringToInt64(const std::string& input, int64_t* output) {
710
0
  return StringToNumber<StringToInt64Traits>(input, output);
711
0
}
712
713
0
bool StringToInt64(const string16& input, int64_t* output) {
714
0
  return StringToNumber<String16ToInt64Traits>(input, output);
715
0
}
716
717
0
int StringToInt(const std::string& value) {
718
0
  int result;
719
0
  StringToInt(value, &result);
720
0
  return result;
721
0
}
722
723
0
int StringToInt(const string16& value) {
724
0
  int result;
725
0
  StringToInt(value, &result);
726
0
  return result;
727
0
}
728
729
0
int64_t StringToInt64(const std::string& value) {
730
0
  int64_t result;
731
0
  StringToInt64(value, &result);
732
0
  return result;
733
0
}
734
735
0
int64_t StringToInt64(const string16& value) {
736
0
  int64_t result;
737
0
  StringToInt64(value, &result);
738
0
  return result;
739
0
}
740
741
// The following code is compatible with the OpenBSD lcpy interface.  See:
742
//   http://www.gratisoft.us/todd/papers/strlcpy.html
743
//   ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c
744
745
namespace {
746
747
template <typename CHAR>
748
0
size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) {
749
0
  for (size_t i = 0; i < dst_size; ++i) {
750
0
    if ((dst[i] = src[i]) == 0)  // We hit and copied the terminating NULL.
751
0
      return i;
752
0
  }
753
0
754
0
  // We were left off at dst_size.  We over copied 1 byte.  Null terminate.
755
0
  if (dst_size != 0)
756
0
    dst[dst_size - 1] = 0;
757
0
758
0
  // Count the rest of the |src|, and return it's length in characters.
759
0
  while (src[dst_size]) ++dst_size;
760
0
  return dst_size;
761
0
}
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:unsigned long (anonymous namespace)::lcpyT<char>(char*, char const*, unsigned long)
Unexecuted instantiation: Unified_cpp_ipc_chromium1.cpp:unsigned long (anonymous namespace)::lcpyT<wchar_t>(wchar_t*, wchar_t const*, unsigned long)
762
763
}  // namespace
764
765
0
size_t base::strlcpy(char* dst, const char* src, size_t dst_size) {
766
0
  return lcpyT<char>(dst, src, dst_size);
767
0
}
768
0
size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) {
769
0
  return lcpyT<wchar_t>(dst, src, dst_size);
770
0
}