1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_STRINGS_STRING_UTIL_WIN_H_
6 #define BASE_STRINGS_STRING_UTIL_WIN_H_
7
8 #include <stdarg.h>
9 #include <stddef.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <wchar.h>
13
14 #include <string>
15 #include <string_view>
16 #include <vector>
17
18 #include "base/check.h"
19 #include "base/containers/span.h"
20 #include "base/strings/string_util.h"
21
22 namespace base {
23
24 // Chromium code style is to not use malloc'd strings; this is only for use
25 // for interaction with APIs that require it.
strdup(const char * str)26 inline char* strdup(const char* str) {
27 return _strdup(str);
28 }
29
vsnprintf(char * buffer,size_t size,const char * format,va_list arguments)30 inline int vsnprintf(char* buffer, size_t size,
31 const char* format, va_list arguments) {
32 int length = vsnprintf_s(buffer, size, size - 1, format, arguments);
33 if (length < 0)
34 return _vscprintf(format, arguments);
35 return length;
36 }
37
vswprintf(wchar_t * buffer,size_t size,const wchar_t * format,va_list arguments)38 inline int vswprintf(wchar_t* buffer, size_t size,
39 const wchar_t* format, va_list arguments) {
40 DCHECK(IsWprintfFormatPortable(format));
41
42 int length = _vsnwprintf_s(buffer, size, size - 1, format, arguments);
43 if (length < 0)
44 return _vscwprintf(format, arguments);
45 return length;
46 }
47
48 // Utility functions to access the underlying string buffer as a wide char
49 // pointer.
50 //
51 // Note: These functions violate strict aliasing when char16_t and wchar_t are
52 // unrelated types. We thus pass -fno-strict-aliasing to the compiler on
53 // non-Windows platforms [1], and rely on it being off in Clang's CL mode [2].
54 //
55 // [1] https://crrev.com/b9a0976622/build/config/compiler/BUILD.gn#244
56 // [2]
57 // https://github.com/llvm/llvm-project/blob/1e28a66/clang/lib/Driver/ToolChains/Clang.cpp#L3949
as_writable_wcstr(char16_t * str)58 inline wchar_t* as_writable_wcstr(char16_t* str) {
59 return reinterpret_cast<wchar_t*>(str);
60 }
61
as_writable_wcstr(std::u16string & str)62 inline wchar_t* as_writable_wcstr(std::u16string& str) {
63 return reinterpret_cast<wchar_t*>(data(str));
64 }
65
as_wcstr(const char16_t * str)66 inline const wchar_t* as_wcstr(const char16_t* str) {
67 return reinterpret_cast<const wchar_t*>(str);
68 }
69
as_wcstr(std::u16string_view str)70 inline const wchar_t* as_wcstr(std::u16string_view str) {
71 return reinterpret_cast<const wchar_t*>(str.data());
72 }
73
74 // Utility functions to access the underlying string buffer as a char16_t
75 // pointer.
as_writable_u16cstr(wchar_t * str)76 inline char16_t* as_writable_u16cstr(wchar_t* str) {
77 return reinterpret_cast<char16_t*>(str);
78 }
79
as_writable_u16cstr(std::wstring & str)80 inline char16_t* as_writable_u16cstr(std::wstring& str) {
81 return reinterpret_cast<char16_t*>(data(str));
82 }
83
as_u16cstr(const wchar_t * str)84 inline const char16_t* as_u16cstr(const wchar_t* str) {
85 return reinterpret_cast<const char16_t*>(str);
86 }
87
as_u16cstr(std::wstring_view str)88 inline const char16_t* as_u16cstr(std::wstring_view str) {
89 return reinterpret_cast<const char16_t*>(str.data());
90 }
91
92 // Utility functions to convert between std::wstring_view and
93 // std::u16string_view.
AsWStringView(std::u16string_view str)94 inline std::wstring_view AsWStringView(std::u16string_view str) {
95 return std::wstring_view(as_wcstr(str.data()), str.size());
96 }
97
AsStringPiece16(std::wstring_view str)98 inline std::u16string_view AsStringPiece16(std::wstring_view str) {
99 return std::u16string_view(as_u16cstr(str.data()), str.size());
100 }
101
AsWString(std::u16string_view str)102 inline std::wstring AsWString(std::u16string_view str) {
103 return std::wstring(as_wcstr(str.data()), str.size());
104 }
105
AsString16(std::wstring_view str)106 inline std::u16string AsString16(std::wstring_view str) {
107 return std::u16string(as_u16cstr(str.data()), str.size());
108 }
109
110 // The following section contains overloads of the cross-platform APIs for
111 // std::wstring and std::wstring_view.
112 BASE_EXPORT bool IsStringASCII(std::wstring_view str);
113
114 BASE_EXPORT std::wstring ToLowerASCII(std::wstring_view str);
115
116 BASE_EXPORT std::wstring ToUpperASCII(std::wstring_view str);
117
118 BASE_EXPORT int CompareCaseInsensitiveASCII(std::wstring_view a,
119 std::wstring_view b);
120
EqualsCaseInsensitiveASCII(std::wstring_view a,std::wstring_view b)121 inline bool EqualsCaseInsensitiveASCII(std::wstring_view a,
122 std::wstring_view b) {
123 return internal::EqualsCaseInsensitiveASCIIT(a, b);
124 }
EqualsCaseInsensitiveASCII(std::wstring_view a,std::string_view b)125 inline bool EqualsCaseInsensitiveASCII(std::wstring_view a,
126 std::string_view b) {
127 return internal::EqualsCaseInsensitiveASCIIT(a, b);
128 }
EqualsCaseInsensitiveASCII(std::string_view a,std::wstring_view b)129 inline bool EqualsCaseInsensitiveASCII(std::string_view a,
130 std::wstring_view b) {
131 return internal::EqualsCaseInsensitiveASCIIT(a, b);
132 }
133
134 BASE_EXPORT bool RemoveChars(std::wstring_view input,
135 std::wstring_view remove_chars,
136 std::wstring* output);
137
138 BASE_EXPORT bool ReplaceChars(std::wstring_view input,
139 std::wstring_view replace_chars,
140 std::wstring_view replace_with,
141 std::wstring* output);
142
143 BASE_EXPORT bool TrimString(std::wstring_view input,
144 std::wstring_view trim_chars,
145 std::wstring* output);
146
147 BASE_EXPORT std::wstring_view TrimString(std::wstring_view input,
148 std::wstring_view trim_chars,
149 TrimPositions positions);
150
151 BASE_EXPORT TrimPositions TrimWhitespace(std::wstring_view input,
152 TrimPositions positions,
153 std::wstring* output);
154
155 BASE_EXPORT std::wstring_view TrimWhitespace(std::wstring_view input,
156 TrimPositions positions);
157
158 BASE_EXPORT std::wstring CollapseWhitespace(
159 std::wstring_view text,
160 bool trim_sequences_with_line_breaks);
161
162 BASE_EXPORT bool ContainsOnlyChars(std::wstring_view input,
163 std::wstring_view characters);
164
165 BASE_EXPORT bool EqualsASCII(std::u16string_view str, std::string_view ascii);
166
167 BASE_EXPORT bool StartsWith(
168 std::wstring_view str,
169 std::wstring_view search_for,
170 CompareCase case_sensitivity = CompareCase::SENSITIVE);
171
172 BASE_EXPORT bool EndsWith(
173 std::wstring_view str,
174 std::wstring_view search_for,
175 CompareCase case_sensitivity = CompareCase::SENSITIVE);
176
177 BASE_EXPORT void ReplaceFirstSubstringAfterOffset(
178 std::wstring* str,
179 size_t start_offset,
180 std::wstring_view find_this,
181 std::wstring_view replace_with);
182
183 BASE_EXPORT void ReplaceSubstringsAfterOffset(std::wstring* str,
184 size_t start_offset,
185 std::wstring_view find_this,
186 std::wstring_view replace_with);
187
188 BASE_EXPORT wchar_t* WriteInto(std::wstring* str, size_t length_with_null);
189
190 BASE_EXPORT std::wstring JoinString(span<const std::wstring> parts,
191 std::wstring_view separator);
192
193 BASE_EXPORT std::wstring JoinString(span<const std::wstring_view> parts,
194 std::wstring_view separator);
195
196 BASE_EXPORT std::wstring JoinString(
197 std::initializer_list<std::wstring_view> parts,
198 std::wstring_view separator);
199
200 BASE_EXPORT std::wstring ReplaceStringPlaceholders(
201 std::wstring_view format_string,
202 const std::vector<std::wstring>& subst,
203 std::vector<size_t>* offsets);
204
205 } // namespace base
206
207 #endif // BASE_STRINGS_STRING_UTIL_WIN_H_
208