147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_STRINGUTILS_H__
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_STRINGUTILS_H__
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <ctype.h>
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <stdarg.h>
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <stdio.h>
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string.h>
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <malloc.h>
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wchar.h>
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define alloca _alloca
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX)
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef BSD
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <stdlib.h>
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else  // BSD
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <alloca.h>
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // !BSD
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_POSIX
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string>
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/basictypes.h"
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Generic string/memory utilities
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define STACK_ARRAY(TYPE, LEN) static_cast<TYPE*>(::alloca((LEN)*sizeof(TYPE)))
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Complement to memset.  Verifies memory consists of count bytes of value c.
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool memory_check(const void* memory, int c, size_t count);
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Determines whether the simple wildcard pattern matches target.
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Alpha characters in pattern match case-insensitively.
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Asterisks in pattern match 0 or more characters.
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool string_match(const char* target, const char* pattern);
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Rename a bunch of common string functions so they are consistent across
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// platforms and between char and wchar_t variants.
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Here is the full list of functions that are unified:
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//  strlen, strcmp, stricmp, strncmp, strnicmp
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//  strchr, vsnprintf, strtoul, tolowercase
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// tolowercase is like tolower, but not compatible with end-of-file value
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// It's not clear if we will ever use wchar_t strings on unix.  In theory,
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// all strings should be Utf8 all the time, except when interfacing with Win32
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// APIs that require Utf16.
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline char tolowercase(char c) {
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return static_cast<char>(tolower(c));
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline size_t strlen(const wchar_t* s) {
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return wcslen(s);
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int strcmp(const wchar_t* s1, const wchar_t* s2) {
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return wcscmp(s1, s2);
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int stricmp(const wchar_t* s1, const wchar_t* s2) {
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return _wcsicmp(s1, s2);
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return wcsncmp(s1, s2, n);
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int strnicmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return _wcsnicmp(s1, s2, n);
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline const wchar_t* strchr(const wchar_t* s, wchar_t c) {
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return wcschr(s, c);
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline const wchar_t* strstr(const wchar_t* haystack, const wchar_t* needle) {
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return wcsstr(haystack, needle);
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef vsnprintf
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int vsnprintf(wchar_t* buf, size_t n, const wchar_t* fmt, va_list args) {
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return _vsnwprintf(buf, n, fmt, args);
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // !vsnprintf
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline unsigned long strtoul(const wchar_t* snum, wchar_t** end, int base) {
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return wcstoul(snum, end, base);
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline wchar_t tolowercase(wchar_t c) {
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return static_cast<wchar_t>(towlower(c));
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX)
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int _stricmp(const char* s1, const char* s2) {
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return strcasecmp(s1, s2);
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int _strnicmp(const char* s1, const char* s2, size_t n) {
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return strncasecmp(s1, s2, n);
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_POSIX
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Traits simplifies porting string functions to be CTYPE-agnostic
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst size_t SIZE_UNKNOWN = static_cast<size_t>(-1);
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct Traits {
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // STL string type
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  //typedef XXX string;
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Null-terminated string
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  //inline static const CTYPE* empty_str();
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// String utilities which work with char or wchar_t
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = NULL) {
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return str ? str : (def_str ? def_str : Traits<CTYPE>::empty_str());
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst CTYPE* strchr(const CTYPE* str, const CTYPE* chs) {
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (size_t i=0; str[i]; ++i) {
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (size_t j=0; chs[j]; ++j) {
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (str[i] == chs[j]) {
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return str + i;
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return 0;
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) {
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (size_t i=0; i<slen && str[i]; ++i) {
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (str[i] == ch) {
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return str + i;
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return 0;
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t strlenn(const CTYPE* buffer, size_t buflen) {
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t bufpos = 0;
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (buffer[bufpos] && (bufpos < buflen)) {
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ++bufpos;
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return bufpos;
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Safe versions of strncpy, strncat, snprintf and vsnprintf that always
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// null-terminate.
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t strcpyn(CTYPE* buffer, size_t buflen,
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (buflen <= 0)
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (srclen == SIZE_UNKNOWN) {
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    srclen = strlenn(source, buflen - 1);
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (srclen >= buflen) {
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    srclen = buflen - 1;
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(buffer, source, srclen * sizeof(CTYPE));
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  buffer[srclen] = 0;
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return srclen;
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t strcatn(CTYPE* buffer, size_t buflen,
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (buflen <= 0)
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t bufpos = strlenn(buffer, buflen - 1);
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen);
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Some compilers (clang specifically) require vsprintfn be defined before
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// sprintfn.
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t vsprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format,
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 va_list args) {
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int len = vsnprintf(buffer, buflen, format, args);
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((len < 0) || (static_cast<size_t>(len) >= buflen)) {
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    len = static_cast<int>(buflen - 1);
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer[len] = 0;
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return len;
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...);
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<class CTYPE>
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) {
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  va_list args;
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  va_start(args, format);
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t len = vsprintfn(buffer, buflen, format, args);
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  va_end(args);
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return len;
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Allow safe comparing and copying ascii (not UTF-8) with both wide and
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// non-wide character strings.
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int asccmp(const char* s1, const char* s2) {
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return strcmp(s1, s2);
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int ascicmp(const char* s1, const char* s2) {
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return _stricmp(s1, s2);
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int ascncmp(const char* s1, const char* s2, size_t n) {
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return strncmp(s1, s2, n);
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int ascnicmp(const char* s1, const char* s2, size_t n) {
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return _strnicmp(s1, s2, n);
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline size_t asccpyn(char* buffer, size_t buflen,
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      const char* source, size_t srclen = SIZE_UNKNOWN) {
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return strcpyn(buffer, buflen, source, srclen);
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef wchar_t(*CharacterTransformation)(wchar_t);
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline wchar_t identity(wchar_t c) { return c; }
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         CharacterTransformation transformation);
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int asccmp(const wchar_t* s1, const char* s2) {
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), identity);
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int ascicmp(const wchar_t* s1, const char* s2) {
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), tolowercase);
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int ascncmp(const wchar_t* s1, const char* s2, size_t n) {
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ascii_string_compare(s1, s2, n, identity);
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orginline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) {
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ascii_string_compare(s1, s2, n, tolowercase);
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t asccpyn(wchar_t* buffer, size_t buflen,
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org               const char* source, size_t srclen = SIZE_UNKNOWN);
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Traits<char> specializations
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<>
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct Traits<char> {
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::string string;
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  inline static const char* empty_str() { return ""; }
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Traits<wchar_t> specializations (Windows only, currently)
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate<>
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct Traits<wchar_t> {
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::wstring string;
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  inline static const wchar_t* Traits<wchar_t>::empty_str() { return L""; }
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Replaces all occurrences of "search" with "replace".
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid replace_substrs(const char *search,
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     size_t search_len,
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     const char *replace,
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     size_t replace_len,
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     std::string *s);
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// True iff s1 starts with s2.
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool starts_with(const char *s1, const char *s2);
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// True iff s1 ends with s2.
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ends_with(const char *s1, const char *s2);
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Remove leading and trailing whitespaces.
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string string_trim(const std::string& s);
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_BASE_STRINGUTILS_H__
319