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 <vector>
16
17 #include "base/check.h"
18 #include "base/containers/span.h"
19 #include "base/strings/string_piece.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(StringPiece16 str)70 inline const wchar_t* as_wcstr(StringPiece16 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(WStringPiece str)88 inline const char16_t* as_u16cstr(WStringPiece str) {
89 return reinterpret_cast<const char16_t*>(str.data());
90 }
91
92 // Utility functions to convert between base::WStringPiece and
93 // base::StringPiece16.
AsWStringPiece(StringPiece16 str)94 inline WStringPiece AsWStringPiece(StringPiece16 str) {
95 return WStringPiece(as_wcstr(str.data()), str.size());
96 }
97
AsStringPiece16(WStringPiece str)98 inline StringPiece16 AsStringPiece16(WStringPiece str) {
99 return StringPiece16(as_u16cstr(str.data()), str.size());
100 }
101
AsWString(StringPiece16 str)102 inline std::wstring AsWString(StringPiece16 str) {
103 return std::wstring(as_wcstr(str.data()), str.size());
104 }
105
AsString16(WStringPiece str)106 inline std::u16string AsString16(WStringPiece 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 base::WStringPiece.
112 BASE_EXPORT bool IsStringASCII(WStringPiece str);
113
114 BASE_EXPORT std::wstring ToLowerASCII(WStringPiece str);
115
116 BASE_EXPORT std::wstring ToUpperASCII(WStringPiece str);
117
118 BASE_EXPORT int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
119
EqualsCaseInsensitiveASCII(WStringPiece a,WStringPiece b)120 inline bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) {
121 return internal::EqualsCaseInsensitiveASCIIT(a, b);
122 }
EqualsCaseInsensitiveASCII(WStringPiece a,StringPiece b)123 inline bool EqualsCaseInsensitiveASCII(WStringPiece a, StringPiece b) {
124 return internal::EqualsCaseInsensitiveASCIIT(a, b);
125 }
EqualsCaseInsensitiveASCII(StringPiece a,WStringPiece b)126 inline bool EqualsCaseInsensitiveASCII(StringPiece a, WStringPiece b) {
127 return internal::EqualsCaseInsensitiveASCIIT(a, b);
128 }
129
130 BASE_EXPORT bool RemoveChars(WStringPiece input,
131 WStringPiece remove_chars,
132 std::wstring* output);
133
134 BASE_EXPORT bool ReplaceChars(WStringPiece input,
135 WStringPiece replace_chars,
136 WStringPiece replace_with,
137 std::wstring* output);
138
139 BASE_EXPORT bool TrimString(WStringPiece input,
140 WStringPiece trim_chars,
141 std::wstring* output);
142
143 BASE_EXPORT WStringPiece TrimString(WStringPiece input,
144 WStringPiece trim_chars,
145 TrimPositions positions);
146
147 BASE_EXPORT TrimPositions TrimWhitespace(WStringPiece input,
148 TrimPositions positions,
149 std::wstring* output);
150
151 BASE_EXPORT WStringPiece TrimWhitespace(WStringPiece input,
152 TrimPositions positions);
153
154 BASE_EXPORT std::wstring CollapseWhitespace(
155 WStringPiece text,
156 bool trim_sequences_with_line_breaks);
157
158 BASE_EXPORT bool ContainsOnlyChars(WStringPiece input, WStringPiece characters);
159
160 BASE_EXPORT bool EqualsASCII(StringPiece16 str, StringPiece ascii);
161
162 BASE_EXPORT bool StartsWith(
163 WStringPiece str,
164 WStringPiece search_for,
165 CompareCase case_sensitivity = CompareCase::SENSITIVE);
166
167 BASE_EXPORT bool EndsWith(
168 WStringPiece str,
169 WStringPiece search_for,
170 CompareCase case_sensitivity = CompareCase::SENSITIVE);
171
172 BASE_EXPORT void ReplaceFirstSubstringAfterOffset(std::wstring* str,
173 size_t start_offset,
174 WStringPiece find_this,
175 WStringPiece replace_with);
176
177 BASE_EXPORT void ReplaceSubstringsAfterOffset(std::wstring* str,
178 size_t start_offset,
179 WStringPiece find_this,
180 WStringPiece replace_with);
181
182 BASE_EXPORT wchar_t* WriteInto(std::wstring* str, size_t length_with_null);
183
184 BASE_EXPORT std::wstring JoinString(span<const std::wstring> parts,
185 WStringPiece separator);
186
187 BASE_EXPORT std::wstring JoinString(span<const WStringPiece> parts,
188 WStringPiece separator);
189
190 BASE_EXPORT std::wstring JoinString(std::initializer_list<WStringPiece> parts,
191 WStringPiece separator);
192
193 BASE_EXPORT std::wstring ReplaceStringPlaceholders(
194 WStringPiece format_string,
195 const std::vector<std::wstring>& subst,
196 std::vector<size_t>* offsets);
197
198 } // namespace base
199
200 #endif // BASE_STRINGS_STRING_UTIL_WIN_H_
201