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