Improve assertions in StringParsingBuffer
[WebKit-https.git] / Source / WTF / wtf / text / StringParsingBuffer.h
1 /*
2  * Copyright (C) 2020 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include <wtf/Forward.h>
29 #include <wtf/text/LChar.h>
30 #include <wtf/text/StringCommon.h>
31
32 namespace WTF {
33
34 template<typename T>
35 class StringParsingBuffer final {
36     WTF_MAKE_FAST_ALLOCATED;
37 public:
38     using CharacterType = T;
39
40     constexpr StringParsingBuffer() = default;
41
42     constexpr StringParsingBuffer(const CharacterType* characters, unsigned length)
43         : m_position { characters }
44         , m_end { characters + length }
45     {
46         ASSERT(characters || !length);
47     }
48
49     constexpr StringParsingBuffer(const CharacterType* characters, const CharacterType* end)
50         : m_position { characters }
51         , m_end { end }
52     {
53         ASSERT(characters <= end);
54         ASSERT(!characters == !end);
55         ASSERT(end - characters <= std::numeric_limits<unsigned>::max());
56     }
57
58     constexpr auto position() const { return m_position; }
59     constexpr auto end() const { return m_end; }
60
61     constexpr bool hasCharactersRemaining() const { return m_position < m_end; }
62     constexpr bool atEnd() const { return m_position == m_end; }
63
64     constexpr unsigned lengthRemaining() const { return m_end - m_position; }
65
66     StringView stringViewOfCharactersRemaining() { return { m_position, lengthRemaining() }; }
67
68     CharacterType operator[](unsigned i)
69     {
70         ASSERT(i < lengthRemaining());
71         return m_position[i];
72     }
73
74     constexpr CharacterType operator*() const
75     {
76         ASSERT(hasCharactersRemaining());
77         return *m_position;
78     }
79
80     constexpr void advance()
81     {
82         ASSERT(hasCharactersRemaining());
83         ++m_position;
84     }
85
86     constexpr void advanceBy(unsigned places)
87     {
88         ASSERT(places <= lengthRemaining());
89         m_position += places;
90     }
91
92     constexpr StringParsingBuffer& operator++()
93     {
94         advance();
95         return *this;
96     }
97
98     constexpr StringParsingBuffer operator++(int)
99     {
100         auto result = *this;
101         ++*this;
102         return result;
103     }
104
105     constexpr StringParsingBuffer& operator+=(int places)
106     {
107         advanceBy(places);
108         return *this;
109     }
110
111 private:
112     const CharacterType* m_position { nullptr };
113     const CharacterType* m_end { nullptr };
114 };
115
116 template<typename StringType, typename Function> decltype(auto) readCharactersForParsing(StringType&& string, Function&& functor)
117 {
118     if (string.is8Bit())
119         return functor(StringParsingBuffer { string.characters8(), string.length() });
120     return functor(StringParsingBuffer { string.characters16(), string.length() });
121 }
122
123 } // namespace WTF
124
125 using WTF::StringParsingBuffer;
126 using WTF::readCharactersForParsing;