1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifndef TALK_BASE_STRINGUTILS_H__
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define TALK_BASE_STRINGUTILS_H__
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <ctype.h>
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <stdarg.h>
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <stdio.h>
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <malloc.h>
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <wchar.h>
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define alloca _alloca
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // WIN32
40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef POSIX
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#ifdef BSD
43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <stdlib.h>
44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#else  // BSD
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <alloca.h>
46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif  // !BSD
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // POSIX
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <cstring>
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <string>
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/basictypes.h"
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Generic string/memory utilities
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define STACK_ARRAY(TYPE, LEN) static_cast<TYPE*>(::alloca((LEN)*sizeof(TYPE)))
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base {
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Complement to memset.  Verifies memory consists of count bytes of value c.
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool memory_check(const void* memory, int c, size_t count);
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Determines whether the simple wildcard pattern matches target.
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Alpha characters in pattern match case-insensitively.
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Asterisks in pattern match 0 or more characters.
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool string_match(const char* target, const char* pattern);
70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}  // namespace talk_base
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Rename a bunch of common string functions so they are consistent across
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// platforms and between char and wchar_t variants.
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Here is the full list of functions that are unified:
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//  strlen, strcmp, stricmp, strncmp, strnicmp
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//  strchr, vsnprintf, strtoul, tolowercase
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// tolowercase is like tolower, but not compatible with end-of-file value
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// It's not clear if we will ever use wchar_t strings on unix.  In theory,
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// all strings should be Utf8 all the time, except when interfacing with Win32
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// APIs that require Utf16.
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline char tolowercase(char c) {
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return static_cast<char>(tolower(c));
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline size_t strlen(const wchar_t* s) {
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return wcslen(s);
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int strcmp(const wchar_t* s1, const wchar_t* s2) {
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return wcscmp(s1, s2);
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int stricmp(const wchar_t* s1, const wchar_t* s2) {
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return _wcsicmp(s1, s2);
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return wcsncmp(s1, s2, n);
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int strnicmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return _wcsnicmp(s1, s2, n);
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline const wchar_t* strchr(const wchar_t* s, wchar_t c) {
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return wcschr(s, c);
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline const wchar_t* strstr(const wchar_t* haystack, const wchar_t* needle) {
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return wcsstr(haystack, needle);
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifndef vsnprintf
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int vsnprintf(char* buf, size_t n, const char* fmt, va_list args) {
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return _vsnprintf(buf, n, fmt, args);
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int vsnprintf(wchar_t* buf, size_t n, const wchar_t* fmt, va_list args) {
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return _vsnwprintf(buf, n, fmt, args);
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // !vsnprintf
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline unsigned long strtoul(const wchar_t* snum, wchar_t** end, int base) {
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return wcstoul(snum, end, base);
123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline wchar_t tolowercase(wchar_t c) {
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return static_cast<wchar_t>(towlower(c));
126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // WIN32
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef POSIX
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int _stricmp(const char* s1, const char* s2) {
133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return strcasecmp(s1, s2);
134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int _strnicmp(const char* s1, const char* s2, size_t n) {
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return strncasecmp(s1, s2, n);
137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // POSIX
140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Traits simplifies porting string functions to be CTYPE-agnostic
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base {
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst size_t SIZE_UNKNOWN = static_cast<size_t>(-1);
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct Traits {
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // STL string type
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //typedef XXX string;
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Null-terminated string
154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //inline static const CTYPE* empty_str();
155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// String utilities which work with char or wchar_t
159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = NULL) {
163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return str ? str : (def_str ? def_str : Traits<CTYPE>::empty_str());
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst CTYPE* strchr(const CTYPE* str, const CTYPE* chs) {
168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (size_t i=0; str[i]; ++i) {
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    for (size_t j=0; chs[j]; ++j) {
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      if (str[i] == chs[j]) {
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        return str + i;
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return 0;
176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) {
180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (size_t i=0; i<slen && str[i]; ++i) {
181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (str[i] == ch) {
182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return str + i;
183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return 0;
186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t strlenn(const CTYPE* buffer, size_t buflen) {
190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t bufpos = 0;
191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (buffer[bufpos] && (bufpos < buflen)) {
192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ++bufpos;
193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return bufpos;
195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Safe versions of strncpy, strncat, snprintf and vsnprintf that always
198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// null-terminate.
199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t strcpyn(CTYPE* buffer, size_t buflen,
202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (buflen <= 0)
204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return 0;
205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (srclen == SIZE_UNKNOWN) {
207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    srclen = strlenn(source, buflen - 1);
208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else if (srclen >= buflen) {
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    srclen = buflen - 1;
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  memcpy(buffer, source, srclen * sizeof(CTYPE));
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  buffer[srclen] = 0;
213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return srclen;
214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t strcatn(CTYPE* buffer, size_t buflen,
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (buflen <= 0)
220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return 0;
221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t bufpos = strlenn(buffer, buflen - 1);
223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen);
224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Some compilers (clang specifically) require vsprintfn be defined before
227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// sprintfn.
228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t vsprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format,
230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                 va_list args) {
231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int len = vsnprintf(buffer, buflen, format, args);
232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if ((len < 0) || (static_cast<size_t>(len) >= buflen)) {
233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    len = static_cast<int>(buflen - 1);
234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    buffer[len] = 0;
235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return len;
237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...);
241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* This works to get GCC to notice printf argument mismatches, but then complains of missing implementation of sprintfn<char>
242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<>
243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t sprintfn(char* buffer, size_t buflen, const char* format, ...)
244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochGCC_ATTR(format(printf,3,4));
245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch*/
246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<class CTYPE>
247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) {
248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  va_list args;
249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  va_start(args, format);
250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t len = vsprintfn(buffer, buflen, format, args);
251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  va_end(args);
252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return len;
253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Allow safe comparing and copying ascii (not UTF-8) with both wide and
257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// non-wide character strings.
258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int asccmp(const char* s1, const char* s2) {
261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return strcmp(s1, s2);
262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int ascicmp(const char* s1, const char* s2) {
264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return _stricmp(s1, s2);
265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int ascncmp(const char* s1, const char* s2, size_t n) {
267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return strncmp(s1, s2, n);
268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int ascnicmp(const char* s1, const char* s2, size_t n) {
270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return _strnicmp(s1, s2, n);
271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline size_t asccpyn(char* buffer, size_t buflen,
273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                      const char* source, size_t srclen = SIZE_UNKNOWN) {
274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return strcpyn(buffer, buflen, source, srclen);
275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef wchar_t(*CharacterTransformation)(wchar_t);
280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline wchar_t identity(wchar_t c) { return c; }
281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         CharacterTransformation transformation);
283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int asccmp(const wchar_t* s1, const char* s2) {
285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), identity);
286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int ascicmp(const wchar_t* s1, const char* s2) {
288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), tolowercase);
289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int ascncmp(const wchar_t* s1, const char* s2, size_t n) {
291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ascii_string_compare(s1, s2, n, identity);
292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochinline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) {
294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ascii_string_compare(s1, s2, n, tolowercase);
295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t asccpyn(wchar_t* buffer, size_t buflen,
297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch               const char* source, size_t srclen = SIZE_UNKNOWN);
298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // WIN32
300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Traits<char> specializations
303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<>
306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct Traits<char> {
307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  typedef std::string string;
308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  inline static const char* empty_str() { return ""; }
309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
310f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
311f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Traits<wchar_t> specializations (Windows only, currently)
313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtemplate<>
318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct Traits<wchar_t> {
319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  typedef std::wstring string;
320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  inline static const wchar_t* Traits<wchar_t>::empty_str() { return L""; }
321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // WIN32
324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Replaces all occurrences of "search" with "replace".
326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid replace_substrs(const char *search,
327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                     size_t search_len,
328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                     const char *replace,
329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                     size_t replace_len,
330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                     std::string *s);
331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// True iff s1 starts with s2.
333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool starts_with(const char *s1, const char *s2);
334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
335dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Remove leading and trailing whitespaces.
336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string string_trim(const std::string& s);
337dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}  // namespace talk_base
339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // TALK_BASE_STRINGUTILS_H__
341