1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <errno.h>
8*6777b538SAndroid Build Coastguard Worker #include <math.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdarg.h>
10*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
11*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
12*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
13*6777b538SAndroid Build Coastguard Worker #include <string.h>
14*6777b538SAndroid Build Coastguard Worker #include <time.h>
15*6777b538SAndroid Build Coastguard Worker #include <wchar.h>
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker #include <limits>
18*6777b538SAndroid Build Coastguard Worker #include <optional>
19*6777b538SAndroid Build Coastguard Worker #include <string_view>
20*6777b538SAndroid Build Coastguard Worker #include <type_traits>
21*6777b538SAndroid Build Coastguard Worker #include <vector>
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util_impl_helpers.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util_internal.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversion_utils.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/third_party/icu/icu_utf.h"
31*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker namespace base {
34*6777b538SAndroid Build Coastguard Worker
IsWprintfFormatPortable(const wchar_t * format)35*6777b538SAndroid Build Coastguard Worker bool IsWprintfFormatPortable(const wchar_t* format) {
36*6777b538SAndroid Build Coastguard Worker for (const wchar_t* position = format; *position != '\0'; ++position) {
37*6777b538SAndroid Build Coastguard Worker if (*position == '%') {
38*6777b538SAndroid Build Coastguard Worker bool in_specification = true;
39*6777b538SAndroid Build Coastguard Worker bool modifier_l = false;
40*6777b538SAndroid Build Coastguard Worker while (in_specification) {
41*6777b538SAndroid Build Coastguard Worker // Eat up characters until reaching a known specifier.
42*6777b538SAndroid Build Coastguard Worker if (*++position == '\0') {
43*6777b538SAndroid Build Coastguard Worker // The format string ended in the middle of a specification. Call
44*6777b538SAndroid Build Coastguard Worker // it portable because no unportable specifications were found. The
45*6777b538SAndroid Build Coastguard Worker // string is equally broken on all platforms.
46*6777b538SAndroid Build Coastguard Worker return true;
47*6777b538SAndroid Build Coastguard Worker }
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Worker if (*position == 'l') {
50*6777b538SAndroid Build Coastguard Worker // 'l' is the only thing that can save the 's' and 'c' specifiers.
51*6777b538SAndroid Build Coastguard Worker modifier_l = true;
52*6777b538SAndroid Build Coastguard Worker } else if (((*position == 's' || *position == 'c') && !modifier_l) ||
53*6777b538SAndroid Build Coastguard Worker *position == 'S' || *position == 'C' || *position == 'F' ||
54*6777b538SAndroid Build Coastguard Worker *position == 'D' || *position == 'O' || *position == 'U') {
55*6777b538SAndroid Build Coastguard Worker // Not portable.
56*6777b538SAndroid Build Coastguard Worker return false;
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker if (wcschr(L"diouxXeEfgGaAcspn%", *position)) {
60*6777b538SAndroid Build Coastguard Worker // Portable, keep scanning the rest of the format string.
61*6777b538SAndroid Build Coastguard Worker in_specification = false;
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker return true;
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker
ToLowerASCII(StringPiece str)70*6777b538SAndroid Build Coastguard Worker std::string ToLowerASCII(StringPiece str) {
71*6777b538SAndroid Build Coastguard Worker return internal::ToLowerASCIIImpl(str);
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker
ToLowerASCII(StringPiece16 str)74*6777b538SAndroid Build Coastguard Worker std::u16string ToLowerASCII(StringPiece16 str) {
75*6777b538SAndroid Build Coastguard Worker return internal::ToLowerASCIIImpl(str);
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker
ToUpperASCII(StringPiece str)78*6777b538SAndroid Build Coastguard Worker std::string ToUpperASCII(StringPiece str) {
79*6777b538SAndroid Build Coastguard Worker return internal::ToUpperASCIIImpl(str);
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker
ToUpperASCII(StringPiece16 str)82*6777b538SAndroid Build Coastguard Worker std::u16string ToUpperASCII(StringPiece16 str) {
83*6777b538SAndroid Build Coastguard Worker return internal::ToUpperASCIIImpl(str);
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker
EmptyString()86*6777b538SAndroid Build Coastguard Worker const std::string& EmptyString() {
87*6777b538SAndroid Build Coastguard Worker static const base::NoDestructor<std::string> s;
88*6777b538SAndroid Build Coastguard Worker return *s;
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker
EmptyString16()91*6777b538SAndroid Build Coastguard Worker const std::u16string& EmptyString16() {
92*6777b538SAndroid Build Coastguard Worker static const base::NoDestructor<std::u16string> s16;
93*6777b538SAndroid Build Coastguard Worker return *s16;
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker
ReplaceChars(StringPiece16 input,StringPiece16 replace_chars,StringPiece16 replace_with,std::u16string * output)96*6777b538SAndroid Build Coastguard Worker bool ReplaceChars(StringPiece16 input,
97*6777b538SAndroid Build Coastguard Worker StringPiece16 replace_chars,
98*6777b538SAndroid Build Coastguard Worker StringPiece16 replace_with,
99*6777b538SAndroid Build Coastguard Worker std::u16string* output) {
100*6777b538SAndroid Build Coastguard Worker return internal::ReplaceCharsT(input, replace_chars, replace_with, output);
101*6777b538SAndroid Build Coastguard Worker }
102*6777b538SAndroid Build Coastguard Worker
ReplaceChars(StringPiece input,StringPiece replace_chars,StringPiece replace_with,std::string * output)103*6777b538SAndroid Build Coastguard Worker bool ReplaceChars(StringPiece input,
104*6777b538SAndroid Build Coastguard Worker StringPiece replace_chars,
105*6777b538SAndroid Build Coastguard Worker StringPiece replace_with,
106*6777b538SAndroid Build Coastguard Worker std::string* output) {
107*6777b538SAndroid Build Coastguard Worker return internal::ReplaceCharsT(input, replace_chars, replace_with, output);
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker
RemoveChars(StringPiece16 input,StringPiece16 remove_chars,std::u16string * output)110*6777b538SAndroid Build Coastguard Worker bool RemoveChars(StringPiece16 input,
111*6777b538SAndroid Build Coastguard Worker StringPiece16 remove_chars,
112*6777b538SAndroid Build Coastguard Worker std::u16string* output) {
113*6777b538SAndroid Build Coastguard Worker return internal::ReplaceCharsT(input, remove_chars, StringPiece16(), output);
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker
RemoveChars(StringPiece input,StringPiece remove_chars,std::string * output)116*6777b538SAndroid Build Coastguard Worker bool RemoveChars(StringPiece input,
117*6777b538SAndroid Build Coastguard Worker StringPiece remove_chars,
118*6777b538SAndroid Build Coastguard Worker std::string* output) {
119*6777b538SAndroid Build Coastguard Worker return internal::ReplaceCharsT(input, remove_chars, StringPiece(), output);
120*6777b538SAndroid Build Coastguard Worker }
121*6777b538SAndroid Build Coastguard Worker
TrimString(StringPiece16 input,StringPiece16 trim_chars,std::u16string * output)122*6777b538SAndroid Build Coastguard Worker bool TrimString(StringPiece16 input,
123*6777b538SAndroid Build Coastguard Worker StringPiece16 trim_chars,
124*6777b538SAndroid Build Coastguard Worker std::u16string* output) {
125*6777b538SAndroid Build Coastguard Worker return internal::TrimStringT(input, trim_chars, TRIM_ALL, output) !=
126*6777b538SAndroid Build Coastguard Worker TRIM_NONE;
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker
TrimString(StringPiece input,StringPiece trim_chars,std::string * output)129*6777b538SAndroid Build Coastguard Worker bool TrimString(StringPiece input,
130*6777b538SAndroid Build Coastguard Worker StringPiece trim_chars,
131*6777b538SAndroid Build Coastguard Worker std::string* output) {
132*6777b538SAndroid Build Coastguard Worker return internal::TrimStringT(input, trim_chars, TRIM_ALL, output) !=
133*6777b538SAndroid Build Coastguard Worker TRIM_NONE;
134*6777b538SAndroid Build Coastguard Worker }
135*6777b538SAndroid Build Coastguard Worker
TrimString(StringPiece16 input,StringPiece16 trim_chars,TrimPositions positions)136*6777b538SAndroid Build Coastguard Worker StringPiece16 TrimString(StringPiece16 input,
137*6777b538SAndroid Build Coastguard Worker StringPiece16 trim_chars,
138*6777b538SAndroid Build Coastguard Worker TrimPositions positions) {
139*6777b538SAndroid Build Coastguard Worker return internal::TrimStringPieceT(input, trim_chars, positions);
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker
TrimString(StringPiece input,StringPiece trim_chars,TrimPositions positions)142*6777b538SAndroid Build Coastguard Worker StringPiece TrimString(StringPiece input,
143*6777b538SAndroid Build Coastguard Worker StringPiece trim_chars,
144*6777b538SAndroid Build Coastguard Worker TrimPositions positions) {
145*6777b538SAndroid Build Coastguard Worker return internal::TrimStringPieceT(input, trim_chars, positions);
146*6777b538SAndroid Build Coastguard Worker }
147*6777b538SAndroid Build Coastguard Worker
TruncateUTF8ToByteSize(const std::string & input,const size_t byte_size,std::string * output)148*6777b538SAndroid Build Coastguard Worker void TruncateUTF8ToByteSize(const std::string& input,
149*6777b538SAndroid Build Coastguard Worker const size_t byte_size,
150*6777b538SAndroid Build Coastguard Worker std::string* output) {
151*6777b538SAndroid Build Coastguard Worker DCHECK(output);
152*6777b538SAndroid Build Coastguard Worker if (byte_size > input.length()) {
153*6777b538SAndroid Build Coastguard Worker *output = input;
154*6777b538SAndroid Build Coastguard Worker return;
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker DCHECK_LE(byte_size,
157*6777b538SAndroid Build Coastguard Worker static_cast<uint32_t>(std::numeric_limits<int32_t>::max()));
158*6777b538SAndroid Build Coastguard Worker // Note: This cast is necessary because CBU8_NEXT uses int32_ts.
159*6777b538SAndroid Build Coastguard Worker int32_t truncation_length = static_cast<int32_t>(byte_size);
160*6777b538SAndroid Build Coastguard Worker int32_t char_index = truncation_length - 1;
161*6777b538SAndroid Build Coastguard Worker const char* data = input.data();
162*6777b538SAndroid Build Coastguard Worker
163*6777b538SAndroid Build Coastguard Worker // Using CBU8, we will move backwards from the truncation point
164*6777b538SAndroid Build Coastguard Worker // to the beginning of the string looking for a valid UTF8
165*6777b538SAndroid Build Coastguard Worker // character. Once a full UTF8 character is found, we will
166*6777b538SAndroid Build Coastguard Worker // truncate the string to the end of that character.
167*6777b538SAndroid Build Coastguard Worker while (char_index >= 0) {
168*6777b538SAndroid Build Coastguard Worker int32_t prev = char_index;
169*6777b538SAndroid Build Coastguard Worker base_icu::UChar32 code_point = 0;
170*6777b538SAndroid Build Coastguard Worker CBU8_NEXT(reinterpret_cast<const uint8_t*>(data), char_index,
171*6777b538SAndroid Build Coastguard Worker truncation_length, code_point);
172*6777b538SAndroid Build Coastguard Worker if (!IsValidCharacter(code_point)) {
173*6777b538SAndroid Build Coastguard Worker char_index = prev - 1;
174*6777b538SAndroid Build Coastguard Worker } else {
175*6777b538SAndroid Build Coastguard Worker break;
176*6777b538SAndroid Build Coastguard Worker }
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker if (char_index >= 0 )
180*6777b538SAndroid Build Coastguard Worker *output = input.substr(0, static_cast<size_t>(char_index));
181*6777b538SAndroid Build Coastguard Worker else
182*6777b538SAndroid Build Coastguard Worker output->clear();
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker
TrimWhitespace(StringPiece16 input,TrimPositions positions,std::u16string * output)185*6777b538SAndroid Build Coastguard Worker TrimPositions TrimWhitespace(StringPiece16 input,
186*6777b538SAndroid Build Coastguard Worker TrimPositions positions,
187*6777b538SAndroid Build Coastguard Worker std::u16string* output) {
188*6777b538SAndroid Build Coastguard Worker return internal::TrimStringT(input, StringPiece16(kWhitespaceUTF16),
189*6777b538SAndroid Build Coastguard Worker positions, output);
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker
TrimWhitespace(StringPiece16 input,TrimPositions positions)192*6777b538SAndroid Build Coastguard Worker StringPiece16 TrimWhitespace(StringPiece16 input,
193*6777b538SAndroid Build Coastguard Worker TrimPositions positions) {
194*6777b538SAndroid Build Coastguard Worker return internal::TrimStringPieceT(input, StringPiece16(kWhitespaceUTF16),
195*6777b538SAndroid Build Coastguard Worker positions);
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker
TrimWhitespaceASCII(StringPiece input,TrimPositions positions,std::string * output)198*6777b538SAndroid Build Coastguard Worker TrimPositions TrimWhitespaceASCII(StringPiece input,
199*6777b538SAndroid Build Coastguard Worker TrimPositions positions,
200*6777b538SAndroid Build Coastguard Worker std::string* output) {
201*6777b538SAndroid Build Coastguard Worker return internal::TrimStringT(input, StringPiece(kWhitespaceASCII), positions,
202*6777b538SAndroid Build Coastguard Worker output);
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker
TrimWhitespaceASCII(StringPiece input,TrimPositions positions)205*6777b538SAndroid Build Coastguard Worker StringPiece TrimWhitespaceASCII(StringPiece input, TrimPositions positions) {
206*6777b538SAndroid Build Coastguard Worker return internal::TrimStringPieceT(input, StringPiece(kWhitespaceASCII),
207*6777b538SAndroid Build Coastguard Worker positions);
208*6777b538SAndroid Build Coastguard Worker }
209*6777b538SAndroid Build Coastguard Worker
CollapseWhitespace(StringPiece16 text,bool trim_sequences_with_line_breaks)210*6777b538SAndroid Build Coastguard Worker std::u16string CollapseWhitespace(StringPiece16 text,
211*6777b538SAndroid Build Coastguard Worker bool trim_sequences_with_line_breaks) {
212*6777b538SAndroid Build Coastguard Worker return internal::CollapseWhitespaceT(text, trim_sequences_with_line_breaks);
213*6777b538SAndroid Build Coastguard Worker }
214*6777b538SAndroid Build Coastguard Worker
CollapseWhitespaceASCII(StringPiece text,bool trim_sequences_with_line_breaks)215*6777b538SAndroid Build Coastguard Worker std::string CollapseWhitespaceASCII(StringPiece text,
216*6777b538SAndroid Build Coastguard Worker bool trim_sequences_with_line_breaks) {
217*6777b538SAndroid Build Coastguard Worker return internal::CollapseWhitespaceT(text, trim_sequences_with_line_breaks);
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker
ContainsOnlyChars(StringPiece input,StringPiece characters)220*6777b538SAndroid Build Coastguard Worker bool ContainsOnlyChars(StringPiece input, StringPiece characters) {
221*6777b538SAndroid Build Coastguard Worker return input.find_first_not_of(characters) == StringPiece::npos;
222*6777b538SAndroid Build Coastguard Worker }
223*6777b538SAndroid Build Coastguard Worker
ContainsOnlyChars(StringPiece16 input,StringPiece16 characters)224*6777b538SAndroid Build Coastguard Worker bool ContainsOnlyChars(StringPiece16 input, StringPiece16 characters) {
225*6777b538SAndroid Build Coastguard Worker return input.find_first_not_of(characters) == StringPiece16::npos;
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker
IsStringASCII(StringPiece str)229*6777b538SAndroid Build Coastguard Worker bool IsStringASCII(StringPiece str) {
230*6777b538SAndroid Build Coastguard Worker return internal::DoIsStringASCII(str.data(), str.length());
231*6777b538SAndroid Build Coastguard Worker }
232*6777b538SAndroid Build Coastguard Worker
IsStringASCII(StringPiece16 str)233*6777b538SAndroid Build Coastguard Worker bool IsStringASCII(StringPiece16 str) {
234*6777b538SAndroid Build Coastguard Worker return internal::DoIsStringASCII(str.data(), str.length());
235*6777b538SAndroid Build Coastguard Worker }
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_32_BIT)
IsStringASCII(std::wstring_view str)238*6777b538SAndroid Build Coastguard Worker bool IsStringASCII(std::wstring_view str) {
239*6777b538SAndroid Build Coastguard Worker return internal::DoIsStringASCII(str.data(), str.length());
240*6777b538SAndroid Build Coastguard Worker }
241*6777b538SAndroid Build Coastguard Worker #endif
242*6777b538SAndroid Build Coastguard Worker
IsStringUTF8(StringPiece str)243*6777b538SAndroid Build Coastguard Worker bool IsStringUTF8(StringPiece str) {
244*6777b538SAndroid Build Coastguard Worker return internal::DoIsStringUTF8<IsValidCharacter>(str);
245*6777b538SAndroid Build Coastguard Worker }
246*6777b538SAndroid Build Coastguard Worker
IsStringUTF8AllowingNoncharacters(StringPiece str)247*6777b538SAndroid Build Coastguard Worker bool IsStringUTF8AllowingNoncharacters(StringPiece str) {
248*6777b538SAndroid Build Coastguard Worker return internal::DoIsStringUTF8<IsValidCodepoint>(str);
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker
EqualsASCII(StringPiece16 str,StringPiece ascii)251*6777b538SAndroid Build Coastguard Worker bool EqualsASCII(StringPiece16 str, StringPiece ascii) {
252*6777b538SAndroid Build Coastguard Worker return ranges::equal(ascii, str);
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker
StartsWith(StringPiece str,StringPiece search_for,CompareCase case_sensitivity)255*6777b538SAndroid Build Coastguard Worker bool StartsWith(StringPiece str,
256*6777b538SAndroid Build Coastguard Worker StringPiece search_for,
257*6777b538SAndroid Build Coastguard Worker CompareCase case_sensitivity) {
258*6777b538SAndroid Build Coastguard Worker return internal::StartsWithT(str, search_for, case_sensitivity);
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker
StartsWith(StringPiece16 str,StringPiece16 search_for,CompareCase case_sensitivity)261*6777b538SAndroid Build Coastguard Worker bool StartsWith(StringPiece16 str,
262*6777b538SAndroid Build Coastguard Worker StringPiece16 search_for,
263*6777b538SAndroid Build Coastguard Worker CompareCase case_sensitivity) {
264*6777b538SAndroid Build Coastguard Worker return internal::StartsWithT(str, search_for, case_sensitivity);
265*6777b538SAndroid Build Coastguard Worker }
266*6777b538SAndroid Build Coastguard Worker
EndsWith(StringPiece str,StringPiece search_for,CompareCase case_sensitivity)267*6777b538SAndroid Build Coastguard Worker bool EndsWith(StringPiece str,
268*6777b538SAndroid Build Coastguard Worker StringPiece search_for,
269*6777b538SAndroid Build Coastguard Worker CompareCase case_sensitivity) {
270*6777b538SAndroid Build Coastguard Worker return internal::EndsWithT(str, search_for, case_sensitivity);
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker
EndsWith(StringPiece16 str,StringPiece16 search_for,CompareCase case_sensitivity)273*6777b538SAndroid Build Coastguard Worker bool EndsWith(StringPiece16 str,
274*6777b538SAndroid Build Coastguard Worker StringPiece16 search_for,
275*6777b538SAndroid Build Coastguard Worker CompareCase case_sensitivity) {
276*6777b538SAndroid Build Coastguard Worker return internal::EndsWithT(str, search_for, case_sensitivity);
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker
HexDigitToInt(char c)279*6777b538SAndroid Build Coastguard Worker char HexDigitToInt(char c) {
280*6777b538SAndroid Build Coastguard Worker DCHECK(IsHexDigit(c));
281*6777b538SAndroid Build Coastguard Worker if (c >= '0' && c <= '9')
282*6777b538SAndroid Build Coastguard Worker return static_cast<char>(c - '0');
283*6777b538SAndroid Build Coastguard Worker return (c >= 'A' && c <= 'F') ? static_cast<char>(c - 'A' + 10)
284*6777b538SAndroid Build Coastguard Worker : static_cast<char>(c - 'a' + 10);
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker
287*6777b538SAndroid Build Coastguard Worker static const char* const kByteStringsUnlocalized[] = {
288*6777b538SAndroid Build Coastguard Worker " B",
289*6777b538SAndroid Build Coastguard Worker " kB",
290*6777b538SAndroid Build Coastguard Worker " MB",
291*6777b538SAndroid Build Coastguard Worker " GB",
292*6777b538SAndroid Build Coastguard Worker " TB",
293*6777b538SAndroid Build Coastguard Worker " PB"
294*6777b538SAndroid Build Coastguard Worker };
295*6777b538SAndroid Build Coastguard Worker
FormatBytesUnlocalized(int64_t bytes)296*6777b538SAndroid Build Coastguard Worker std::u16string FormatBytesUnlocalized(int64_t bytes) {
297*6777b538SAndroid Build Coastguard Worker double unit_amount = static_cast<double>(bytes);
298*6777b538SAndroid Build Coastguard Worker size_t dimension = 0;
299*6777b538SAndroid Build Coastguard Worker const int kKilo = 1024;
300*6777b538SAndroid Build Coastguard Worker while (unit_amount >= kKilo &&
301*6777b538SAndroid Build Coastguard Worker dimension < std::size(kByteStringsUnlocalized) - 1) {
302*6777b538SAndroid Build Coastguard Worker unit_amount /= kKilo;
303*6777b538SAndroid Build Coastguard Worker dimension++;
304*6777b538SAndroid Build Coastguard Worker }
305*6777b538SAndroid Build Coastguard Worker
306*6777b538SAndroid Build Coastguard Worker char buf[64];
307*6777b538SAndroid Build Coastguard Worker if (bytes != 0 && dimension > 0 && unit_amount < 100) {
308*6777b538SAndroid Build Coastguard Worker base::snprintf(buf, std::size(buf), "%.1lf%s", unit_amount,
309*6777b538SAndroid Build Coastguard Worker kByteStringsUnlocalized[dimension]);
310*6777b538SAndroid Build Coastguard Worker } else {
311*6777b538SAndroid Build Coastguard Worker base::snprintf(buf, std::size(buf), "%.0lf%s", unit_amount,
312*6777b538SAndroid Build Coastguard Worker kByteStringsUnlocalized[dimension]);
313*6777b538SAndroid Build Coastguard Worker }
314*6777b538SAndroid Build Coastguard Worker
315*6777b538SAndroid Build Coastguard Worker return ASCIIToUTF16(buf);
316*6777b538SAndroid Build Coastguard Worker }
317*6777b538SAndroid Build Coastguard Worker
ReplaceFirstSubstringAfterOffset(std::u16string * str,size_t start_offset,StringPiece16 find_this,StringPiece16 replace_with)318*6777b538SAndroid Build Coastguard Worker void ReplaceFirstSubstringAfterOffset(std::u16string* str,
319*6777b538SAndroid Build Coastguard Worker size_t start_offset,
320*6777b538SAndroid Build Coastguard Worker StringPiece16 find_this,
321*6777b538SAndroid Build Coastguard Worker StringPiece16 replace_with) {
322*6777b538SAndroid Build Coastguard Worker internal::DoReplaceMatchesAfterOffset(
323*6777b538SAndroid Build Coastguard Worker str, start_offset, internal::MakeSubstringMatcher(find_this),
324*6777b538SAndroid Build Coastguard Worker replace_with, internal::ReplaceType::REPLACE_FIRST);
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker
ReplaceFirstSubstringAfterOffset(std::string * str,size_t start_offset,StringPiece find_this,StringPiece replace_with)327*6777b538SAndroid Build Coastguard Worker void ReplaceFirstSubstringAfterOffset(std::string* str,
328*6777b538SAndroid Build Coastguard Worker size_t start_offset,
329*6777b538SAndroid Build Coastguard Worker StringPiece find_this,
330*6777b538SAndroid Build Coastguard Worker StringPiece replace_with) {
331*6777b538SAndroid Build Coastguard Worker internal::DoReplaceMatchesAfterOffset(
332*6777b538SAndroid Build Coastguard Worker str, start_offset, internal::MakeSubstringMatcher(find_this),
333*6777b538SAndroid Build Coastguard Worker replace_with, internal::ReplaceType::REPLACE_FIRST);
334*6777b538SAndroid Build Coastguard Worker }
335*6777b538SAndroid Build Coastguard Worker
ReplaceSubstringsAfterOffset(std::u16string * str,size_t start_offset,StringPiece16 find_this,StringPiece16 replace_with)336*6777b538SAndroid Build Coastguard Worker void ReplaceSubstringsAfterOffset(std::u16string* str,
337*6777b538SAndroid Build Coastguard Worker size_t start_offset,
338*6777b538SAndroid Build Coastguard Worker StringPiece16 find_this,
339*6777b538SAndroid Build Coastguard Worker StringPiece16 replace_with) {
340*6777b538SAndroid Build Coastguard Worker internal::DoReplaceMatchesAfterOffset(
341*6777b538SAndroid Build Coastguard Worker str, start_offset, internal::MakeSubstringMatcher(find_this),
342*6777b538SAndroid Build Coastguard Worker replace_with, internal::ReplaceType::REPLACE_ALL);
343*6777b538SAndroid Build Coastguard Worker }
344*6777b538SAndroid Build Coastguard Worker
ReplaceSubstringsAfterOffset(std::string * str,size_t start_offset,StringPiece find_this,StringPiece replace_with)345*6777b538SAndroid Build Coastguard Worker void ReplaceSubstringsAfterOffset(std::string* str,
346*6777b538SAndroid Build Coastguard Worker size_t start_offset,
347*6777b538SAndroid Build Coastguard Worker StringPiece find_this,
348*6777b538SAndroid Build Coastguard Worker StringPiece replace_with) {
349*6777b538SAndroid Build Coastguard Worker internal::DoReplaceMatchesAfterOffset(
350*6777b538SAndroid Build Coastguard Worker str, start_offset, internal::MakeSubstringMatcher(find_this),
351*6777b538SAndroid Build Coastguard Worker replace_with, internal::ReplaceType::REPLACE_ALL);
352*6777b538SAndroid Build Coastguard Worker }
353*6777b538SAndroid Build Coastguard Worker
WriteInto(std::string * str,size_t length_with_null)354*6777b538SAndroid Build Coastguard Worker char* WriteInto(std::string* str, size_t length_with_null) {
355*6777b538SAndroid Build Coastguard Worker return internal::WriteIntoT(str, length_with_null);
356*6777b538SAndroid Build Coastguard Worker }
357*6777b538SAndroid Build Coastguard Worker
WriteInto(std::u16string * str,size_t length_with_null)358*6777b538SAndroid Build Coastguard Worker char16_t* WriteInto(std::u16string* str, size_t length_with_null) {
359*6777b538SAndroid Build Coastguard Worker return internal::WriteIntoT(str, length_with_null);
360*6777b538SAndroid Build Coastguard Worker }
361*6777b538SAndroid Build Coastguard Worker
JoinString(span<const std::string> parts,StringPiece separator)362*6777b538SAndroid Build Coastguard Worker std::string JoinString(span<const std::string> parts, StringPiece separator) {
363*6777b538SAndroid Build Coastguard Worker return internal::JoinStringT(parts, separator);
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker
JoinString(span<const std::u16string> parts,StringPiece16 separator)366*6777b538SAndroid Build Coastguard Worker std::u16string JoinString(span<const std::u16string> parts,
367*6777b538SAndroid Build Coastguard Worker StringPiece16 separator) {
368*6777b538SAndroid Build Coastguard Worker return internal::JoinStringT(parts, separator);
369*6777b538SAndroid Build Coastguard Worker }
370*6777b538SAndroid Build Coastguard Worker
JoinString(span<const StringPiece> parts,StringPiece separator)371*6777b538SAndroid Build Coastguard Worker std::string JoinString(span<const StringPiece> parts, StringPiece separator) {
372*6777b538SAndroid Build Coastguard Worker return internal::JoinStringT(parts, separator);
373*6777b538SAndroid Build Coastguard Worker }
374*6777b538SAndroid Build Coastguard Worker
JoinString(span<const StringPiece16> parts,StringPiece16 separator)375*6777b538SAndroid Build Coastguard Worker std::u16string JoinString(span<const StringPiece16> parts,
376*6777b538SAndroid Build Coastguard Worker StringPiece16 separator) {
377*6777b538SAndroid Build Coastguard Worker return internal::JoinStringT(parts, separator);
378*6777b538SAndroid Build Coastguard Worker }
379*6777b538SAndroid Build Coastguard Worker
JoinString(std::initializer_list<StringPiece> parts,StringPiece separator)380*6777b538SAndroid Build Coastguard Worker std::string JoinString(std::initializer_list<StringPiece> parts,
381*6777b538SAndroid Build Coastguard Worker StringPiece separator) {
382*6777b538SAndroid Build Coastguard Worker return internal::JoinStringT(parts, separator);
383*6777b538SAndroid Build Coastguard Worker }
384*6777b538SAndroid Build Coastguard Worker
JoinString(std::initializer_list<StringPiece16> parts,StringPiece16 separator)385*6777b538SAndroid Build Coastguard Worker std::u16string JoinString(std::initializer_list<StringPiece16> parts,
386*6777b538SAndroid Build Coastguard Worker StringPiece16 separator) {
387*6777b538SAndroid Build Coastguard Worker return internal::JoinStringT(parts, separator);
388*6777b538SAndroid Build Coastguard Worker }
389*6777b538SAndroid Build Coastguard Worker
ReplaceStringPlaceholders(StringPiece16 format_string,const std::vector<std::u16string> & subst,std::vector<size_t> * offsets)390*6777b538SAndroid Build Coastguard Worker std::u16string ReplaceStringPlaceholders(
391*6777b538SAndroid Build Coastguard Worker StringPiece16 format_string,
392*6777b538SAndroid Build Coastguard Worker const std::vector<std::u16string>& subst,
393*6777b538SAndroid Build Coastguard Worker std::vector<size_t>* offsets) {
394*6777b538SAndroid Build Coastguard Worker std::optional<std::u16string> replacement =
395*6777b538SAndroid Build Coastguard Worker internal::DoReplaceStringPlaceholders(
396*6777b538SAndroid Build Coastguard Worker format_string, subst,
397*6777b538SAndroid Build Coastguard Worker /*placeholder_prefix*/ u'$',
398*6777b538SAndroid Build Coastguard Worker /*should_escape_multiple_placeholder_prefixes*/ true,
399*6777b538SAndroid Build Coastguard Worker /*is_strict_mode*/ false, offsets);
400*6777b538SAndroid Build Coastguard Worker
401*6777b538SAndroid Build Coastguard Worker DCHECK(replacement);
402*6777b538SAndroid Build Coastguard Worker return replacement.value();
403*6777b538SAndroid Build Coastguard Worker }
404*6777b538SAndroid Build Coastguard Worker
ReplaceStringPlaceholders(StringPiece format_string,const std::vector<std::string> & subst,std::vector<size_t> * offsets)405*6777b538SAndroid Build Coastguard Worker std::string ReplaceStringPlaceholders(StringPiece format_string,
406*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& subst,
407*6777b538SAndroid Build Coastguard Worker std::vector<size_t>* offsets) {
408*6777b538SAndroid Build Coastguard Worker std::optional<std::string> replacement =
409*6777b538SAndroid Build Coastguard Worker internal::DoReplaceStringPlaceholders(
410*6777b538SAndroid Build Coastguard Worker format_string, subst,
411*6777b538SAndroid Build Coastguard Worker /*placeholder_prefix*/ '$',
412*6777b538SAndroid Build Coastguard Worker /*should_escape_multiple_placeholder_prefixes*/ true,
413*6777b538SAndroid Build Coastguard Worker /*is_strict_mode*/ false, offsets);
414*6777b538SAndroid Build Coastguard Worker
415*6777b538SAndroid Build Coastguard Worker DCHECK(replacement);
416*6777b538SAndroid Build Coastguard Worker return replacement.value();
417*6777b538SAndroid Build Coastguard Worker }
418*6777b538SAndroid Build Coastguard Worker
ReplaceStringPlaceholders(const std::u16string & format_string,const std::u16string & a,size_t * offset)419*6777b538SAndroid Build Coastguard Worker std::u16string ReplaceStringPlaceholders(const std::u16string& format_string,
420*6777b538SAndroid Build Coastguard Worker const std::u16string& a,
421*6777b538SAndroid Build Coastguard Worker size_t* offset) {
422*6777b538SAndroid Build Coastguard Worker std::vector<size_t> offsets;
423*6777b538SAndroid Build Coastguard Worker std::u16string result =
424*6777b538SAndroid Build Coastguard Worker ReplaceStringPlaceholders(format_string, {a}, &offsets);
425*6777b538SAndroid Build Coastguard Worker
426*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(1U, offsets.size());
427*6777b538SAndroid Build Coastguard Worker if (offset)
428*6777b538SAndroid Build Coastguard Worker *offset = offsets[0];
429*6777b538SAndroid Build Coastguard Worker return result;
430*6777b538SAndroid Build Coastguard Worker }
431*6777b538SAndroid Build Coastguard Worker
strlcpy(char * dst,const char * src,size_t dst_size)432*6777b538SAndroid Build Coastguard Worker size_t strlcpy(char* dst, const char* src, size_t dst_size) {
433*6777b538SAndroid Build Coastguard Worker return internal::lcpyT(dst, src, dst_size);
434*6777b538SAndroid Build Coastguard Worker }
435*6777b538SAndroid Build Coastguard Worker
u16cstrlcpy(char16_t * dst,const char16_t * src,size_t dst_size)436*6777b538SAndroid Build Coastguard Worker size_t u16cstrlcpy(char16_t* dst, const char16_t* src, size_t dst_size) {
437*6777b538SAndroid Build Coastguard Worker return internal::lcpyT(dst, src, dst_size);
438*6777b538SAndroid Build Coastguard Worker }
439*6777b538SAndroid Build Coastguard Worker
wcslcpy(wchar_t * dst,const wchar_t * src,size_t dst_size)440*6777b538SAndroid Build Coastguard Worker size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) {
441*6777b538SAndroid Build Coastguard Worker return internal::lcpyT(dst, src, dst_size);
442*6777b538SAndroid Build Coastguard Worker }
443*6777b538SAndroid Build Coastguard Worker
444*6777b538SAndroid Build Coastguard Worker } // namespace base
445