OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_BASE_STRINGUTILS_H__ | 11 #ifndef WEBRTC_BASE_STRINGUTILS_H_ |
12 #define WEBRTC_BASE_STRINGUTILS_H__ | 12 #define WEBRTC_BASE_STRINGUTILS_H_ |
13 | 13 |
14 #include <ctype.h> | |
15 #include <stdarg.h> | |
16 #include <stdio.h> | |
17 #include <string.h> | |
18 | 14 |
19 #if defined(WEBRTC_WIN) | 15 // This header is deprecated and is just left here temporarily during |
20 #include <malloc.h> | 16 // refactoring. See https://bugs.webrtc.org/7634 for more details. |
21 #include <wchar.h> | 17 #include "webrtc/rtc_base/stringutils.h" |
22 #define alloca _alloca | |
23 #endif // WEBRTC_WIN | |
24 | 18 |
25 #if defined(WEBRTC_POSIX) | 19 #endif // WEBRTC_BASE_STRINGUTILS_H_ |
26 #ifdef 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 #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 inline char tolowercase(char c) { | |
68 return static_cast<char>(tolower(c)); | |
69 } | |
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 inline int _stricmp(const char* s1, const char* s2) { | |
111 return strcasecmp(s1, s2); | |
112 } | |
113 inline int _strnicmp(const char* s1, const char* s2, size_t n) { | |
114 return strncasecmp(s1, s2, n); | |
115 } | |
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 = nullptr) { | |
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 const CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) { | |
158 for (size_t i=0; i<slen && str[i]; ++i) { | |
159 if (str[i] == ch) { | |
160 return str + i; | |
161 } | |
162 } | |
163 return 0; | |
164 } | |
165 | |
166 template<class CTYPE> | |
167 size_t strlenn(const CTYPE* buffer, size_t buflen) { | |
168 size_t bufpos = 0; | |
169 while (buffer[bufpos] && (bufpos < buflen)) { | |
170 ++bufpos; | |
171 } | |
172 return bufpos; | |
173 } | |
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 const CTYPE* source, size_t srclen = SIZE_UNKNOWN) { | |
181 if (buflen <= 0) | |
182 return 0; | |
183 | |
184 if (srclen == SIZE_UNKNOWN) { | |
185 srclen = strlenn(source, buflen - 1); | |
186 } else if (srclen >= buflen) { | |
187 srclen = buflen - 1; | |
188 } | |
189 memcpy(buffer, source, srclen * sizeof(CTYPE)); | |
190 buffer[srclen] = 0; | |
191 return srclen; | |
192 } | |
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 va_list args) { | |
209 int len = vsnprintf(buffer, buflen, format, args); | |
210 if ((len < 0) || (static_cast<size_t>(len) >= buflen)) { | |
211 len = static_cast<int>(buflen - 1); | |
212 buffer[len] = 0; | |
213 } | |
214 return len; | |
215 } | |
216 | |
217 template<class CTYPE> | |
218 size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...); | |
219 template<class CTYPE> | |
220 size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) { | |
221 va_list args; | |
222 va_start(args, format); | |
223 size_t len = vsprintfn(buffer, buflen, format, args); | |
224 va_end(args); | |
225 return len; | |
226 } | |
227 | |
228 /////////////////////////////////////////////////////////////////////////////// | |
229 // Allow safe comparing and copying ascii (not UTF-8) with both wide and | |
230 // non-wide character strings. | |
231 /////////////////////////////////////////////////////////////////////////////// | |
232 | |
233 inline int asccmp(const char* s1, const char* s2) { | |
234 return strcmp(s1, s2); | |
235 } | |
236 inline int ascicmp(const char* s1, const char* s2) { | |
237 return _stricmp(s1, s2); | |
238 } | |
239 inline int ascncmp(const char* s1, const char* s2, size_t n) { | |
240 return strncmp(s1, s2, n); | |
241 } | |
242 inline int ascnicmp(const char* s1, const char* s2, size_t n) { | |
243 return _strnicmp(s1, s2, n); | |
244 } | |
245 inline size_t asccpyn(char* buffer, size_t buflen, | |
246 const char* source, size_t srclen = SIZE_UNKNOWN) { | |
247 return strcpyn(buffer, buflen, source, srclen); | |
248 } | |
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 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__ | |
OLD | NEW |