1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGXML_XPATH_XPATH_EXPR
  7 #define SNGXML_XPATH_XPATH_EXPR
  8 #include <sngxml/xpath/XPathObject.hpp>
  9 #include <sngxml/xpath/XPathContext.hpp>
 10 #include <string>
 11 #include <memory>
 12 #include <vector>
 13 
 14 namespace sngxml { namespace xpath {
 15 
 16 enum class Operator
 17 {
 18     equalnotEquallessgreaterlessOrEqualgreaterOrEqualplusminusmuldivmodslashslashSlash
 19 };
 20 
 21 class XPathExpr 
 22 {
 23 public:
 24     XPathExpr();
 25     XPathExpr(const XPathExpr&) = delete;
 26     XPathExpr& operator=(const XPathExpr&) = delete;
 27     XPathExpr(XPathExpr&&) = delete;
 28     XPathExpr&& operator=(XPathExpr&&) = delete;
 29     virtual ~XPathExpr();
 30     virtual std::std::unique_ptr<XPathObject>Evaluate(XPathContext&context){returnstd::unique_ptr<XPathObject>(); }
 31     virtual std::u32string TextValue() const { return std::u32string(); }
 32     virtual std::unique_ptr<dom::Node> ToDom() const = 0;
 33 };
 34 
 35 class XPathUnaryExpr public XPathExpr
 36 {
 37 public:
 38     XPathUnaryExpr(XPathExpr* operand_);
 39     XPathExpr* Operand() const { return operand.get(); }
 40 private:
 41     std::unique_ptr<XPathExpr> operand;
 42 };
 43 
 44 class XPathBinaryExpr public XPathExpr
 45 {
 46 public:
 47     XPathBinaryExpr(XPathExpr* left_XPathExpr* right_);
 48     XPathExpr* Left() const { return left.get(); }
 49     XPathExpr* Right() const { return right.get(); }
 50 private:
 51     std::unique_ptr<XPathExpr> left;
 52     std::unique_ptr<XPathExpr> right;
 53 };
 54 
 55 class XPathOrExpr public XPathBinaryExpr
 56 {
 57 public:
 58     XPathOrExpr(XPathExpr* left_XPathExpr* right_);
 59     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
 60     std::unique_ptr<dom::Node> ToDom() const override;
 61 };
 62 
 63 class XPathAndExpr public XPathBinaryExpr
 64 {
 65 public:
 66     XPathAndExpr(XPathExpr* left_XPathExpr* right_);
 67     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
 68     std::unique_ptr<dom::Node> ToDom() const override;
 69 };
 70 
 71 class XPathEqualExpr public XPathBinaryExpr
 72 {
 73 public:
 74     XPathEqualExpr(XPathExpr* left_XPathExpr* right_);
 75     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
 76     std::unique_ptr<dom::Node> ToDom() const override;
 77 };
 78 
 79 class XPathNotEqualExpr public XPathBinaryExpr
 80 {
 81 public:
 82     XPathNotEqualExpr(XPathExpr* left_XPathExpr* right_);
 83     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
 84     std::unique_ptr<dom::Node> ToDom() const override;
 85 };
 86 
 87 class XPathLessExpr public XPathBinaryExpr
 88 {
 89 public:
 90     XPathLessExpr(XPathExpr* left_XPathExpr* right_);
 91     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
 92     std::unique_ptr<dom::Node> ToDom() const override;
 93 };
 94 
 95 class XPathGreaterExpr public XPathBinaryExpr
 96 {
 97 public:
 98     XPathGreaterExpr(XPathExpr* left_XPathExpr* right_);
 99     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
100     std::unique_ptr<dom::Node> ToDom() const override;
101 };
102 
103 class XPathLessOrEqualExpr public XPathBinaryExpr
104 {
105 public:
106     XPathLessOrEqualExpr(XPathExpr* left_XPathExpr* right_);
107     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
108     std::unique_ptr<dom::Node> ToDom() const override;
109 };
110 
111 class XPathGreaterOrEqualExpr public XPathBinaryExpr
112 {
113 public:
114     XPathGreaterOrEqualExpr(XPathExpr* left_XPathExpr* right_);
115     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
116     std::unique_ptr<dom::Node> ToDom() const override;
117 };
118 
119 class XPathAddExpr public XPathBinaryExpr
120 {
121 public:
122     XPathAddExpr(XPathExpr* left_XPathExpr* right_);
123     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
124     std::unique_ptr<dom::Node> ToDom() const override;
125 };
126 
127 class XPathSubExpr public XPathBinaryExpr
128 {
129 public:
130     XPathSubExpr(XPathExpr* left_XPathExpr* right_);
131     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
132     std::unique_ptr<dom::Node> ToDom() const override;
133 };
134 
135 class XPathMulExpr public XPathBinaryExpr
136 {
137 public:
138     XPathMulExpr(XPathExpr* left_XPathExpr* right_);
139     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
140     std::unique_ptr<dom::Node> ToDom() const override;
141 };
142 
143 class XPathDivExpr public XPathBinaryExpr
144 {
145 public:
146     XPathDivExpr(XPathExpr* left_XPathExpr* right_);
147     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
148     std::unique_ptr<dom::Node> ToDom() const override;
149 };
150 
151 class XPathModExpr public XPathBinaryExpr
152 {
153 public:
154     XPathModExpr(XPathExpr* left_XPathExpr* right_);
155     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
156     std::unique_ptr<dom::Node> ToDom() const override;
157 };
158 
159 class XPathUnaryMinusExpr public XPathUnaryExpr
160 {
161 public:
162     XPathUnaryMinusExpr(XPathExpr* operand_);
163     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
164     std::unique_ptr<dom::Node> ToDom() const override;
165 };
166 
167 class XPathUnionExpr public XPathBinaryExpr
168 {
169 public:
170     XPathUnionExpr(XPathExpr* left_XPathExpr* right_);
171     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
172     std::unique_ptr<dom::Node> ToDom() const override;
173 };
174 
175 class XPathCombineStepExpr public XPathBinaryExpr
176 {
177 public:
178     XPathCombineStepExpr(XPathExpr* left_XPathExpr* right_);
179     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
180     std::unique_ptr<dom::Node> ToDom() const override;
181 };
182 
183 class XPathRootNodeExpr public XPathExpr
184 {
185 public:
186     XPathRootNodeExpr();
187     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
188     std::unique_ptr<dom::Node> ToDom() const override;
189 };
190 
191 class XPathFilterExpr public XPathUnaryExpr
192 {
193 public:
194     XPathFilterExpr(XPathExpr* expr_XPathExpr* predicate_);
195     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
196     std::unique_ptr<dom::Node> ToDom() const override;
197 private:
198     std::unique_ptr<XPathExpr> predicate;
199 };
200 
201 class XPathNodeTestExpr public XPathExpr
202 {
203 public:
204     virtual bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const { return true; }
205 };
206 
207 class XPathLocationStepExpr public XPathExpr
208 {
209 public:
210     XPathLocationStepExpr(sngxml::dom::Axis axis_XPathNodeTestExpr* nodeTest_);
211     XPathLocationStepExpr(const XPathLocationStepExpr&) = delete;
212     XPathLocationStepExpr& operator=(const XPathLocationStepExpr&) = delete;
213     XPathLocationStepExpr(XPathLocationStepExpr&&) = delete;
214     XPathLocationStepExpr&& operator=(XPathLocationStepExpr&&) = delete;
215     void AddPredicate(XPathExpr* predicate);
216     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
217     std::unique_ptr<dom::Node> ToDom() const override;
218 private:
219     sngxml::dom::Axis axis;
220     std::unique_ptr<XPathNodeTestExpr> nodeTest;
221     std::vector<std::std::unique_ptr<XPathExpr>>predicates;
222 };
223 
224 sngxml::dom::Axis GetAxis(const std::u32string& axisName);
225 
226 class XPathPILiteralTest public XPathNodeTestExpr
227 {
228 public:
229     XPathPILiteralTest(XPathExpr* literal_);
230     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
231     std::unique_ptr<dom::Node> ToDom() const override;
232 private:
233     std::unique_ptr<XPathExpr> literal;
234 };
235 
236 class XPathCommentNodeTest public XPathNodeTestExpr
237 {
238 public:
239     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
240     std::unique_ptr<dom::Node> ToDom() const override;
241 };
242 
243 class XPathTextNodeTest public XPathNodeTestExpr
244 {
245 public:
246     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
247     std::unique_ptr<dom::Node> ToDom() const override;
248 };
249 
250 class XPathPINodeTest public XPathNodeTestExpr
251 {
252 public:
253     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
254     std::unique_ptr<dom::Node> ToDom() const override;
255 };
256 
257 class XPathAnyNodeTest public XPathNodeTestExpr
258 {
259 public:
260     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
261     std::unique_ptr<dom::Node> ToDom() const override;
262 };
263 
264 class XPathPrincipalNodeTest public XPathNodeTestExpr
265 {
266 public:
267     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
268     std::unique_ptr<dom::Node> ToDom() const override;
269 };
270 
271 class XPathPrefixTest public XPathNodeTestExpr
272 {
273 public:
274     XPathPrefixTest(const std::u32string& name_);
275     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
276     std::unique_ptr<dom::Node> ToDom() const override;
277 private:
278     std::u32string name;
279 };
280 
281 class XPathNameTest public XPathNodeTestExpr
282 {
283 public:
284     XPathNameTest(const std::u32string& name_);
285     bool Select(sngxml::dom::Node* nodesngxml::dom::Axis axis) const override;
286     std::unique_ptr<dom::Node> ToDom() const override;
287 private:
288     std::u32string name;
289 };
290 
291 class XPathVariableReference public XPathExpr
292 {
293 public:
294     XPathVariableReference(const std::u32string& name_);
295     std::unique_ptr<dom::Node> ToDom() const override;
296 private:
297     std::u32string name;
298 };
299 
300 class XPathLiteral public XPathExpr
301 {
302 public:
303     XPathLiteral(const std::u32string& value_);
304     std::u32string TextValue() const override { return value; }
305     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
306     std::unique_ptr<dom::Node> ToDom() const override;
307 private:
308     std::u32string value;
309 };
310 
311 class XPathNumberExpr public XPathExpr
312 {
313 public:
314     XPathNumberExpr(const std::u32string& value_);
315     XPathNumberExpr(double value_);
316     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
317     std::unique_ptr<dom::Node> ToDom() const override;
318 private:
319     double value;
320 };
321 
322 class XPathFunctionCall public XPathExpr
323 {
324 public:
325     XPathFunctionCall(const std::u32string& functionName_);
326     void AddArgument(XPathExpr* argument);
327     std::unique_ptr<XPathObject> Evaluate(XPathContext& context) override;
328     std::unique_ptr<dom::Node> ToDom() const override;
329 private:
330     std::u32string functionName;
331     std::vector<std::std::unique_ptr<XPathExpr>>arguments;
332 };
333 
334 } } // namespace sngxml::xpath
335 
336 #endif // SNGXML_XPATH_XPATH_EXPR