Skip to content

Commit c23f6c2

Browse files
darinadlercalvaris
authored andcommitted
Add constructor for String that takes span<char8_t>
https://bugs.webkit.org/show_bug.cgi?id=301739 rdar://163764627 Reviewed by Sam Weinig. * Source/WTF/wtf/Logger.h: (WTF::LogArgument::toString): Added overload that takes std::span<const char8_t>. * Source/WTF/wtf/PrintStream.cpp: (WTF::printInternal): Added overload that takes std::span<const char8_t>. * Source/WTF/wtf/PrintStream.h: Ditto. * Source/WTF/wtf/text/StringImpl.cpp: (WTF::StringImpl::create): Added overload that takes std::span<const char8_t>. * Source/WTF/wtf/text/StringImpl.h: Ditto. * Source/WTF/wtf/text/WTFString.cpp: (WTF::String::String): Added overload that takes std::span<const char8_t>. (WTF::fromUTF8Impl): Deleted. (WTF::String::fromUTF8): Changed to call the constructor. (WTF::String::fromUTF8ReplacingInvalidSequences): Moved code here from the fromUTF8Impl function. (WTF::String::fromUTF8WithLatin1Fallback): Call the constructor rather than the fromUTF8 function. * Source/WTF/wtf/text/WTFString.h: Added constructor that takes std::span<const char8_t>. Canonical link: https://commits.webkit.org/302417@main Signed-off-by: Xabier Rodriguez Calvar <calvaris@igalia.com>
1 parent 891fa6d commit c23f6c2

7 files changed

Lines changed: 54 additions & 22 deletions

File tree

Source/WTF/wtf/Logger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct LogArgument {
5757
template<typename U = T> static std::enable_if_t<std::is_same_v<typename std::remove_reference_t<U>, StringBuilder*>, String> toString(StringBuilder* argument) { return argument->toString(); }
5858
template<typename U = T> static std::enable_if_t<std::is_same_v<U, const char*>, String> toString(const char* argument) { return String::fromLatin1(argument); }
5959
template<typename U = T> static std::enable_if_t<std::is_same_v<U, ASCIILiteral>, String> toString(ASCIILiteral argument) { return argument; }
60+
template<typename U = T> static std::enable_if_t<std::is_same_v<U, std::span<const char8_t>>, String> toString(std::span<const char8_t> argument) { return argument; }
6061
#ifdef __OBJC__
6162
template<typename U = T> static std::enable_if_t<std::is_base_of_v<NSError, std::remove_pointer_t<U>>, String> toString(NSError *argument) { return String(argument.localizedDescription); }
6263
template<typename U = T> static std::enable_if_t<std::is_base_of_v<NSObject, std::remove_pointer_t<U>>, String> toString(NSObject *argument) { return String(argument.description); }

Source/WTF/wtf/PrintStream.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ void printInternal(PrintStream& out, const StringImpl* string)
119119
printExpectedCStringHelper(out, "StringImpl*", string->tryGetUTF8());
120120
}
121121

122+
void printInternal(PrintStream& stream, std::span<const char8_t> codeUnits)
123+
{
124+
printInternal(stream, byteCast<char>(codeUnits));
125+
}
126+
122127
void printInternal(PrintStream& out, bool value)
123128
{
124129
out.print(boolForPrinting(value));

Source/WTF/wtf/PrintStream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const CString&);
113113
WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const String&);
114114
WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const AtomString&);
115115
WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const StringImpl*);
116+
WTF_EXPORT_PRIVATE void printInternal(PrintStream&, std::span<const char8_t>);
116117
inline void printInternal(PrintStream& out, const AtomStringImpl* value) { printInternal(out, std::bit_cast<const StringImpl*>(value)); }
117118
inline void printInternal(PrintStream& out, const UniquedStringImpl* value) { printInternal(out, std::bit_cast<const StringImpl*>(value)); }
118119
inline void printInternal(PrintStream& out, const UniquedStringImpl& value) { printInternal(out, &value); }

Source/WTF/wtf/text/StringImpl.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,28 @@ Ref<StringImpl> StringImpl::create(std::span<const Latin1Character> characters)
316316
return createInternal(characters);
317317
}
318318

319+
RefPtr<StringImpl> StringImpl::create(std::span<const char8_t> codeUnits)
320+
{
321+
RELEASE_ASSERT(codeUnits.size() <= String::MaxLength);
322+
323+
if (!codeUnits.data())
324+
return nullptr;
325+
if (codeUnits.empty())
326+
return empty();
327+
328+
if (charactersAreAllASCII(codeUnits))
329+
return create(byteCast<Latin1Character>(codeUnits));
330+
331+
Vector<char16_t, 1024> buffer(codeUnits.size());
332+
333+
auto result = Unicode::convert(codeUnits, buffer.mutableSpan());
334+
if (result.code != Unicode::ConversionResultCode::Success)
335+
return nullptr;
336+
337+
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.buffer.size() <= codeUnits.size());
338+
return create(result.buffer);
339+
}
340+
319341
Ref<StringImpl> StringImpl::createStaticStringImpl(std::span<const Latin1Character> characters)
320342
{
321343
if (characters.empty())

Source/WTF/wtf/text/StringImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ class StringImpl : private StringImplShape {
261261
ALWAYS_INLINE static Ref<StringImpl> create(std::span<const char> characters) { return create(byteCast<Latin1Character>(characters)); }
262262
WTF_EXPORT_PRIVATE static Ref<StringImpl> create8BitIfPossible(std::span<const char16_t>);
263263

264+
// Construct a string with UTF-8 data, null if it contains invalid UTF-8 sequences.
265+
WTF_EXPORT_PRIVATE static RefPtr<StringImpl> create(std::span<const char8_t>);
266+
264267
// Not using create() naming to encourage developers to call create(ASCIILiteral) when they have a string literal.
265268
ALWAYS_INLINE static Ref<StringImpl> createFromCString(const char* characters) { return create(WTF::span8(characters)); }
266269

Source/WTF/wtf/text/WTFString.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ String::String(std::span<const Latin1Character> characters)
5151
{
5252
}
5353

54+
// Construct a string with UTF-8 data.
55+
String::String(std::span<const char8_t> characters)
56+
: m_impl(StringImpl::create(characters))
57+
{
58+
}
59+
5460
// Construct a string with Latin-1 data.
5561
String::String(std::span<const char> characters)
5662
: m_impl(characters.data() ? RefPtr { StringImpl::create(byteCast<Latin1Character>(characters)) } : nullptr)
@@ -464,9 +470,16 @@ void String::convertTo16Bit()
464470
*this = WTFMove(convertedString);
465471
}
466472

467-
template<bool replaceInvalidSequences>
468-
String fromUTF8Impl(std::span<const char8_t> string)
473+
String String::fromUTF8(std::span<const char8_t> codeUnits)
474+
{
475+
return codeUnits;
476+
}
477+
478+
String String::fromUTF8ReplacingInvalidSequences(std::span<const char8_t> string)
469479
{
480+
if (!string.data())
481+
return { };
482+
470483
RELEASE_ASSERT(string.size() <= String::MaxLength);
471484

472485
if (string.empty())
@@ -475,35 +488,19 @@ String fromUTF8Impl(std::span<const char8_t> string)
475488
if (charactersAreAllASCII(string))
476489
return StringImpl::create(spanReinterpretCast<const Latin1Character>(string));
477490

478-
Vector<UChar, 1024> buffer(string.size());
479-
480-
auto result = replaceInvalidSequences
481-
? Unicode::convertReplacingInvalidSequences(string, buffer.mutableSpan())
482-
: Unicode::convert(string, buffer.mutableSpan());
491+
Vector<char16_t, 1024> buffer(string.size());
492+
493+
auto result = Unicode::convertReplacingInvalidSequences(string, buffer.mutableSpan());
483494
if (result.code != Unicode::ConversionResultCode::Success)
484495
return { };
485496

486497
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.buffer.size() <= string.size());
487498
return StringImpl::create(result.buffer);
488499
}
489500

490-
String String::fromUTF8(std::span<const char8_t> string)
491-
{
492-
if (!string.data())
493-
return { };
494-
return fromUTF8Impl<false>(string);
495-
}
496-
497-
String String::fromUTF8ReplacingInvalidSequences(std::span<const char8_t> characters)
498-
{
499-
if (!characters.data())
500-
return { };
501-
return fromUTF8Impl<true>(characters);
502-
}
503-
504501
String String::fromUTF8WithLatin1Fallback(std::span<const char8_t> string)
505502
{
506-
String utf8 = fromUTF8(string);
503+
String utf8 { string };
507504
if (!utf8) {
508505
// Do this assertion before chopping the size_t down to unsigned.
509506
RELEASE_ASSERT(string.size() <= String::MaxLength);

Source/WTF/wtf/text/WTFString.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ class String final {
6464
WTF_EXPORT_PRIVATE String(std::span<const char> characters);
6565
ALWAYS_INLINE static String fromLatin1(const char* characters) { return String { characters }; }
6666

67+
// Construct a string with UTF-8 data, null string if it contains invalid UTF-8 sequences.
68+
WTF_EXPORT_PRIVATE String(std::span<const char8_t>);
69+
6770
// Construct a string referencing an existing StringImpl.
6871
String(StringImpl&);
6972
String(StringImpl*);

0 commit comments

Comments
 (0)