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