1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Copyright (C) 2016 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 are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#pragma once
31
32#include <wtf/text/StringView.h>
33
34namespace WebCore {
35
36constexpr LChar kEndOfFileMarker = 0;
37
38class CSSTokenizerInputStream {
39 WTF_MAKE_NONCOPYABLE(CSSTokenizerInputStream);
40 WTF_MAKE_FAST_ALLOCATED;
41public:
42 explicit CSSTokenizerInputStream(const String& input);
43
44 // Gets the char in the stream replacing NUL characters with a unicode
45 // replacement character. Will return (NUL) kEndOfFileMarker when at the
46 // end of the stream.
47 UChar nextInputChar() const
48 {
49 if (m_offset >= m_stringLength)
50 return '\0';
51 UChar result = (*m_string)[m_offset];
52 return result ? result : 0xFFFD;
53 }
54
55 // Gets the char at lookaheadOffset from the current stream position. Will
56 // return NUL (kEndOfFileMarker) if the stream position is at the end.
57 // NOTE: This may *also* return NUL if there's one in the input! Never
58 // compare the return value to '\0'.
59 UChar peekWithoutReplacement(unsigned lookaheadOffset) const
60 {
61 if ((m_offset + lookaheadOffset) >= m_stringLength)
62 return '\0';
63 return (*m_string)[m_offset + lookaheadOffset];
64 }
65
66 void advance(unsigned offset = 1) { m_offset += offset; }
67 void pushBack(UChar cc)
68 {
69 --m_offset;
70 ASSERT_UNUSED(cc, nextInputChar() == cc);
71 }
72
73 double getDouble(unsigned start, unsigned end) const;
74
75 template<bool characterPredicate(UChar)>
76 unsigned skipWhilePredicate(unsigned offset)
77 {
78 if (m_string->is8Bit()) {
79 const LChar* characters8 = m_string->characters8();
80 while ((m_offset + offset) < m_stringLength && characterPredicate(characters8[m_offset + offset]))
81 ++offset;
82 } else {
83 const UChar* characters16 = m_string->characters16();
84 while ((m_offset + offset) < m_stringLength && characterPredicate(characters16[m_offset + offset]))
85 ++offset;
86 }
87 return offset;
88 }
89
90 void advanceUntilNonWhitespace();
91
92 unsigned length() const { return m_stringLength; }
93 unsigned offset() const { return std::min(m_offset, m_stringLength); }
94
95 StringView rangeAt(unsigned start, unsigned length) const
96 {
97 ASSERT(start + length <= m_stringLength);
98 return StringView(m_string.get()).substring(start, length); // FIXME: Should make a constructor on StringView for this.
99 }
100
101private:
102 size_t m_offset;
103 const size_t m_stringLength;
104 RefPtr<StringImpl> m_string;
105};
106
107} // namespace WebCore
108