Commit 665969c8 authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[base] Re-organize Windows only string utils

This change moves the Windows only code in base/strings/{strcat,
string_util, string_split}.h to their own _win.h headers, and introduces
appropriate _internal.h headers to be able to share the templated code
between Windows and cross-platform code.

This change is purely organizational, and there is no functionality
added or removed.

Bug: 911896
Change-Id: I3d2eae1e665cfcf48e727d6d71ca1975c441a370
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2228622
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775075}
parent 6ab9e145
......@@ -544,6 +544,7 @@ jumbo_component("base") {
"strings/safe_sprintf.h",
"strings/strcat.cc",
"strings/strcat.h",
"strings/strcat_internal.h",
"strings/string16.cc",
"strings/string16.h",
"strings/string_number_conversions.cc",
......@@ -553,10 +554,12 @@ jumbo_component("base") {
"strings/string_piece_forward.h",
"strings/string_split.cc",
"strings/string_split.h",
"strings/string_split_internal.h",
"strings/string_tokenizer.h",
"strings/string_util.cc",
"strings/string_util.h",
"strings/string_util_constants.cc",
"strings/string_util_internal.h",
"strings/stringize_macros.h",
"strings/stringprintf.cc",
"strings/stringprintf.h",
......@@ -930,6 +933,11 @@ jumbo_component("base") {
"profiler/suspendable_thread_delegate_win.cc",
"profiler/suspendable_thread_delegate_win.h",
"scoped_clear_last_error_win.cc",
"strings/strcat_win.cc",
"strings/strcat_win.h",
"strings/string_split_win.cc",
"strings/string_split_win.h",
"strings/string_util_win.cc",
"strings/string_util_win.h",
"strings/sys_string_conversions_win.cc",
"sync_socket_win.cc",
......
......@@ -6,102 +6,40 @@
#include <string>
namespace base {
namespace {
// Reserves an additional amount of capacity in the given string, growing by at
// least 2x if necessary. Used by StrAppendT().
//
// The "at least 2x" growing rule duplicates the exponential growth of
// std::string. The problem is that most implementations of reserve() will grow
// exactly to the requested amount instead of exponentially growing like would
// happen when appending normally. If we didn't do this, an append after the
// call to StrAppend() would definitely cause a reallocation, and loops with
// StrAppend() calls would have O(n^2) complexity to execute. Instead, we want
// StrAppend() to have the same semantics as std::string::append().
template <typename String>
void ReserveAdditionalIfNeeded(String* str,
typename String::size_type additional) {
const size_t required = str->size() + additional;
// Check whether we need to reserve additional capacity at all.
if (required <= str->capacity())
return;
str->reserve(std::max(required, str->capacity() * 2));
}
template <typename DestString, typename InputString>
void StrAppendT(DestString* dest, span<const InputString> pieces) {
size_t additional_size = 0;
for (const auto& cur : pieces)
additional_size += cur.size();
ReserveAdditionalIfNeeded(dest, additional_size);
for (const auto& cur : pieces)
dest->append(cur.data(), cur.size());
}
template <typename StringT>
auto StrCatT(span<const StringT> pieces) {
std::basic_string<typename StringT::value_type, typename StringT::traits_type>
result;
StrAppendT(&result, pieces);
return result;
}
#include "base/strings/strcat_internal.h"
} // namespace
namespace base {
std::string StrCat(span<const StringPiece> pieces) {
return StrCatT(pieces);
return internal::StrCatT(pieces);
}
string16 StrCat(span<const StringPiece16> pieces) {
return StrCatT(pieces);
return internal::StrCatT(pieces);
}
std::string StrCat(span<const std::string> pieces) {
return StrCatT(pieces);
return internal::StrCatT(pieces);
}
string16 StrCat(span<const string16> pieces) {
return StrCatT(pieces);
}
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
std::wstring StrCat(span<const WStringPiece> pieces) {
return StrCatT(pieces);
}
std::wstring StrCat(span<const std::wstring> pieces) {
return StrCatT(pieces);
return internal::StrCatT(pieces);
}
#endif
void StrAppend(std::string* dest, span<const StringPiece> pieces) {
StrAppendT(dest, pieces);
internal::StrAppendT(dest, pieces);
}
void StrAppend(string16* dest, span<const StringPiece16> pieces) {
StrAppendT(dest, pieces);
internal::StrAppendT(dest, pieces);
}
void StrAppend(std::string* dest, span<const std::string> pieces) {
StrAppendT(dest, pieces);
internal::StrAppendT(dest, pieces);
}
void StrAppend(string16* dest, span<const string16> pieces) {
StrAppendT(dest, pieces);
}
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
void StrAppend(std::wstring* dest, span<const WStringPiece> pieces) {
StrAppendT(dest, pieces);
}
void StrAppend(std::wstring* dest, span<const std::wstring> pieces) {
StrAppendT(dest, pieces);
internal::StrAppendT(dest, pieces);
}
#endif
} // namespace base
......@@ -76,17 +76,6 @@ inline string16 StrCat(std::initializer_list<StringPiece16> pieces) {
return StrCat(make_span(pieces));
}
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT std::wstring StrCat(span<const WStringPiece> pieces)
WARN_UNUSED_RESULT;
BASE_EXPORT std::wstring StrCat(span<const std::wstring> pieces)
WARN_UNUSED_RESULT;
inline std::wstring StrCat(std::initializer_list<WStringPiece> pieces) {
return StrCat(make_span(pieces));
}
#endif // defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
// StrAppend -------------------------------------------------------------------
//
// Appends a sequence of strings to a destination. Prefer:
......@@ -111,16 +100,10 @@ inline void StrAppend(string16* dest,
StrAppend(dest, make_span(pieces));
}
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT void StrAppend(std::wstring* dest, span<const WStringPiece> pieces);
BASE_EXPORT void StrAppend(std::wstring* dest, span<const std::wstring> pieces);
inline void StrAppend(std::wstring* dest,
std::initializer_list<WStringPiece> pieces) {
StrAppend(dest, make_span(pieces));
}
#endif // defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
} // namespace base
#if defined(OS_WIN)
#include "base/strings/strcat_win.h"
#endif
#endif // BASE_STRINGS_STRCAT_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_STRINGS_STRCAT_INTERNAL_H_
#define BASE_STRINGS_STRCAT_INTERNAL_H_
#include <string>
#include "base/containers/span.h"
namespace base {
namespace internal {
// Reserves an additional amount of capacity in the given string, growing by at
// least 2x if necessary. Used by StrAppendT().
//
// The "at least 2x" growing rule duplicates the exponential growth of
// std::string. The problem is that most implementations of reserve() will grow
// exactly to the requested amount instead of exponentially growing like would
// happen when appending normally. If we didn't do this, an append after the
// call to StrAppend() would definitely cause a reallocation, and loops with
// StrAppend() calls would have O(n^2) complexity to execute. Instead, we want
// StrAppend() to have the same semantics as std::string::append().
template <typename String>
void ReserveAdditionalIfNeeded(String* str,
typename String::size_type additional) {
const size_t required = str->size() + additional;
// Check whether we need to reserve additional capacity at all.
if (required <= str->capacity())
return;
str->reserve(std::max(required, str->capacity() * 2));
}
template <typename DestString, typename InputString>
void StrAppendT(DestString* dest, span<const InputString> pieces) {
size_t additional_size = 0;
for (const auto& cur : pieces)
additional_size += cur.size();
ReserveAdditionalIfNeeded(dest, additional_size);
for (const auto& cur : pieces)
dest->append(cur.data(), cur.size());
}
template <typename StringT>
auto StrCatT(span<const StringT> pieces) {
std::basic_string<typename StringT::value_type, typename StringT::traits_type>
result;
StrAppendT(&result, pieces);
return result;
}
} // namespace internal
} // namespace base
#endif // BASE_STRINGS_STRCAT_INTERNAL_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/strcat_win.h"
#include <string>
#include "base/containers/span.h"
#include "base/strings/strcat_internal.h"
#include "base/strings/string_piece.h"
namespace base {
#if defined(BASE_STRING16_IS_STD_U16STRING)
std::wstring StrCat(span<const WStringPiece> pieces) {
return internal::StrCatT(pieces);
}
std::wstring StrCat(span<const std::wstring> pieces) {
return internal::StrCatT(pieces);
}
void StrAppend(std::wstring* dest, span<const WStringPiece> pieces) {
internal::StrAppendT(dest, pieces);
}
void StrAppend(std::wstring* dest, span<const std::wstring> pieces) {
internal::StrAppendT(dest, pieces);
}
#endif
} // namespace base
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_STRINGS_STRCAT_WIN_H_
#define BASE_STRINGS_STRCAT_WIN_H_
#include <initializer_list>
#include <string>
#include "base/base_export.h"
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/strings/string_piece.h"
namespace base {
// The following section contains overloads of the cross-platform APIs for
// std::wstring and base::WStringPiece. These are only enabled if std::wstring
// and base::string16 are distinct types, as otherwise this would result in an
// ODR violation.
// TODO(crbug.com/911896): Remove those guards once base::string16 is
// std::u16string.
#if defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT void StrAppend(std::wstring* dest, span<const WStringPiece> pieces);
BASE_EXPORT void StrAppend(std::wstring* dest, span<const std::wstring> pieces);
inline void StrAppend(std::wstring* dest,
std::initializer_list<WStringPiece> pieces) {
StrAppend(dest, make_span(pieces));
}
BASE_EXPORT std::wstring StrCat(span<const WStringPiece> pieces)
WARN_UNUSED_RESULT;
BASE_EXPORT std::wstring StrCat(span<const std::wstring> pieces)
WARN_UNUSED_RESULT;
inline std::wstring StrCat(std::initializer_list<WStringPiece> pieces) {
return StrCat(make_span(pieces));
}
#endif // defined(BASE_STRING16_IS_STD_U16STRING)
} // namespace base
#endif // BASE_STRINGS_STRCAT_WIN_H_
......@@ -7,6 +7,7 @@
#include <stddef.h>
#include "base/logging.h"
#include "base/strings/string_split_internal.h"
#include "base/strings/string_util.h"
#include "base/third_party/icu/icu_utf.h"
......@@ -14,56 +15,6 @@ namespace base {
namespace {
// Returns either the ASCII or UTF-16 whitespace.
template<typename Str> BasicStringPiece<Str> WhitespaceForType();
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
template <>
WStringPiece WhitespaceForType<std::wstring>() {
return kWhitespaceWide;
}
#endif
template<> StringPiece16 WhitespaceForType<string16>() {
return kWhitespaceUTF16;
}
template<> StringPiece WhitespaceForType<std::string>() {
return kWhitespaceASCII;
}
// General string splitter template. Can take 8- or 16-bit input, can produce
// the corresponding string or StringPiece output.
template <typename OutputStringType, typename Str>
static std::vector<OutputStringType> SplitStringT(
BasicStringPiece<Str> str,
BasicStringPiece<Str> delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
std::vector<OutputStringType> result;
if (str.empty())
return result;
size_t start = 0;
while (start != Str::npos) {
size_t end = str.find_first_of(delimiter, start);
BasicStringPiece<Str> piece;
if (end == Str::npos) {
piece = str.substr(start);
start = Str::npos;
} else {
piece = str.substr(start, end - start);
start = end + 1;
}
if (whitespace == TRIM_WHITESPACE)
piece = TrimString(piece, WhitespaceForType<Str>(), TRIM_ALL);
if (result_type == SPLIT_WANT_ALL || !piece.empty())
result.emplace_back(piece);
}
return result;
}
bool AppendStringKeyValue(StringPiece input,
char delimiter,
StringPairs* result) {
......@@ -94,67 +45,38 @@ bool AppendStringKeyValue(StringPiece input,
return true;
}
template <typename OutputStringType, typename Str>
std::vector<OutputStringType> SplitStringUsingSubstrT(
BasicStringPiece<Str> input,
BasicStringPiece<Str> delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
using Piece = BasicStringPiece<Str>;
using size_type = typename Piece::size_type;
std::vector<OutputStringType> result;
if (delimiter.size() == 0) {
result.emplace_back(input);
return result;
}
for (size_type begin_index = 0, end_index = 0; end_index != Piece::npos;
begin_index = end_index + delimiter.size()) {
end_index = input.find(delimiter, begin_index);
Piece term = end_index == Piece::npos
? input.substr(begin_index)
: input.substr(begin_index, end_index - begin_index);
if (whitespace == TRIM_WHITESPACE)
term = TrimString(term, WhitespaceForType<Str>(), TRIM_ALL);
if (result_type == SPLIT_WANT_ALL || !term.empty())
result.emplace_back(term);
}
return result;
}
} // namespace
std::vector<std::string> SplitString(StringPiece input,
StringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringT<std::string>(input, separators, whitespace, result_type);
return internal::SplitStringT<std::string>(input, separators, whitespace,
result_type);
}
std::vector<string16> SplitString(StringPiece16 input,
StringPiece16 separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringT<string16>(input, separators, whitespace, result_type);
return internal::SplitStringT<string16>(input, separators, whitespace,
result_type);
}
std::vector<StringPiece> SplitStringPiece(StringPiece input,
StringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringT<StringPiece>(input, separators, whitespace, result_type);
return internal::SplitStringT<StringPiece>(input, separators, whitespace,
result_type);
}
std::vector<StringPiece16> SplitStringPiece(StringPiece16 input,
StringPiece16 separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringT<StringPiece16>(input, separators, whitespace,
result_type);
return internal::SplitStringT<StringPiece16>(input, separators, whitespace,
result_type);
}
bool SplitStringIntoKeyValuePairs(StringPiece input,
......@@ -192,16 +114,16 @@ std::vector<string16> SplitStringUsingSubstr(StringPiece16 input,
StringPiece16 delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringUsingSubstrT<string16>(input, delimiter, whitespace,
result_type);
return internal::SplitStringUsingSubstrT<string16>(input, delimiter,
whitespace, result_type);
}
std::vector<std::string> SplitStringUsingSubstr(StringPiece input,
StringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringUsingSubstrT<std::string>(input, delimiter, whitespace,
result_type);
return internal::SplitStringUsingSubstrT<std::string>(
input, delimiter, whitespace, result_type);
}
std::vector<StringPiece16> SplitStringPieceUsingSubstr(
......@@ -210,8 +132,8 @@ std::vector<StringPiece16> SplitStringPieceUsingSubstr(
WhitespaceHandling whitespace,
SplitResult result_type) {
std::vector<StringPiece16> result;
return SplitStringUsingSubstrT<StringPiece16>(input, delimiter, whitespace,
result_type);
return internal::SplitStringUsingSubstrT<StringPiece16>(
input, delimiter, whitespace, result_type);
}
std::vector<StringPiece> SplitStringPieceUsingSubstr(
......@@ -219,41 +141,8 @@ std::vector<StringPiece> SplitStringPieceUsingSubstr(
StringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringUsingSubstrT<StringPiece>(input, delimiter, whitespace,
result_type);
}
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
std::vector<std::wstring> SplitString(WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringT<std::wstring>(input, separators, whitespace, result_type);
}
std::vector<WStringPiece> SplitStringPiece(WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringT<WStringPiece>(input, separators, whitespace, result_type);
}
std::vector<std::wstring> SplitStringUsingSubstr(WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringUsingSubstrT<std::wstring>(input, delimiter, whitespace,
result_type);
}
std::vector<WStringPiece> SplitStringPieceUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return SplitStringUsingSubstrT<WStringPiece>(input, delimiter, whitespace,
result_type);
return internal::SplitStringUsingSubstrT<StringPiece>(
input, delimiter, whitespace, result_type);
}
#endif
} // namespace base
......@@ -138,32 +138,10 @@ BASE_EXPORT std::vector<StringPiece> SplitStringPieceUsingSubstr(
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT std::vector<std::wstring> SplitString(WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type)
WARN_UNUSED_RESULT;
BASE_EXPORT std::vector<WStringPiece> SplitStringPiece(
WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
BASE_EXPORT std::vector<std::wstring> SplitStringUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
} // namespace base
BASE_EXPORT std::vector<WStringPiece> SplitStringPieceUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
#if defined(OS_WIN)
#include "base/strings/string_split_win.h"
#endif
} // namespace base
#endif // BASE_STRINGS_STRING_SPLIT_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_STRINGS_STRING_SPLIT_INTERNAL_H_
#define BASE_STRINGS_STRING_SPLIT_INTERNAL_H_
#include <vector>
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
namespace base {
namespace internal {
// Returns either the ASCII or UTF-16 whitespace.
template <typename Str>
BasicStringPiece<Str> WhitespaceForType();
template <>
inline StringPiece16 WhitespaceForType<string16>() {
return kWhitespaceUTF16;
}
template <>
inline StringPiece WhitespaceForType<std::string>() {
return kWhitespaceASCII;
}
// General string splitter template. Can take 8- or 16-bit input, can produce
// the corresponding string or StringPiece output.
template <typename OutputStringType, typename Str>
static std::vector<OutputStringType> SplitStringT(
BasicStringPiece<Str> str,
BasicStringPiece<Str> delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
std::vector<OutputStringType> result;
if (str.empty())
return result;
size_t start = 0;
while (start != Str::npos) {
size_t end = str.find_first_of(delimiter, start);
BasicStringPiece<Str> piece;
if (end == Str::npos) {
piece = str.substr(start);
start = Str::npos;
} else {
piece = str.substr(start, end - start);
start = end + 1;
}
if (whitespace == TRIM_WHITESPACE)
piece = TrimString(piece, WhitespaceForType<Str>(), TRIM_ALL);
if (result_type == SPLIT_WANT_ALL || !piece.empty())
result.emplace_back(piece);
}
return result;
}
template <typename OutputStringType, typename Str>
std::vector<OutputStringType> SplitStringUsingSubstrT(
BasicStringPiece<Str> input,
BasicStringPiece<Str> delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
using Piece = BasicStringPiece<Str>;
using size_type = typename Piece::size_type;
std::vector<OutputStringType> result;
if (delimiter.size() == 0) {
result.emplace_back(input);
return result;
}
for (size_type begin_index = 0, end_index = 0; end_index != Piece::npos;
begin_index = end_index + delimiter.size()) {
end_index = input.find(delimiter, begin_index);
Piece term = end_index == Piece::npos
? input.substr(begin_index)
: input.substr(begin_index, end_index - begin_index);
if (whitespace == TRIM_WHITESPACE)
term = TrimString(term, WhitespaceForType<Str>(), TRIM_ALL);
if (result_type == SPLIT_WANT_ALL || !term.empty())
result.emplace_back(term);
}
return result;
}
} // namespace internal
} // namespace base
#endif // BASE_STRINGS_STRING_SPLIT_INTERNAL_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/string_split_win.h"
#include <string>
#include <vector>
#include "base/strings/string_piece.h"
#include "base/strings/string_split_internal.h"
namespace base {
#if defined(BASE_STRING16_IS_STD_U16STRING)
namespace internal {
template <>
inline WStringPiece WhitespaceForType<std::wstring>() {
return kWhitespaceWide;
}
} // namespace internal
std::vector<std::wstring> SplitString(WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return internal::SplitStringT<std::wstring>(input, separators, whitespace,
result_type);
}
std::vector<WStringPiece> SplitStringPiece(WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) {
return internal::SplitStringT<WStringPiece>(input, separators, whitespace,
result_type);
}
std::vector<std::wstring> SplitStringUsingSubstr(WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return internal::SplitStringUsingSubstrT<std::wstring>(
input, delimiter, whitespace, result_type);
}
std::vector<WStringPiece> SplitStringPieceUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) {
return internal::SplitStringUsingSubstrT<WStringPiece>(
input, delimiter, whitespace, result_type);
}
#endif
} // namespace base
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_STRINGS_STRING_SPLIT_WIN_H_
#define BASE_STRINGS_STRING_SPLIT_WIN_H_
#include <string>
#include <vector>
#include "base/base_export.h"
#include "base/compiler_specific.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
namespace base {
// The following section contains overloads of the cross-platform APIs for
// std::wstring and base::WStringPiece. These are only enabled if std::wstring
// and base::string16 are distinct types, as otherwise this would result in an
// ODR violation.
// TODO(crbug.com/911896): Remove those guards once base::string16 is
// std::u16string.
#if defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT std::vector<std::wstring> SplitString(WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type)
WARN_UNUSED_RESULT;
BASE_EXPORT std::vector<WStringPiece> SplitStringPiece(
WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
BASE_EXPORT std::vector<std::wstring> SplitStringUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
BASE_EXPORT std::vector<WStringPiece> SplitStringPieceUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
SplitResult result_type) WARN_UNUSED_RESULT;
#endif
} // namespace base
#endif // BASE_STRINGS_STRING_SPLIT_WIN_H_
This diff is collapsed.
......@@ -226,69 +226,6 @@ BASE_EXPORT void TruncateUTF8ToByteSize(const std::string& input,
const size_t byte_size,
std::string* output);
#if defined(WCHAR_T_IS_UTF16)
// Utility functions to access the underlying string buffer as a wide char
// pointer.
//
// Note: These functions violate strict aliasing when char16 and wchar_t are
// unrelated types. We thus pass -fno-strict-aliasing to the compiler on
// non-Windows platforms [1], and rely on it being off in Clang's CL mode [2].
//
// [1] https://crrev.com/b9a0976622/build/config/compiler/BUILD.gn#244
// [2]
// https://github.com/llvm/llvm-project/blob/1e28a66/clang/lib/Driver/ToolChains/Clang.cpp#L3949
inline wchar_t* as_writable_wcstr(char16* str) {
return reinterpret_cast<wchar_t*>(str);
}
inline wchar_t* as_writable_wcstr(string16& str) {
return reinterpret_cast<wchar_t*>(data(str));
}
inline const wchar_t* as_wcstr(const char16* str) {
return reinterpret_cast<const wchar_t*>(str);
}
inline const wchar_t* as_wcstr(StringPiece16 str) {
return reinterpret_cast<const wchar_t*>(str.data());
}
// Utility functions to access the underlying string buffer as a char16 pointer.
inline char16* as_writable_u16cstr(wchar_t* str) {
return reinterpret_cast<char16*>(str);
}
inline char16* as_writable_u16cstr(std::wstring& str) {
return reinterpret_cast<char16*>(data(str));
}
inline const char16* as_u16cstr(const wchar_t* str) {
return reinterpret_cast<const char16*>(str);
}
inline const char16* as_u16cstr(WStringPiece str) {
return reinterpret_cast<const char16*>(str.data());
}
// Utility functions to convert between base::WStringPiece and
// base::StringPiece16.
inline WStringPiece AsWStringPiece(StringPiece16 str) {
return WStringPiece(as_wcstr(str.data()), str.size());
}
inline StringPiece16 AsStringPiece16(WStringPiece str) {
return StringPiece16(as_u16cstr(str.data()), str.size());
}
inline std::wstring AsWString(StringPiece16 str) {
return std::wstring(as_wcstr(str.data()), str.size());
}
inline string16 AsString16(WStringPiece str) {
return string16(as_u16cstr(str.data()), str.size());
}
#endif // defined(WCHAR_T_IS_UTF16)
// Trims any whitespace from either end of the input string.
//
// The StringPiece versions return a substring referencing the input buffer.
......@@ -347,7 +284,7 @@ BASE_EXPORT bool IsStringUTF8AllowingNoncharacters(StringPiece str);
BASE_EXPORT bool IsStringASCII(StringPiece str);
BASE_EXPORT bool IsStringASCII(StringPiece16 str);
#if defined(BASE_STRING16_IS_STD_U16STRING) || defined(WCHAR_T_IS_UTF32)
#if defined(WCHAR_T_IS_UTF32)
BASE_EXPORT bool IsStringASCII(WStringPiece str);
#endif
......@@ -536,89 +473,6 @@ BASE_EXPORT string16 ReplaceStringPlaceholders(const string16& format_string,
const string16& a,
size_t* offset);
// The following section contains overloads of the previously defined APIs for
// std::wstring and base::WStringPiece. In order to discourage using
// std::wstring in cross-platform code, these overloads are only enabled on
// Windows, and only if std::wstring is a different type than base::string16.
#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT std::wstring ToLowerASCII(WStringPiece str);
BASE_EXPORT std::wstring ToUpperASCII(WStringPiece str);
BASE_EXPORT int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
BASE_EXPORT bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
BASE_EXPORT bool RemoveChars(WStringPiece input,
WStringPiece remove_chars,
std::wstring* output);
BASE_EXPORT bool ReplaceChars(WStringPiece input,
WStringPiece replace_chars,
WStringPiece replace_with,
std::wstring* output);
BASE_EXPORT bool TrimString(WStringPiece input,
WStringPiece trim_chars,
std::string* output);
BASE_EXPORT WStringPiece TrimString(WStringPiece input,
WStringPiece trim_chars,
TrimPositions positions);
BASE_EXPORT TrimPositions TrimWhitespace(WStringPiece input,
TrimPositions positions,
std::wstring* output);
BASE_EXPORT WStringPiece TrimWhitespace(WStringPiece input,
TrimPositions positions);
BASE_EXPORT std::wstring CollapseWhitespace(
WStringPiece text,
bool trim_sequences_with_line_breaks);
BASE_EXPORT bool ContainsOnlyChars(WStringPiece input, WStringPiece characters);
BASE_EXPORT bool LowerCaseEqualsASCII(WStringPiece str,
StringPiece lowecase_ascii);
BASE_EXPORT bool EqualsASCII(StringPiece16 str, StringPiece ascii);
BASE_EXPORT bool StartsWith(WStringPiece str,
WStringPiece search_for,
CompareCase case_sensitivity);
BASE_EXPORT bool EndsWith(WStringPiece str,
WStringPiece search_for,
CompareCase case_sensitivity);
BASE_EXPORT void ReplaceFirstSubstringAfterOffset(std::wstring* str,
size_t start_offset,
WStringPiece find_this,
WStringPiece replace_with);
BASE_EXPORT void ReplaceSubstringsAfterOffset(std::wstring* str,
size_t start_offset,
WStringPiece find_this,
WStringPiece replace_with);
BASE_EXPORT wchar_t* WriteInto(std::wstring* str, size_t length_with_null);
BASE_EXPORT std::wstring JoinString(span<const std::wstring> parts,
WStringPiece separator);
BASE_EXPORT std::wstring JoinString(span<const WStringPiece> parts,
WStringPiece separator);
BASE_EXPORT std::wstring JoinString(std::initializer_list<WStringPiece> parts,
WStringPiece separator);
BASE_EXPORT std::wstring ReplaceStringPlaceholders(
WStringPiece format_string,
const std::vector<string16>& subst,
std::vector<size_t>* offsets);
#endif
} // namespace base
#if defined(OS_WIN)
......
This diff is collapsed.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/string_util_win.h"
#include "base/strings/string_util_internal.h"
namespace base {
#if defined(BASE_STRING16_IS_STD_U16STRING)
bool IsStringASCII(WStringPiece str) {
return internal::DoIsStringASCII(str.data(), str.length());
}
std::wstring ToLowerASCII(WStringPiece str) {
return internal::ToLowerASCIIImpl(str);
}
std::wstring ToUpperASCII(WStringPiece str) {
return internal::ToUpperASCIIImpl(str);
}
int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b) {
return internal::CompareCaseInsensitiveASCIIT(a, b);
}
bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) {
return a.size() == b.size() &&
internal::CompareCaseInsensitiveASCIIT(a, b) == 0;
}
bool RemoveChars(WStringPiece input,
WStringPiece remove_chars,
std::wstring* output) {
return internal::ReplaceCharsT(input, remove_chars, WStringPiece(), output);
}
bool ReplaceChars(WStringPiece input,
WStringPiece replace_chars,
WStringPiece replace_with,
std::wstring* output) {
return internal::ReplaceCharsT(input, replace_chars, replace_with, output);
}
bool TrimString(WStringPiece input,
WStringPiece trim_chars,
std::wstring* output) {
return internal::TrimStringT(input, trim_chars, TRIM_ALL, output) !=
TRIM_NONE;
}
WStringPiece TrimString(WStringPiece input,
WStringPiece trim_chars,
TrimPositions positions) {
return internal::TrimStringPieceT(input, trim_chars, positions);
}
TrimPositions TrimWhitespace(WStringPiece input,
TrimPositions positions,
std::wstring* output) {
return internal::TrimStringT(input, WStringPiece(kWhitespaceWide), positions,
output);
}
WStringPiece TrimWhitespace(WStringPiece input, TrimPositions positions) {
return internal::TrimStringPieceT(input, WStringPiece(kWhitespaceWide),
positions);
}
std::wstring CollapseWhitespace(WStringPiece text,
bool trim_sequences_with_line_breaks) {
return internal::CollapseWhitespaceT(text, trim_sequences_with_line_breaks);
}
bool ContainsOnlyChars(WStringPiece input, WStringPiece characters) {
return input.find_first_not_of(characters) == StringPiece::npos;
}
bool LowerCaseEqualsASCII(WStringPiece str, StringPiece lowercase_ascii) {
return internal::DoLowerCaseEqualsASCII(str, lowercase_ascii);
}
bool EqualsASCII(WStringPiece str, StringPiece ascii) {
return std::equal(ascii.begin(), ascii.end(), str.begin(), str.end());
}
bool StartsWith(WStringPiece str,
WStringPiece search_for,
CompareCase case_sensitivity) {
return internal::StartsWithT(str, search_for, case_sensitivity);
}
bool EndsWith(WStringPiece str,
WStringPiece search_for,
CompareCase case_sensitivity) {
return internal::EndsWithT(str, search_for, case_sensitivity);
}
void ReplaceFirstSubstringAfterOffset(std::wstring* str,
size_t start_offset,
WStringPiece find_this,
WStringPiece replace_with) {
internal::DoReplaceMatchesAfterOffset(
str, start_offset, internal::SubstringMatcher<std::wstring>{find_this},
replace_with, internal::ReplaceType::REPLACE_FIRST);
}
void ReplaceSubstringsAfterOffset(std::wstring* str,
size_t start_offset,
WStringPiece find_this,
WStringPiece replace_with) {
internal::DoReplaceMatchesAfterOffset(
str, start_offset, internal::SubstringMatcher<std::wstring>{find_this},
replace_with, internal::ReplaceType::REPLACE_ALL);
}
wchar_t* WriteInto(std::wstring* str, size_t length_with_null) {
return internal::WriteIntoT(str, length_with_null);
}
std::wstring JoinString(span<const std::wstring> parts,
WStringPiece separator) {
return internal::JoinStringT(parts, separator);
}
std::wstring JoinString(span<const WStringPiece> parts,
WStringPiece separator) {
return internal::JoinStringT(parts, separator);
}
std::wstring JoinString(std::initializer_list<WStringPiece> parts,
WStringPiece separator) {
return internal::JoinStringT(parts, separator);
}
std::wstring ReplaceStringPlaceholders(WStringPiece format_string,
const std::vector<std::wstring>& subst,
std::vector<size_t>* offsets) {
return internal::DoReplaceStringPlaceholders(format_string, subst, offsets);
}
#endif
} // namespace base
......@@ -11,7 +11,14 @@
#include <string.h>
#include <wchar.h>
#include <string>
#include <vector>
#include "base/containers/span.h"
#include "base/logging.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
namespace base {
......@@ -39,6 +46,154 @@ inline int vswprintf(wchar_t* buffer, size_t size,
return length;
}
// Utility functions to access the underlying string buffer as a wide char
// pointer.
//
// Note: These functions violate strict aliasing when char16 and wchar_t are
// unrelated types. We thus pass -fno-strict-aliasing to the compiler on
// non-Windows platforms [1], and rely on it being off in Clang's CL mode [2].
//
// [1] https://crrev.com/b9a0976622/build/config/compiler/BUILD.gn#244
// [2]
// https://github.com/llvm/llvm-project/blob/1e28a66/clang/lib/Driver/ToolChains/Clang.cpp#L3949
inline wchar_t* as_writable_wcstr(char16* str) {
return reinterpret_cast<wchar_t*>(str);
}
inline wchar_t* as_writable_wcstr(string16& str) {
return reinterpret_cast<wchar_t*>(data(str));
}
inline const wchar_t* as_wcstr(const char16* str) {
return reinterpret_cast<const wchar_t*>(str);
}
inline const wchar_t* as_wcstr(StringPiece16 str) {
return reinterpret_cast<const wchar_t*>(str.data());
}
// Utility functions to access the underlying string buffer as a char16 pointer.
inline char16* as_writable_u16cstr(wchar_t* str) {
return reinterpret_cast<char16*>(str);
}
inline char16* as_writable_u16cstr(std::wstring& str) {
return reinterpret_cast<char16*>(data(str));
}
inline const char16* as_u16cstr(const wchar_t* str) {
return reinterpret_cast<const char16*>(str);
}
inline const char16* as_u16cstr(WStringPiece str) {
return reinterpret_cast<const char16*>(str.data());
}
// Utility functions to convert between base::WStringPiece and
// base::StringPiece16.
inline WStringPiece AsWStringPiece(StringPiece16 str) {
return WStringPiece(as_wcstr(str.data()), str.size());
}
inline StringPiece16 AsStringPiece16(WStringPiece str) {
return StringPiece16(as_u16cstr(str.data()), str.size());
}
inline std::wstring AsWString(StringPiece16 str) {
return std::wstring(as_wcstr(str.data()), str.size());
}
inline string16 AsString16(WStringPiece str) {
return string16(as_u16cstr(str.data()), str.size());
}
// The following section contains overloads of the cross-platform APIs for
// std::wstring and base::WStringPiece. These are only enabled if std::wstring
// and base::string16 are distinct types, as otherwise this would result in an
// ODR violation.
// TODO(crbug.com/911896): Remove those guards once base::string16 is
// std::u16string.
#if defined(BASE_STRING16_IS_STD_U16STRING)
BASE_EXPORT bool IsStringASCII(WStringPiece str);
BASE_EXPORT std::wstring ToLowerASCII(WStringPiece str);
BASE_EXPORT std::wstring ToUpperASCII(WStringPiece str);
BASE_EXPORT int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
BASE_EXPORT bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
BASE_EXPORT bool RemoveChars(WStringPiece input,
WStringPiece remove_chars,
std::wstring* output);
BASE_EXPORT bool ReplaceChars(WStringPiece input,
WStringPiece replace_chars,
WStringPiece replace_with,
std::wstring* output);
BASE_EXPORT bool TrimString(WStringPiece input,
WStringPiece trim_chars,
std::string* output);
BASE_EXPORT WStringPiece TrimString(WStringPiece input,
WStringPiece trim_chars,
TrimPositions positions);
BASE_EXPORT TrimPositions TrimWhitespace(WStringPiece input,
TrimPositions positions,
std::wstring* output);
BASE_EXPORT WStringPiece TrimWhitespace(WStringPiece input,
TrimPositions positions);
BASE_EXPORT std::wstring CollapseWhitespace(
WStringPiece text,
bool trim_sequences_with_line_breaks);
BASE_EXPORT bool ContainsOnlyChars(WStringPiece input, WStringPiece characters);
BASE_EXPORT bool LowerCaseEqualsASCII(WStringPiece str,
StringPiece lowecase_ascii);
BASE_EXPORT bool EqualsASCII(StringPiece16 str, StringPiece ascii);
BASE_EXPORT bool StartsWith(WStringPiece str,
WStringPiece search_for,
CompareCase case_sensitivity);
BASE_EXPORT bool EndsWith(WStringPiece str,
WStringPiece search_for,
CompareCase case_sensitivity);
BASE_EXPORT void ReplaceFirstSubstringAfterOffset(std::wstring* str,
size_t start_offset,
WStringPiece find_this,
WStringPiece replace_with);
BASE_EXPORT void ReplaceSubstringsAfterOffset(std::wstring* str,
size_t start_offset,
WStringPiece find_this,
WStringPiece replace_with);
BASE_EXPORT wchar_t* WriteInto(std::wstring* str, size_t length_with_null);
BASE_EXPORT std::wstring JoinString(span<const std::wstring> parts,
WStringPiece separator);
BASE_EXPORT std::wstring JoinString(span<const WStringPiece> parts,
WStringPiece separator);
BASE_EXPORT std::wstring JoinString(std::initializer_list<WStringPiece> parts,
WStringPiece separator);
BASE_EXPORT std::wstring ReplaceStringPlaceholders(
WStringPiece format_string,
const std::vector<string16>& subst,
std::vector<size_t>* offsets);
#endif
} // namespace base
#endif // BASE_STRINGS_STRING_UTIL_WIN_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment