Diff
Modified: trunk/Source/WTF/ChangeLog (263528 => 263529)
--- trunk/Source/WTF/ChangeLog 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Source/WTF/ChangeLog 2020-06-25 21:13:18 UTC (rev 263529)
@@ -1,3 +1,44 @@
+2020-06-25 Sam Weinig <[email protected]>
+
+ Add a new templated string type to help write more idiomatic parsing code
+ https://bugs.webkit.org/show_bug.cgi?id=213588
+
+ Reviewed by Darin Adler.
+
+ Introduce StringParsingBuffer<CharType>, a new class in the String class family
+ designed to be used by parsing code. It's designed to be used with the helper
+ function, readCharactersForParsing, and for the user to write the parsing code
+ in a way that will work for both latin1 and UTF-16 inputs. Most usage will likely
+ follow something like the following form
+
+ {
+ ...
+ auto parsedResult = readCharactersForParsing(stringishObjectToParse, [](auto parsingBuffer) {
+ while (parsingBuffer.hasCharactersRemaining()) {
+ if (*parsingBuffer == foo) {
+ ...
+ }
+ }
+
+ ...
+
+ return parsedResult
+ });
+ ...
+ }
+
+ API tests added.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/CMakeLists.txt:
+ Add StringParsingBuffer.h
+
+ * wtf/Forward.h:
+ Forward declare StringParsingBuffer.
+
+ * wtf/text/StringParsingBuffer.h:
+ Added.
+
2020-06-25 Tadeu Zagallo <[email protected]>
WTF::callOnMainThread should not require the main runloop to be initialized
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (263528 => 263529)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2020-06-25 21:13:18 UTC (rev 263529)
@@ -455,6 +455,7 @@
7C137942222326D500D7A824 /* ieee.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ieee.h; sourceTree = "<group>"; };
7C137943222326D500D7A824 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
7C3A45D023CFA883007DE3A6 /* PlatformHave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformHave.h; sourceTree = "<group>"; };
+ 7C3B06E824A116E600FD26C7 /* StringParsingBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StringParsingBuffer.h; sourceTree = "<group>"; };
7C3F72391D78811900674E26 /* Brigand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Brigand.h; sourceTree = "<group>"; };
7C42307123CE2D8A006E54D0 /* PlatformEnable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformEnable.h; sourceTree = "<group>"; };
7C42307223CE2D8A006E54D0 /* PlatformCPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformCPU.h; sourceTree = "<group>"; };
@@ -1401,6 +1402,7 @@
A8A47328151A825B004123FF /* StringImpl.cpp */,
A8A47329151A825B004123FF /* StringImpl.h */,
A8A4732A151A825B004123FF /* StringOperators.h */,
+ 7C3B06E824A116E600FD26C7 /* StringParsingBuffer.h */,
CD00360D21501F7800F4ED4C /* StringToIntegerConversion.h */,
93F1993D19D7958D00C2390B /* StringView.cpp */,
1A6EB1DF187D0BD30030126F /* StringView.h */,
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (263528 => 263529)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2020-06-25 21:13:18 UTC (rev 263529)
@@ -339,6 +339,7 @@
text/StringHasher.h
text/StringImpl.h
text/StringOperators.h
+ text/StringParsingBuffer.h
text/StringToIntegerConversion.h
text/StringView.h
text/SymbolImpl.h
Modified: trunk/Source/WTF/wtf/Forward.h (263528 => 263529)
--- trunk/Source/WTF/wtf/Forward.h 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Source/WTF/wtf/Forward.h 2020-06-25 21:13:18 UTC (rev 263529)
@@ -71,6 +71,7 @@
template<typename T, typename = DumbPtrTraits<T>> class Ref;
template<typename T, typename = DumbPtrTraits<T>> class RefPtr;
template<typename> class StringBuffer;
+template<typename> class StringParsingBuffer;
template<typename, typename = void> class StringTypeAdapter;
template<typename> class UniqueRef;
template<typename...> class Variant;
@@ -122,6 +123,7 @@
using WTF::StringBuffer;
using WTF::StringBuilder;
using WTF::StringImpl;
+using WTF::StringParsingBuffer;
using WTF::StringView;
using WTF::TextPosition;
using WTF::TextStream;
Added: trunk/Source/WTF/wtf/text/StringParsingBuffer.h (0 => 263529)
--- trunk/Source/WTF/wtf/text/StringParsingBuffer.h (rev 0)
+++ trunk/Source/WTF/wtf/text/StringParsingBuffer.h 2020-06-25 21:13:18 UTC (rev 263529)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Forward.h>
+#include <wtf/text/LChar.h>
+#include <wtf/text/StringCommon.h>
+
+namespace WTF {
+
+template<typename T>
+class StringParsingBuffer final {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ using CharacterType = T;
+
+ constexpr StringParsingBuffer() = default;
+
+ constexpr StringParsingBuffer(const CharacterType* characters, unsigned length)
+ : m_position { characters }
+ , m_end { characters + length }
+ {
+ ASSERT(characters || !length);
+ }
+
+ constexpr StringParsingBuffer(const CharacterType* characters, const CharacterType* end)
+ : m_position { characters }
+ , m_end { end }
+ {
+ ASSERT(m_end >= m_position);
+ ASSERT(!characters == !end);
+ }
+
+ constexpr auto position() const { return m_position; }
+ constexpr auto end() const { return m_end; }
+
+ constexpr bool hasCharactersRemaining() const { return m_position < m_end; }
+ constexpr bool atEnd() const { return m_position == m_end; }
+
+ constexpr unsigned lengthRemaining() const { return m_end - m_position; }
+
+ StringView stringViewOfCharactersRemaining() { return { m_position, lengthRemaining() }; }
+
+ CharacterType operator[](unsigned i)
+ {
+ ASSERT(m_position + i < m_end);
+ return m_position[i];
+ }
+
+ constexpr CharacterType operator*() const
+ {
+ ASSERT(m_position < m_end);
+ return *m_position;
+ }
+
+ constexpr void advance()
+ {
+ ASSERT(m_position < m_end);
+ ++m_position;
+ }
+
+ constexpr void advanceBy(unsigned places)
+ {
+ ASSERT(m_position <= m_end);
+ ASSERT(m_position + places <= m_end);
+ m_position += places;
+ }
+
+ constexpr StringParsingBuffer& operator++()
+ {
+ advance();
+ return *this;
+ }
+
+ constexpr StringParsingBuffer operator++(int)
+ {
+ auto result = *this;
+ ++*this;
+ return result;
+ }
+
+ constexpr StringParsingBuffer& operator+=(int places)
+ {
+ advanceBy(places);
+ return *this;
+ }
+
+private:
+ const CharacterType* m_position { nullptr };
+ const CharacterType* m_end { nullptr };
+};
+
+template<typename StringType, typename Function> decltype(auto) readCharactersForParsing(StringType&& string, Function&& functor)
+{
+ if (string.is8Bit())
+ return functor(StringParsingBuffer { string.characters8(), string.length() });
+ return functor(StringParsingBuffer { string.characters16(), string.length() });
+}
+
+} // namespace WTF
+
+using WTF::StringParsingBuffer;
+using WTF::readCharactersForParsing;
Modified: trunk/Tools/ChangeLog (263528 => 263529)
--- trunk/Tools/ChangeLog 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Tools/ChangeLog 2020-06-25 21:13:18 UTC (rev 263529)
@@ -1,3 +1,16 @@
+2020-06-25 Sam Weinig <[email protected]>
+
+ Add a new templated string type to help write more idiomatic parsing code
+ https://bugs.webkit.org/show_bug.cgi?id=213588
+
+ Reviewed by Darin Adler.
+
+ * TestWebKitAPI/CMakeLists.txt:
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WTF/StringParsingBuffer.cpp: Added.
+ (TestWebKitAPI::TEST):
+ Added new tests for new class.
+
2020-06-25 Wenson Hsieh <[email protected]>
Text manipulation should exclude text rendered using icon-only fonts
Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (263528 => 263529)
--- trunk/Tools/TestWebKitAPI/CMakeLists.txt 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt 2020-06-25 21:13:18 UTC (rev 263529)
@@ -89,6 +89,7 @@
Tests/WTF/StringHasher.cpp
Tests/WTF/StringImpl.cpp
Tests/WTF/StringOperators.cpp
+ Tests/WTF/StringParsingBuffer.cpp
Tests/WTF/StringView.cpp
Tests/WTF/SynchronizedFixedQueue.cpp
Tests/WTF/TextBreakIterator.cpp
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (263528 => 263529)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2020-06-25 20:57:59 UTC (rev 263528)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2020-06-25 21:13:18 UTC (rev 263529)
@@ -743,6 +743,7 @@
7CCE7F2E1A411B1000447C4C /* WKBrowsingContextGroupTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC3C4C7D14587AA60025FB62 /* WKBrowsingContextGroupTest.mm */; };
7CCE7F2F1A411B1000447C4C /* WKBrowsingContextLoadDelegateTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC3C4C7014575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm */; };
7CD4C26E1E2C0E6E00929470 /* StringConcatenate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD4C26C1E2C0E6E00929470 /* StringConcatenate.cpp */; };
+ 7CD70C4F24A436EE00E61040 /* StringParsingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD70C4E24A436EE00E61040 /* StringParsingBuffer.cpp */; };
7CEB62AB223609DE0069CBB0 /* IteratorRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEB62A92236086C0069CBB0 /* IteratorRange.cpp */; };
7CEFA9661AC0B9E200B910FD /* _WKUserContentExtensionStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7CEFA9641AC0B9E200B910FD /* _WKUserContentExtensionStore.mm */; };
7CFBCAE51743238F00B2BFCF /* WillLoad_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFBCAE31743238E00B2BFCF /* WillLoad_Bundle.cpp */; };
@@ -2276,6 +2277,7 @@
7CCE7EA31A4115CB00447C4C /* TestWebKitAPILibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TestWebKitAPILibrary.xcconfig; sourceTree = "<group>"; };
7CD0D5AA1D5534DE000CC9E1 /* Variant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Variant.cpp; sourceTree = "<group>"; };
7CD4C26C1E2C0E6E00929470 /* StringConcatenate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringConcatenate.cpp; sourceTree = "<group>"; };
+ 7CD70C4E24A436EE00E61040 /* StringParsingBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StringParsingBuffer.cpp; sourceTree = "<group>"; };
7CEB62A92236086C0069CBB0 /* IteratorRange.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorRange.cpp; sourceTree = "<group>"; };
7CEFA9641AC0B9E200B910FD /* _WKUserContentExtensionStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKUserContentExtensionStore.mm; sourceTree = "<group>"; };
7CFBCADD1743234F00B2BFCF /* WillLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillLoad.cpp; sourceTree = "<group>"; };
@@ -4087,6 +4089,7 @@
93ABA80816DDAB91002DB2FA /* StringHasher.cpp */,
26F1B44315CA434F00D1E4BF /* StringImpl.cpp */,
C01363C713C3997300EF3964 /* StringOperators.cpp */,
+ 7CD70C4E24A436EE00E61040 /* StringParsingBuffer.cpp */,
7C74D42D188228F300E5ED57 /* StringView.cpp */,
5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */,
9329AA281DE3F81E003ABD07 /* TextBreakIterator.cpp */,
@@ -4799,6 +4802,7 @@
7C83DF361D0A590C00FEBCF3 /* StringHasher.cpp in Sources */,
7C83DF371D0A590C00FEBCF3 /* StringImpl.cpp in Sources */,
7C83DF381D0A590C00FEBCF3 /* StringOperators.cpp in Sources */,
+ 7CD70C4F24A436EE00E61040 /* StringParsingBuffer.cpp in Sources */,
7C83DF3A1D0A590C00FEBCF3 /* StringView.cpp in Sources */,
5597F8361D9596C80066BC21 /* SynchronizedFixedQueue.cpp in Sources */,
7C83DF401D0A590C00FEBCF3 /* TestsController.cpp in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/StringParsingBuffer.cpp (0 => 263529)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/StringParsingBuffer.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/StringParsingBuffer.cpp 2020-06-25 21:13:18 UTC (rev 263529)
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "WTFStringUtilities.h"
+
+#include <wtf/text/StringParsingBuffer.h>
+#include <wtf/text/StringView.h>
+
+namespace TestWebKitAPI {
+
+TEST(WTF, StringParsingBufferEmpty)
+{
+ StringParsingBuffer<LChar> parsingBuffer;
+
+ EXPECT_TRUE(parsingBuffer.atEnd());
+ EXPECT_FALSE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.position(), nullptr);
+ EXPECT_EQ(parsingBuffer.end(), nullptr);
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 0u);
+
+}
+
+TEST(WTF, StringParsingBufferInitial)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.position(), string.characters8());
+ EXPECT_EQ(parsingBuffer.end(), string.characters8() + string.length());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 3u);
+ EXPECT_EQ(*parsingBuffer, 'a');
+}
+
+TEST(WTF, StringParsingBufferAdvance)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ parsingBuffer.advance();
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 2u);
+ EXPECT_EQ(*parsingBuffer, 'b');
+}
+
+TEST(WTF, StringParsingBufferAdvanceBy)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ parsingBuffer.advanceBy(2);
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 1u);
+ EXPECT_EQ(*parsingBuffer, 'c');
+}
+
+TEST(WTF, StringParsingBufferPreIncrement)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ auto preIncrementedParsingBuffer = ++parsingBuffer;
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 2u);
+ EXPECT_EQ(*parsingBuffer, 'b');
+ EXPECT_FALSE(preIncrementedParsingBuffer.atEnd());
+ EXPECT_TRUE(preIncrementedParsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(preIncrementedParsingBuffer.lengthRemaining(), 2u);
+ EXPECT_EQ(*preIncrementedParsingBuffer, 'b');
+}
+
+TEST(WTF, StringParsingBufferPostIncrement)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ auto postIncrementedParsingBuffer = parsingBuffer++;
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 2u);
+ EXPECT_EQ(*parsingBuffer, 'b');
+ EXPECT_FALSE(postIncrementedParsingBuffer.atEnd());
+ EXPECT_TRUE(postIncrementedParsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(postIncrementedParsingBuffer.lengthRemaining(), 3u);
+ EXPECT_EQ(*postIncrementedParsingBuffer, 'a');
+}
+
+TEST(WTF, StringParsingBufferPlusEquals)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ parsingBuffer += 2;
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 1u);
+ EXPECT_EQ(*parsingBuffer, 'c');
+}
+
+TEST(WTF, StringParsingBufferEnd)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ ++parsingBuffer;
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(*parsingBuffer, 'b');
+
+ ++parsingBuffer;
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(*parsingBuffer, 'c');
+
+ ++parsingBuffer;
+ EXPECT_TRUE(parsingBuffer.atEnd());
+ EXPECT_FALSE(parsingBuffer.hasCharactersRemaining());
+}
+
+TEST(WTF, StringParsingBufferSubscript)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ ++parsingBuffer;
+ EXPECT_EQ(parsingBuffer[0], 'b');
+ EXPECT_EQ(parsingBuffer[1], 'c');
+}
+
+TEST(WTF, StringParsingBufferStringView)
+{
+ StringView string { "abc" };
+ StringParsingBuffer<LChar> parsingBuffer { string.characters8(), string.length() };
+
+ ++parsingBuffer;
+ auto viewRemaining = parsingBuffer.stringViewOfCharactersRemaining();
+ EXPECT_EQ(viewRemaining.length(), 2u);
+ EXPECT_EQ(viewRemaining[0], 'b');
+ EXPECT_EQ(viewRemaining[1], 'c');
+}
+
+TEST(WTF, StringParsingBufferReadCharactersForParsing)
+{
+ auto latin1 = StringView { "abc" };
+ auto result1 = WTF::readCharactersForParsing(latin1, [](auto parsingBuffer) {
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 3u);
+ EXPECT_EQ(*parsingBuffer, 'a');
+
+ ++parsingBuffer;
+ return parsingBuffer.lengthRemaining();
+ });
+ EXPECT_EQ(result1, 2u);
+
+ auto utf16 = utf16String(u"😍😉🙃");
+ auto result2 = WTF::readCharactersForParsing(utf16, [](auto parsingBuffer) {
+ EXPECT_FALSE(parsingBuffer.atEnd());
+ EXPECT_TRUE(parsingBuffer.hasCharactersRemaining());
+ EXPECT_EQ(parsingBuffer.lengthRemaining(), 6u);
+ EXPECT_EQ(*parsingBuffer, 0xD83D);
+
+ ++parsingBuffer;
+ return parsingBuffer.lengthRemaining();
+ });
+ EXPECT_EQ(result2, 5u);
+}
+
+}
+