1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef TX_XSLT_PATTERNS_H
7 #define TX_XSLT_PATTERNS_H
8 
9 #include "mozilla/Attributes.h"
10 #include "txExpandedName.h"
11 #include "txExpr.h"
12 #include "txXMLUtils.h"
13 
14 class txPattern
15 {
16 public:
txPattern()17     txPattern()
18     {
19         MOZ_COUNT_CTOR(txPattern);
20     }
~txPattern()21     virtual ~txPattern()
22     {
23         MOZ_COUNT_DTOR(txPattern);
24     }
25 
26     /*
27      * Determines whether this Pattern matches the given node.
28      */
29     virtual bool matches(const txXPathNode& aNode,
30                           txIMatchContext* aContext) = 0;
31 
32     /*
33      * Returns the default priority of this Pattern.
34      *
35      * Simple Patterns return the values as specified in XPath 5.5.
36      * Returns -Inf for union patterns, as it shouldn't be called on them.
37      */
38     virtual double getDefaultPriority() = 0;
39 
40     /**
41      * Returns the type of this pattern.
42      */
43     enum Type {
44         STEP_PATTERN,
45         UNION_PATTERN,
46         OTHER_PATTERN
47     };
getType()48     virtual Type getType()
49     {
50       return OTHER_PATTERN;
51     }
52 
53     /**
54      * Returns sub-expression at given position
55      */
56     virtual Expr* getSubExprAt(uint32_t aPos) = 0;
57 
58     /**
59      * Replace sub-expression at given position. Does not delete the old
60      * expression, that is the responsibility of the caller.
61      */
62     virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0;
63 
64     /**
65      * Returns sub-pattern at given position
66      */
67     virtual txPattern* getSubPatternAt(uint32_t aPos) = 0;
68 
69     /**
70      * Replace sub-pattern at given position. Does not delete the old
71      * pattern, that is the responsibility of the caller.
72      */
73     virtual void setSubPatternAt(uint32_t aPos, txPattern* aPattern) = 0;
74 
75 #ifdef TX_TO_STRING
76     /*
77      * Returns the String representation of this Pattern.
78      * @param dest the String to use when creating the String
79      * representation. The String representation will be appended to
80      * any data in the destination String, to allow cascading calls to
81      * other #toString() methods for Patterns.
82      * @return the String representation of this Pattern.
83      */
84     virtual void toString(nsAString& aDest) = 0;
85 #endif
86 };
87 
88 #define TX_DECL_PATTERN_BASE \
89     bool matches(const txXPathNode& aNode, txIMatchContext* aContext) override; \
90     double getDefaultPriority() override; \
91     virtual Expr* getSubExprAt(uint32_t aPos) override; \
92     virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) override; \
93     virtual txPattern* getSubPatternAt(uint32_t aPos) override; \
94     virtual void setSubPatternAt(uint32_t aPos, txPattern* aPattern) override
95 
96 #ifndef TX_TO_STRING
97 #define TX_DECL_PATTERN TX_DECL_PATTERN_BASE
98 #else
99 #define TX_DECL_PATTERN \
100     TX_DECL_PATTERN_BASE; \
101     void toString(nsAString& aDest) override
102 #endif
103 
104 #define TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(_class)             \
105 Expr*                                                         \
106 _class::getSubExprAt(uint32_t aPos)                           \
107 {                                                             \
108     return nullptr;                                            \
109 }                                                             \
110 void                                                          \
111 _class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
112 {                                                             \
113     NS_NOTREACHED("setting bad subexpression index");         \
114 }
115 
116 #define TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(_class)          \
117 txPattern*                                                    \
118 _class::getSubPatternAt(uint32_t aPos)                        \
119 {                                                             \
120     return nullptr;                                            \
121 }                                                             \
122 void                                                          \
123 _class::setSubPatternAt(uint32_t aPos, txPattern* aPattern)   \
124 {                                                             \
125     NS_NOTREACHED("setting bad subexpression index");         \
126 }
127 
128 class txUnionPattern : public txPattern
129 {
130 public:
addPattern(txPattern * aPattern)131     nsresult addPattern(txPattern* aPattern)
132     {
133         return mLocPathPatterns.AppendElement(aPattern) ?
134             NS_OK : NS_ERROR_OUT_OF_MEMORY;
135     }
136 
137     TX_DECL_PATTERN;
138     Type getType() override;
139 
140 private:
141     txOwningArray<txPattern> mLocPathPatterns;
142 };
143 
144 class txLocPathPattern : public txPattern
145 {
146 public:
147     nsresult addStep(txPattern* aPattern, bool isChild);
148 
149     TX_DECL_PATTERN;
150 
151 private:
152     class Step {
153     public:
154         nsAutoPtr<txPattern> pattern;
155         bool isChild;
156     };
157 
158     nsTArray<Step> mSteps;
159 };
160 
161 class txRootPattern : public txPattern
162 {
163 public:
164 #ifdef TX_TO_STRING
txRootPattern()165     txRootPattern()
166         : mSerialize(true)
167     {
168     }
169 #endif
170 
171     TX_DECL_PATTERN;
172 
173 #ifdef TX_TO_STRING
174 public:
setSerialize(bool aSerialize)175     void setSerialize(bool aSerialize)
176     {
177         mSerialize = aSerialize;
178     }
179 
180 private:
181     // Don't serialize txRootPattern if it's used in a txLocPathPattern
182     bool mSerialize;
183 #endif
184 };
185 
186 class txIdPattern : public txPattern
187 {
188 public:
189     explicit txIdPattern(const nsSubstring& aString);
190 
191     TX_DECL_PATTERN;
192 
193 private:
194     nsCOMArray<nsIAtom> mIds;
195 };
196 
197 class txKeyPattern : public txPattern
198 {
199 public:
txKeyPattern(nsIAtom * aPrefix,nsIAtom * aLocalName,int32_t aNSID,const nsAString & aValue)200     txKeyPattern(nsIAtom* aPrefix, nsIAtom* aLocalName,
201                  int32_t aNSID, const nsAString& aValue)
202         : mName(aNSID, aLocalName),
203 #ifdef TX_TO_STRING
204           mPrefix(aPrefix),
205 #endif
206           mValue(aValue)
207     {
208     }
209 
210     TX_DECL_PATTERN;
211 
212 private:
213     txExpandedName mName;
214 #ifdef TX_TO_STRING
215     nsCOMPtr<nsIAtom> mPrefix;
216 #endif
217     nsString mValue;
218 };
219 
220 class txStepPattern : public txPattern,
221                       public PredicateList
222 {
223 public:
txStepPattern(txNodeTest * aNodeTest,bool isAttr)224     txStepPattern(txNodeTest* aNodeTest, bool isAttr)
225         : mNodeTest(aNodeTest), mIsAttr(isAttr)
226     {
227     }
228 
229     TX_DECL_PATTERN;
230     Type getType() override;
231 
getNodeTest()232     txNodeTest* getNodeTest()
233     {
234       return mNodeTest;
235     }
setNodeTest(txNodeTest * aNodeTest)236     void setNodeTest(txNodeTest* aNodeTest)
237     {
238       mNodeTest.forget();
239       mNodeTest = aNodeTest;
240     }
241 
242 private:
243     nsAutoPtr<txNodeTest> mNodeTest;
244     bool mIsAttr;
245 };
246 
247 #endif // TX_XSLT_PATTERNS_H
248