Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / html / parser / AtomicHTMLToken.h
1 /*
2  * Copyright (C) 2013 Google, Inc. All Rights Reserved.
3  * Copyright (C) 2015 Apple Inc. All Rights Reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #ifndef AtomicHTMLToken_h
28 #define AtomicHTMLToken_h
29
30 #include "HTMLToken.h"
31
32 namespace WebCore {
33
34 class AtomicHTMLToken {
35 public:
36     explicit AtomicHTMLToken(HTMLToken&);
37     AtomicHTMLToken(HTMLToken::Type, const AtomicString& name, Vector<Attribute>&& = Vector<Attribute>()); // Only StartTag or EndTag.
38
39     HTMLToken::Type type() const;
40
41     // StartTag, EndTag, DOCTYPE.
42
43     void setName(const AtomicString&);
44
45     const AtomicString& name() const;
46
47     // DOCTYPE.
48
49     bool forceQuirks() const;
50     String publicIdentifier() const;
51     String systemIdentifier() const;
52
53     // StartTag, EndTag.
54
55     Vector<Attribute>& attributes();
56
57     bool selfClosing() const;
58     const Vector<Attribute>& attributes() const;
59
60     // Characters
61
62     const UChar* characters() const;
63     unsigned charactersLength() const;
64     bool charactersIsAll8BitData() const;
65
66     // Comment
67
68     const String& comment() const;
69
70 private:
71     HTMLToken::Type m_type;
72
73     void initializeAttributes(const HTMLToken::AttributeList& attributes);
74
75     AtomicString m_name; // StartTag, EndTag, DOCTYPE.
76
77     String m_data; // Comment
78
79     // We don't want to copy the the characters out of the HTMLToken, so we keep a pointer to its buffer instead.
80     // This buffer is owned by the HTMLToken and causes a lifetime dependence between these objects.
81     // FIXME: Add a mechanism for "internalizing" the characters when the HTMLToken is destroyed.
82     const UChar* m_externalCharacters; // Character
83     unsigned m_externalCharactersLength; // Character
84     bool m_externalCharactersIsAll8BitData; // Character
85
86     std::unique_ptr<DoctypeData> m_doctypeData; // DOCTYPE.
87
88     bool m_selfClosing; // StartTag, EndTag.
89     Vector<Attribute> m_attributes; // StartTag, EndTag.
90 };
91
92 Attribute* findAttribute(Vector<Attribute>&, const QualifiedName&);
93
94 inline HTMLToken::Type AtomicHTMLToken::type() const
95 {
96     return m_type;
97 }
98
99 inline const AtomicString& AtomicHTMLToken::name() const
100 {
101     ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE);
102     return m_name;
103 }
104
105 inline void AtomicHTMLToken::setName(const AtomicString& name)
106 {
107     ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE);
108     m_name = name;
109 }
110
111 inline bool AtomicHTMLToken::selfClosing() const
112 {
113     ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
114     return m_selfClosing;
115 }
116
117 inline Vector<Attribute>& AtomicHTMLToken::attributes()
118 {
119     ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
120     return m_attributes;
121 }
122
123 inline const Vector<Attribute>& AtomicHTMLToken::attributes() const
124 {
125     ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
126     return m_attributes;
127 }
128
129 inline const UChar* AtomicHTMLToken::characters() const
130 {
131     ASSERT(m_type == HTMLToken::Character);
132     return m_externalCharacters;
133 }
134
135 inline unsigned AtomicHTMLToken::charactersLength() const
136 {
137     ASSERT(m_type == HTMLToken::Character);
138     return m_externalCharactersLength;
139 }
140
141 inline bool AtomicHTMLToken::charactersIsAll8BitData() const
142 {
143     return m_externalCharactersIsAll8BitData;
144 }
145
146 inline const String& AtomicHTMLToken::comment() const
147 {
148     ASSERT(m_type == HTMLToken::Comment);
149     return m_data;
150 }
151
152 inline bool AtomicHTMLToken::forceQuirks() const
153 {
154     ASSERT(m_type == HTMLToken::DOCTYPE);
155     return m_doctypeData->forceQuirks;
156 }
157
158 inline String AtomicHTMLToken::publicIdentifier() const
159 {
160     ASSERT(m_type == HTMLToken::DOCTYPE);
161     if (!m_doctypeData->hasPublicIdentifier)
162         return String();
163     return StringImpl::create8BitIfPossible(m_doctypeData->publicIdentifier);
164 }
165
166 inline String AtomicHTMLToken::systemIdentifier() const
167 {
168     if (!m_doctypeData->hasSystemIdentifier)
169         return String();
170     return StringImpl::create8BitIfPossible(m_doctypeData->systemIdentifier);
171 }
172
173 inline Attribute* findAttribute(Vector<Attribute>& attributes, const QualifiedName& name)
174 {
175     for (auto& attribute : attributes) {
176         if (attribute.name().matches(name))
177             return &attribute;
178     }
179     return nullptr;
180 }
181
182 inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList& attributes)
183 {
184     unsigned size = attributes.size();
185     if (!size)
186         return;
187
188     m_attributes.reserveInitialCapacity(size);
189     for (auto& attribute : attributes) {
190         if (attribute.name.isEmpty())
191             continue;
192
193         QualifiedName name(nullAtom, AtomicString(attribute.name), nullAtom);
194
195         // FIXME: This is N^2 for the number of attributes.
196         if (!findAttribute(m_attributes, name))
197             m_attributes.append(Attribute(name, AtomicString(attribute.value)));
198     }
199 }
200
201 inline AtomicHTMLToken::AtomicHTMLToken(HTMLToken& token)
202     : m_type(token.type())
203 {
204     switch (m_type) {
205     case HTMLToken::Uninitialized:
206         ASSERT_NOT_REACHED();
207         return;
208     case HTMLToken::DOCTYPE:
209         m_name = AtomicString(token.name());
210         m_doctypeData = token.releaseDoctypeData();
211         return;
212     case HTMLToken::EndOfFile:
213         return;
214     case HTMLToken::StartTag:
215     case HTMLToken::EndTag:
216         m_selfClosing = token.selfClosing();
217         m_name = AtomicString(token.name());
218         initializeAttributes(token.attributes());
219         return;
220     case HTMLToken::Comment:
221         if (token.commentIsAll8BitData())
222             m_data = String::make8BitFrom16BitSource(token.comment());
223         else
224             m_data = String(token.comment());
225         return;
226     case HTMLToken::Character:
227         m_externalCharacters = token.characters().data();
228         m_externalCharactersLength = token.characters().size();
229         m_externalCharactersIsAll8BitData = token.charactersIsAll8BitData();
230         return;
231     }
232     ASSERT_NOT_REACHED();
233 }
234
235 inline AtomicHTMLToken::AtomicHTMLToken(HTMLToken::Type type, const AtomicString& name, Vector<Attribute>&& attributes)
236     : m_type(type)
237     , m_name(name)
238     , m_selfClosing(false)
239     , m_attributes(WTFMove(attributes))
240 {
241     ASSERT(type == HTMLToken::StartTag || type == HTMLToken::EndTag);
242 }
243
244 }
245
246 #endif