Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/webrtc/trunk/webrtc/base/stringutils.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
 *  that can be found in the LICENSE file in the root of the source
6
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
9
 */
10
11
#ifndef WEBRTC_BASE_STRINGUTILS_H__
12
#define WEBRTC_BASE_STRINGUTILS_H__
13
14
#include <ctype.h>
15
#include <stdarg.h>
16
#include <stdio.h>
17
#include <string.h>
18
19
#if defined(WEBRTC_WIN)
20
#include <malloc.h>
21
#include <wchar.h>
22
#define alloca _alloca
23
#endif  // WEBRTC_WIN 
24
25
#if defined(WEBRTC_POSIX)
26
#ifdef WEBRTC_BSD
27
#include <stdlib.h>
28
#else  // BSD
29
#include <alloca.h>
30
#endif  // !BSD
31
#endif  // WEBRTC_POSIX
32
33
#include <string>
34
35
///////////////////////////////////////////////////////////////////////////////
36
// Generic string/memory utilities
37
///////////////////////////////////////////////////////////////////////////////
38
39
0
#define STACK_ARRAY(TYPE, LEN) static_cast<TYPE*>(::alloca((LEN)*sizeof(TYPE)))
40
41
namespace rtc {
42
43
// Complement to memset.  Verifies memory consists of count bytes of value c.
44
bool memory_check(const void* memory, int c, size_t count);
45
46
// Determines whether the simple wildcard pattern matches target.
47
// Alpha characters in pattern match case-insensitively.
48
// Asterisks in pattern match 0 or more characters.
49
// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true
50
bool string_match(const char* target, const char* pattern);
51
52
}  // namespace rtc
53
54
///////////////////////////////////////////////////////////////////////////////
55
// Rename a bunch of common string functions so they are consistent across
56
// platforms and between char and wchar_t variants.
57
// Here is the full list of functions that are unified:
58
//  strlen, strcmp, stricmp, strncmp, strnicmp
59
//  strchr, vsnprintf, strtoul, tolowercase
60
// tolowercase is like tolower, but not compatible with end-of-file value
61
//
62
// It's not clear if we will ever use wchar_t strings on unix.  In theory,
63
// all strings should be Utf8 all the time, except when interfacing with Win32
64
// APIs that require Utf16.
65
///////////////////////////////////////////////////////////////////////////////
66
67
0
inline char tolowercase(char c) {
68
0
  return static_cast<char>(tolower(c));
69
0
}
70
71
#if defined(WEBRTC_WIN)
72
73
inline size_t strlen(const wchar_t* s) {
74
  return wcslen(s);
75
}
76
inline int strcmp(const wchar_t* s1, const wchar_t* s2) {
77
  return wcscmp(s1, s2);
78
}
79
inline int stricmp(const wchar_t* s1, const wchar_t* s2) {
80
  return _wcsicmp(s1, s2);
81
}
82
inline int strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
83
  return wcsncmp(s1, s2, n);
84
}
85
inline int strnicmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
86
  return _wcsnicmp(s1, s2, n);
87
}
88
inline const wchar_t* strchr(const wchar_t* s, wchar_t c) {
89
  return wcschr(s, c);
90
}
91
inline const wchar_t* strstr(const wchar_t* haystack, const wchar_t* needle) {
92
  return wcsstr(haystack, needle);
93
}
94
#ifndef vsnprintf
95
inline int vsnprintf(wchar_t* buf, size_t n, const wchar_t* fmt, va_list args) {
96
  return _vsnwprintf(buf, n, fmt, args);
97
}
98
#endif // !vsnprintf
99
inline unsigned long strtoul(const wchar_t* snum, wchar_t** end, int base) {
100
  return wcstoul(snum, end, base);
101
}
102
inline wchar_t tolowercase(wchar_t c) {
103
  return static_cast<wchar_t>(towlower(c));
104
}
105
106
#endif  // WEBRTC_WIN 
107
108
#if defined(WEBRTC_POSIX)
109
110
0
inline int _stricmp(const char* s1, const char* s2) {
111
0
  return strcasecmp(s1, s2);
112
0
}
113
0
inline int _strnicmp(const char* s1, const char* s2, size_t n) {
114
0
  return strncasecmp(s1, s2, n);
115
0
}
116
117
#endif // WEBRTC_POSIX
118
119
///////////////////////////////////////////////////////////////////////////////
120
// Traits simplifies porting string functions to be CTYPE-agnostic
121
///////////////////////////////////////////////////////////////////////////////
122
123
namespace rtc {
124
125
const size_t SIZE_UNKNOWN = static_cast<size_t>(-1);
126
127
template<class CTYPE>
128
struct Traits {
129
  // STL string type
130
  //typedef XXX string;
131
  // Null-terminated string
132
  //inline static const CTYPE* empty_str();
133
};
134
135
///////////////////////////////////////////////////////////////////////////////
136
// String utilities which work with char or wchar_t
137
///////////////////////////////////////////////////////////////////////////////
138
139
template<class CTYPE>
140
inline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = NULL) {
141
  return str ? str : (def_str ? def_str : Traits<CTYPE>::empty_str());
142
}
143
144
template<class CTYPE>
145
const CTYPE* strchr(const CTYPE* str, const CTYPE* chs) {
146
  for (size_t i=0; str[i]; ++i) {
147
    for (size_t j=0; chs[j]; ++j) {
148
      if (str[i] == chs[j]) {
149
        return str + i;
150
      }
151
    }
152
  }
153
  return 0;
154
}
155
156
template<class CTYPE>
157
0
const CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) {
158
0
  for (size_t i=0; i<slen && str[i]; ++i) {
159
0
    if (str[i] == ch) {
160
0
      return str + i;
161
0
    }
162
0
  }
163
0
  return 0;
164
0
}
165
166
template<class CTYPE>
167
0
size_t strlenn(const CTYPE* buffer, size_t buflen) {
168
0
  size_t bufpos = 0;
169
0
  while (buffer[bufpos] && (bufpos < buflen)) {
170
0
    ++bufpos;
171
0
  }
172
0
  return bufpos;
173
0
}
174
175
// Safe versions of strncpy, strncat, snprintf and vsnprintf that always
176
// null-terminate.
177
178
template<class CTYPE>
179
size_t strcpyn(CTYPE* buffer, size_t buflen,
180
0
               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
181
0
  if (buflen <= 0)
182
0
    return 0;
183
0
184
0
  if (srclen == SIZE_UNKNOWN) {
185
0
    srclen = strlenn(source, buflen - 1);
186
0
  } else if (srclen >= buflen) {
187
0
    srclen = buflen - 1;
188
0
  }
189
0
  memcpy(buffer, source, srclen * sizeof(CTYPE));
190
0
  buffer[srclen] = 0;
191
0
  return srclen;
192
0
}
193
194
template<class CTYPE>
195
size_t strcatn(CTYPE* buffer, size_t buflen,
196
               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
197
  if (buflen <= 0)
198
    return 0;
199
200
  size_t bufpos = strlenn(buffer, buflen - 1);
201
  return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen);
202
}
203
204
// Some compilers (clang specifically) require vsprintfn be defined before
205
// sprintfn.
206
template<class CTYPE>
207
size_t vsprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format,
208
0
                 va_list args) {
209
0
  int len = vsnprintf(buffer, buflen, format, args);
210
0
  if ((len < 0) || (static_cast<size_t>(len) >= buflen)) {
211
0
    len = static_cast<int>(buflen - 1);
212
0
    buffer[len] = 0;
213
0
  }
214
0
  return len;
215
0
}
216
217
template<class CTYPE>
218
size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...);
219
template<class CTYPE>
220
0
size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) {
221
0
  va_list args;
222
0
  va_start(args, format);
223
0
  size_t len = vsprintfn(buffer, buflen, format, args);
224
0
  va_end(args);
225
0
  return len;
226
0
}
227
228
///////////////////////////////////////////////////////////////////////////////
229
// Allow safe comparing and copying ascii (not UTF-8) with both wide and
230
// non-wide character strings.
231
///////////////////////////////////////////////////////////////////////////////
232
233
0
inline int asccmp(const char* s1, const char* s2) {
234
0
  return strcmp(s1, s2);
235
0
}
236
0
inline int ascicmp(const char* s1, const char* s2) {
237
0
  return _stricmp(s1, s2);
238
0
}
239
0
inline int ascncmp(const char* s1, const char* s2, size_t n) {
240
0
  return strncmp(s1, s2, n);
241
0
}
242
0
inline int ascnicmp(const char* s1, const char* s2, size_t n) {
243
0
  return _strnicmp(s1, s2, n);
244
0
}
245
inline size_t asccpyn(char* buffer, size_t buflen,
246
0
                      const char* source, size_t srclen = SIZE_UNKNOWN) {
247
0
  return strcpyn(buffer, buflen, source, srclen);
248
0
}
249
250
#if defined(WEBRTC_WIN)
251
252
typedef wchar_t(*CharacterTransformation)(wchar_t);
253
inline wchar_t identity(wchar_t c) { return c; }
254
int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
255
                         CharacterTransformation transformation);
256
257
inline int asccmp(const wchar_t* s1, const char* s2) {
258
  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), identity);
259
}
260
inline int ascicmp(const wchar_t* s1, const char* s2) {
261
  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), tolowercase);
262
}
263
inline int ascncmp(const wchar_t* s1, const char* s2, size_t n) {
264
  return ascii_string_compare(s1, s2, n, identity);
265
}
266
inline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) {
267
  return ascii_string_compare(s1, s2, n, tolowercase);
268
}
269
size_t asccpyn(wchar_t* buffer, size_t buflen,
270
               const char* source, size_t srclen = SIZE_UNKNOWN);
271
272
#endif  // WEBRTC_WIN 
273
274
///////////////////////////////////////////////////////////////////////////////
275
// Traits<char> specializations
276
///////////////////////////////////////////////////////////////////////////////
277
278
template<>
279
struct Traits<char> {
280
  typedef std::string string;
281
0
  inline static const char* empty_str() { return ""; }
282
};
283
284
///////////////////////////////////////////////////////////////////////////////
285
// Traits<wchar_t> specializations (Windows only, currently)
286
///////////////////////////////////////////////////////////////////////////////
287
288
#if defined(WEBRTC_WIN)
289
290
template<>
291
struct Traits<wchar_t> {
292
  typedef std::wstring string;
293
  inline static const wchar_t* empty_str() { return L""; }
294
};
295
296
#endif  // WEBRTC_WIN 
297
298
// Replaces all occurrences of "search" with "replace".
299
void replace_substrs(const char *search,
300
                     size_t search_len,
301
                     const char *replace,
302
                     size_t replace_len,
303
                     std::string *s);
304
305
// True iff s1 starts with s2.
306
bool starts_with(const char *s1, const char *s2);
307
308
// True iff s1 ends with s2.
309
bool ends_with(const char *s1, const char *s2);
310
311
// Remove leading and trailing whitespaces.
312
std::string string_trim(const std::string& s);
313
314
}  // namespace rtc
315
316
#endif // WEBRTC_BASE_STRINGUTILS_H__