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  public:
txPattern()16   txPattern() { MOZ_COUNT_CTOR(txPattern); }
~txPattern()17   virtual ~txPattern() { MOZ_COUNT_DTOR(txPattern); }
18 
19   /*
20    * Determines whether this Pattern matches the given node.
21    */
22   virtual nsresult matches(const txXPathNode& aNode, txIMatchContext* aContext,
23                            bool& aMatched) = 0;
24 
25   /*
26    * Returns the default priority of this Pattern.
27    *
28    * Simple Patterns return the values as specified in XPath 5.5.
29    * Returns -Inf for union patterns, as it shouldn't be called on them.
30    */
31   virtual double getDefaultPriority() = 0;
32 
33   /**
34    * Returns the type of this pattern.
35    */
36   enum Type { STEP_PATTERN, UNION_PATTERN, OTHER_PATTERN };
getType()37   virtual Type getType() { return OTHER_PATTERN; }
38 
39   /**
40    * Returns sub-expression at given position
41    */
42   virtual Expr* getSubExprAt(uint32_t aPos) = 0;
43 
44   /**
45    * Replace sub-expression at given position. Does not delete the old
46    * expression, that is the responsibility of the caller.
47    */
48   virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0;
49 
50   /**
51    * Returns sub-pattern at given position
52    */
53   virtual txPattern* getSubPatternAt(uint32_t aPos) = 0;
54 
55   /**
56    * Replace sub-pattern at given position. Does not delete the old
57    * pattern, that is the responsibility of the caller.
58    */
59   virtual void setSubPatternAt(uint32_t aPos, txPattern* aPattern) = 0;
60 
61 #ifdef TX_TO_STRING
62   /*
63    * Returns the String representation of this Pattern.
64    * @param dest the String to use when creating the String
65    * representation. The String representation will be appended to
66    * any data in the destination String, to allow cascading calls to
67    * other #toString() methods for Patterns.
68    * @return the String representation of this Pattern.
69    */
70   virtual void toString(nsAString& aDest) = 0;
71 #endif
72 };
73 
74 #define TX_DECL_PATTERN_BASE                                            \
75   nsresult matches(const txXPathNode& aNode, txIMatchContext* aContext, \
76                    bool& aMatched) override;                            \
77   double getDefaultPriority() override;                                 \
78   virtual Expr* getSubExprAt(uint32_t aPos) override;                   \
79   virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) override;       \
80   virtual txPattern* getSubPatternAt(uint32_t aPos) override;           \
81   virtual void setSubPatternAt(uint32_t aPos, txPattern* aPattern) override
82 
83 #ifndef TX_TO_STRING
84 #define TX_DECL_PATTERN TX_DECL_PATTERN_BASE
85 #else
86 #define TX_DECL_PATTERN \
87   TX_DECL_PATTERN_BASE; \
88   void toString(nsAString& aDest) override
89 #endif
90 
91 #define TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(_class)               \
92   Expr* _class::getSubExprAt(uint32_t aPos) { return nullptr; } \
93   void _class::setSubExprAt(uint32_t aPos, Expr* aExpr) {       \
94     NS_NOTREACHED("setting bad subexpression index");           \
95   }
96 
97 #define TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(_class)                    \
98   txPattern* _class::getSubPatternAt(uint32_t aPos) { return nullptr; } \
99   void _class::setSubPatternAt(uint32_t aPos, txPattern* aPattern) {    \
100     NS_NOTREACHED("setting bad subexpression index");                   \
101   }
102 
103 class txUnionPattern : public txPattern {
104  public:
addPattern(txPattern * aPattern)105   nsresult addPattern(txPattern* aPattern) {
106     return mLocPathPatterns.AppendElement(aPattern) ? NS_OK
107                                                     : NS_ERROR_OUT_OF_MEMORY;
108   }
109 
110   TX_DECL_PATTERN;
111   Type getType() override;
112 
113  private:
114   txOwningArray<txPattern> mLocPathPatterns;
115 };
116 
117 class txLocPathPattern : public txPattern {
118  public:
119   nsresult addStep(txPattern* aPattern, bool isChild);
120 
121   TX_DECL_PATTERN;
122 
123  private:
124   class Step {
125    public:
126     nsAutoPtr<txPattern> pattern;
127     bool isChild;
128   };
129 
130   nsTArray<Step> mSteps;
131 };
132 
133 class txRootPattern : public txPattern {
134  public:
135 #ifdef TX_TO_STRING
txRootPattern()136   txRootPattern() : mSerialize(true) {}
137 #endif
138 
139   TX_DECL_PATTERN;
140 
141 #ifdef TX_TO_STRING
142  public:
setSerialize(bool aSerialize)143   void setSerialize(bool aSerialize) { mSerialize = aSerialize; }
144 
145  private:
146   // Don't serialize txRootPattern if it's used in a txLocPathPattern
147   bool mSerialize;
148 #endif
149 };
150 
151 class txIdPattern : public txPattern {
152  public:
153   explicit txIdPattern(const nsAString& aString);
154 
155   TX_DECL_PATTERN;
156 
157  private:
158   nsTArray<RefPtr<nsAtom>> mIds;
159 };
160 
161 class txKeyPattern : public txPattern {
162  public:
txKeyPattern(nsAtom * aPrefix,nsAtom * aLocalName,int32_t aNSID,const nsAString & aValue)163   txKeyPattern(nsAtom* aPrefix, nsAtom* aLocalName, int32_t aNSID,
164                const nsAString& aValue)
165       : mName(aNSID, aLocalName),
166 #ifdef TX_TO_STRING
167         mPrefix(aPrefix),
168 #endif
169         mValue(aValue) {
170   }
171 
172   TX_DECL_PATTERN;
173 
174  private:
175   txExpandedName mName;
176 #ifdef TX_TO_STRING
177   RefPtr<nsAtom> mPrefix;
178 #endif
179   nsString mValue;
180 };
181 
182 class txStepPattern : public txPattern, public PredicateList {
183  public:
txStepPattern(txNodeTest * aNodeTest,bool isAttr)184   txStepPattern(txNodeTest* aNodeTest, bool isAttr)
185       : mNodeTest(aNodeTest), mIsAttr(isAttr) {}
186 
187   TX_DECL_PATTERN;
188   Type getType() override;
189 
getNodeTest()190   txNodeTest* getNodeTest() { return mNodeTest; }
setNodeTest(txNodeTest * aNodeTest)191   void setNodeTest(txNodeTest* aNodeTest) {
192     mNodeTest.forget();
193     mNodeTest = aNodeTest;
194   }
195 
196  private:
197   nsAutoPtr<txNodeTest> mNodeTest;
198   bool mIsAttr;
199 };
200 
201 #endif  // TX_XSLT_PATTERNS_H
202