1 /* 2 * Copyright (C) 2005 Frerich Raabe <raabe (at) kde.org> 3 * Copyright (C) 2006, 2009 Apple Inc. 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 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef XPathStep_h 28 #define XPathStep_h 29 30 #include "core/xml/XPathExpressionNode.h" 31 #include "core/xml/XPathNodeSet.h" 32 33 namespace WebCore { 34 35 class Node; 36 37 namespace XPath { 38 39 class Predicate; 40 41 class Step : public ParseNode { 42 WTF_MAKE_NONCOPYABLE(Step); 43 WTF_MAKE_FAST_ALLOCATED; 44 public: 45 enum Axis { 46 AncestorAxis, AncestorOrSelfAxis, AttributeAxis, 47 ChildAxis, DescendantAxis, DescendantOrSelfAxis, 48 FollowingAxis, FollowingSiblingAxis, NamespaceAxis, 49 ParentAxis, PrecedingAxis, PrecedingSiblingAxis, 50 SelfAxis 51 }; 52 53 class NodeTest { 54 WTF_MAKE_FAST_ALLOCATED; 55 public: 56 enum Kind { 57 TextNodeTest, CommentNodeTest, ProcessingInstructionNodeTest, AnyNodeTest, NameTest 58 }; 59 60 NodeTest(Kind kind) : m_kind(kind) { } 61 NodeTest(Kind kind, const String& data) : m_kind(kind), m_data(data) { } 62 NodeTest(Kind kind, const AtomicString& data, const AtomicString& namespaceURI) : m_kind(kind), m_data(data), m_namespaceURI(namespaceURI) { } 63 64 NodeTest(const NodeTest& o) 65 : m_kind(o.m_kind) 66 , m_data(o.m_data) 67 , m_namespaceURI(o.m_namespaceURI) 68 { 69 ASSERT(o.m_mergedPredicates.isEmpty()); 70 } 71 NodeTest& operator=(const NodeTest& o) 72 { 73 m_kind = o.m_kind; 74 m_data = o.m_data; 75 m_namespaceURI = o.m_namespaceURI; 76 ASSERT(o.m_mergedPredicates.isEmpty()); 77 return *this; 78 } 79 80 Kind kind() const { return m_kind; } 81 const AtomicString& data() const { return m_data; } 82 const AtomicString& namespaceURI() const { return m_namespaceURI; } 83 Vector<OwnPtr<Predicate> >& mergedPredicates() { return m_mergedPredicates; } 84 const Vector<OwnPtr<Predicate> >& mergedPredicates() const { return m_mergedPredicates; } 85 86 private: 87 Kind m_kind; 88 AtomicString m_data; 89 AtomicString m_namespaceURI; 90 91 // When possible, we merge some or all predicates with node test for better performance. 92 Vector<OwnPtr<Predicate> > m_mergedPredicates; 93 }; 94 95 Step(Axis, const NodeTest&); 96 Step(Axis, const NodeTest&, Vector<OwnPtr<Predicate> >&); 97 ~Step(); 98 99 void optimize(); 100 101 void evaluate(Node* context, NodeSet&) const; 102 103 Axis axis() const { return m_axis; } 104 const NodeTest& nodeTest() const { return m_nodeTest; } 105 106 private: 107 friend void optimizeStepPair(Step*, Step*, bool&); 108 bool predicatesAreContextListInsensitive() const; 109 110 void parseNodeTest(const String&); 111 void nodesInAxis(Node* context, NodeSet&) const; 112 String namespaceFromNodetest(const String& nodeTest) const; 113 114 Axis m_axis; 115 NodeTest m_nodeTest; 116 Vector<OwnPtr<Predicate> > m_predicates; 117 }; 118 119 void optimizeStepPair(Step*, Step*, bool& dropSecondStep); 120 121 } // namespace XPath 122 123 } // namespace WebCore 124 125 #endif // XPathStep_h 126