henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
| 3 | * |
| 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 |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 11 | #ifndef RTC_BASE_STRING_UTILS_H_ |
| 12 | #define RTC_BASE_STRING_UTILS_H_ |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 13 | |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 14 | #include <stdio.h> |
| 15 | #include <string.h> |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 16 | |
Ali Tofigh | 7fa9057 | 2022-03-17 14:47:49 | [diff] [blame] | 17 | #include "absl/strings/string_view.h" |
| 18 | |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 19 | #if defined(WEBRTC_WIN) |
| 20 | #include <malloc.h> |
| 21 | #include <wchar.h> |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 22 | #include <windows.h> |
Yves Gerey | 988cc08 | 2018-10-23 10:03:01 | [diff] [blame] | 23 | |
Henrik Kjellander | c036276 | 2017-06-29 06:03:04 | [diff] [blame] | 24 | #endif // WEBRTC_WIN |
henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 25 | |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 26 | #if defined(WEBRTC_POSIX) |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 27 | #include <stdlib.h> |
Yves Gerey | 988cc08 | 2018-10-23 10:03:01 | [diff] [blame] | 28 | #include <strings.h> |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 29 | #endif // WEBRTC_POSIX |
| 30 | |
| 31 | #include <string> |
| 32 | |
Ali Tofigh | 7fa9057 | 2022-03-17 14:47:49 | [diff] [blame] | 33 | #include "absl/strings/string_view.h" |
| 34 | |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 35 | namespace rtc { |
| 36 | |
| 37 | const size_t SIZE_UNKNOWN = static_cast<size_t>(-1); |
| 38 | |
Ali Tofigh | 7fa9057 | 2022-03-17 14:47:49 | [diff] [blame] | 39 | // An absl::string_view comparator functor for use with container types such as |
| 40 | // std::map that support heterogenous lookup. |
| 41 | // |
| 42 | // Example usage: |
| 43 | // std::map<std::string, int, rtc::AbslStringViewCmp> my_map; |
| 44 | struct AbslStringViewCmp { |
| 45 | using is_transparent = void; |
| 46 | bool operator()(absl::string_view a, absl::string_view b) const { |
| 47 | return a < b; |
| 48 | } |
| 49 | }; |
| 50 | |
Niels Möller | d189252 | 2018-10-17 11:39:01 | [diff] [blame] | 51 | // Safe version of strncpy that always nul-terminate. |
Ali Tofigh | e5b2220 | 2022-03-24 23:08:32 | [diff] [blame] | 52 | size_t strcpyn(char* buffer, size_t buflen, absl::string_view source); |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 53 | |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 54 | /////////////////////////////////////////////////////////////////////////////// |
| 55 | // UTF helpers (Windows only) |
| 56 | /////////////////////////////////////////////////////////////////////////////// |
| 57 | |
| 58 | #if defined(WEBRTC_WIN) |
| 59 | |
| 60 | inline std::wstring ToUtf16(const char* utf8, size_t len) { |
Noah Richards | 4ed5b08 | 2019-07-30 18:56:08 | [diff] [blame] | 61 | if (len == 0) |
| 62 | return std::wstring(); |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 63 | int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(len), |
| 64 | nullptr, 0); |
Niels Möller | f25df35 | 2019-05-24 07:14:13 | [diff] [blame] | 65 | std::wstring ws(len16, 0); |
| 66 | ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(len), &*ws.begin(), |
| 67 | len16); |
| 68 | return ws; |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 69 | } |
| 70 | |
Ali Tofigh | 7fa9057 | 2022-03-17 14:47:49 | [diff] [blame] | 71 | inline std::wstring ToUtf16(absl::string_view str) { |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 72 | return ToUtf16(str.data(), str.length()); |
| 73 | } |
| 74 | |
| 75 | inline std::string ToUtf8(const wchar_t* wide, size_t len) { |
Noah Richards | 4ed5b08 | 2019-07-30 18:56:08 | [diff] [blame] | 76 | if (len == 0) |
| 77 | return std::string(); |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 78 | int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len), |
| 79 | nullptr, 0, nullptr, nullptr); |
Niels Möller | f25df35 | 2019-05-24 07:14:13 | [diff] [blame] | 80 | std::string ns(len8, 0); |
| 81 | ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len), &*ns.begin(), |
| 82 | len8, nullptr, nullptr); |
| 83 | return ns; |
Patrik Höglund | a8005cf | 2017-12-13 15:05:42 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | inline std::string ToUtf8(const wchar_t* wide) { |
| 87 | return ToUtf8(wide, wcslen(wide)); |
| 88 | } |
| 89 | |
| 90 | inline std::string ToUtf8(const std::wstring& wstr) { |
| 91 | return ToUtf8(wstr.data(), wstr.length()); |
| 92 | } |
| 93 | |
| 94 | #endif // WEBRTC_WIN |
| 95 | |
Jonas Olsson | abbe841 | 2018-04-03 11:40:05 | [diff] [blame] | 96 | // TODO(jonasolsson): replace with absl::Hex when that becomes available. |
Ali Tofigh | 6223809 | 2022-01-25 12:27:19 | [diff] [blame] | 97 | std::string ToHex(int i); |
Jonas Olsson | d8c5078 | 2018-09-07 09:21:28 | [diff] [blame] | 98 | |
Markus Handell | 3d46d0b | 2021-05-27 19:42:57 | [diff] [blame] | 99 | // CompileTimeString comprises of a string-like object which can be used as a |
| 100 | // regular const char* in compile time and supports concatenation. Useful for |
| 101 | // concatenating constexpr strings in for example macro declarations. |
| 102 | namespace rtc_base_string_utils_internal { |
| 103 | template <int NPlus1> |
| 104 | struct CompileTimeString { |
| 105 | char string[NPlus1] = {0}; |
| 106 | constexpr CompileTimeString() = default; |
| 107 | template <int MPlus1> |
| 108 | explicit constexpr CompileTimeString(const char (&chars)[MPlus1]) { |
| 109 | char* chars_pointer = string; |
| 110 | for (auto c : chars) |
| 111 | *chars_pointer++ = c; |
| 112 | } |
| 113 | template <int MPlus1> |
| 114 | constexpr auto Concat(CompileTimeString<MPlus1> b) { |
| 115 | CompileTimeString<NPlus1 + MPlus1 - 1> result; |
| 116 | char* chars_pointer = result.string; |
| 117 | for (auto c : string) |
| 118 | *chars_pointer++ = c; |
| 119 | chars_pointer = result.string + NPlus1 - 1; |
| 120 | for (auto c : b.string) |
| 121 | *chars_pointer++ = c; |
| 122 | result.string[NPlus1 + MPlus1 - 2] = 0; |
| 123 | return result; |
| 124 | } |
| 125 | constexpr operator const char*() { return string; } |
| 126 | }; |
| 127 | } // namespace rtc_base_string_utils_internal |
| 128 | |
| 129 | // Makes a constexpr CompileTimeString<X> without having to specify X |
| 130 | // explicitly. |
| 131 | template <int N> |
| 132 | constexpr auto MakeCompileTimeString(const char (&a)[N]) { |
| 133 | return rtc_base_string_utils_internal::CompileTimeString<N>(a); |
| 134 | } |
| 135 | |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 136 | } // namespace rtc |
| 137 | |
Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 138 | #endif // RTC_BASE_STRING_UTILS_H_ |