/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__ |