15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2009 Apple Inc.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
1502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathFunctions.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/XMLNames.h"
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/Attr.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ProcessingInstruction.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/TreeScope.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathUtil.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathValue.h"
38e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/MathExtras.h"
39e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/text/StringBuilder.h"
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace XPath {
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isWhitespace(UChar c)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return c == ' ' || c == '\n' || c == '\r' || c == '\t';
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DEFINE_FUNCTION_CREATOR(Class) static Function* create##Class() { return new Class; }
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Interval {
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static const int Inf = -1;
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Interval();
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Interval(int value);
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Interval(int min, int max);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool contains(int value) const;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_min;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_max;
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct FunctionRec {
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef Function *(*FactoryFn)();
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FactoryFn factoryFn;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Interval args;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static HashMap<String, FunctionRec>* functionMap;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunLast FINAL : public Function {
76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FunLast() { setIsContextSizeSensitive(true); }
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunPosition FINAL : public Function {
83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FunPosition() { setIsContextPositionSensitive(true); }
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunCount FINAL : public Function {
90197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunId FINAL : public Function {
95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunLocalName FINAL : public Function {
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
10302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunLocalName() { setIsContextNodeSensitive(true); } // local-name() with no arguments uses context node.
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunNamespaceURI FINAL : public Function {
107197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
11002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunNamespaceURI() { setIsContextNodeSensitive(true); } // namespace-uri() with no arguments uses context node.
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunName FINAL : public Function {
114197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
11702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunName() { setIsContextNodeSensitive(true); } // name() with no arguments uses context node.
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunString FINAL : public Function {
121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
12402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunString() { setIsContextNodeSensitive(true); } // string() with no arguments uses context node.
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunConcat FINAL : public Function {
128197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunStartsWith FINAL : public Function {
133197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunContains FINAL : public Function {
138197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunSubstringBefore FINAL : public Function {
143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunSubstringAfter FINAL : public Function {
148197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunSubstring FINAL : public Function {
153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunStringLength FINAL : public Function {
158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
16102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunStringLength() { setIsContextNodeSensitive(true); } // string-length() with no arguments uses context node.
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunNormalizeSpace FINAL : public Function {
165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
16802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunNormalizeSpace() { setIsContextNodeSensitive(true); } // normalize-space() with no arguments uses context node.
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunTranslate FINAL : public Function {
172197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunBoolean FINAL : public Function {
177197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunNot FINAL : public Function {
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunTrue FINAL : public Function {
187197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunFalse FINAL : public Function {
192197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunLang FINAL : public Function {
197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
20002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunLang() { setIsContextNodeSensitive(true); } // lang() always works on context node.
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunNumber FINAL : public Function {
204197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
20702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    FunNumber() { setIsContextNodeSensitive(true); } // number() with no arguments uses context node.
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunSum FINAL : public Function {
211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
21509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunFloor FINAL : public Function {
216197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunCeiling FINAL : public Function {
221197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
22509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FunRound FINAL : public Function {
226197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual Value evaluate(EvaluationContext&) const OVERRIDE;
22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static double round(double);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunLast)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunPosition)
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunCount)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunId)
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunLocalName)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunNamespaceURI)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunName)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunString)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunConcat)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunStartsWith)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunContains)
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunSubstringBefore)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunSubstringAfter)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunSubstring)
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunStringLength)
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunNormalizeSpace)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunTranslate)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunBoolean)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunNot)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunTrue)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunFalse)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunLang)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunNumber)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunSum)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunFloor)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunCeiling)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DEFINE_FUNCTION_CREATOR(FunRound)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#undef DEFINE_FUNCTION_CREATOR
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline Interval::Interval()
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_min(Inf), m_max(Inf)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline Interval::Interval(int value)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_min(value), m_max(value)
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline Interval::Interval(int min, int max)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_min(min), m_max(max)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool Interval::contains(int value) const
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_min == Inf && m_max == Inf)
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_min == Inf)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return value <= m_max;
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_max == Inf)
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return value >= m_min;
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return value >= m_min && value <= m_max;
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
294d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void Function::setArguments(WillBeHeapVector<OwnPtrWillBeMember<Expression> >& args)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!subExprCount());
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Some functions use context node as implicit argument, so when explicit arguments are added, they may no longer be context node sensitive.
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_name != "lang" && !args.isEmpty())
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setIsContextNodeSensitive(false);
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
302d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WillBeHeapVector<OwnPtrWillBeMember<Expression> >::iterator end = args.end();
303d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for (WillBeHeapVector<OwnPtrWillBeMember<Expression> >::iterator it = args.begin(); it != end; ++it)
304bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        addSubExpression(it->release());
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
307197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunLast::evaluate(EvaluationContext& context) const
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
309197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return context.size;
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
312197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunPosition::evaluate(EvaluationContext& context) const
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
314197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return context.position;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
317197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunId::evaluate(EvaluationContext& context) const
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
319197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Value a = arg(0)->evaluate(context);
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder idList; // A whitespace-separated list of IDs
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (a.isNodeSet()) {
323197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        const NodeSet& nodes = a.toNodeSet(&context);
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < nodes.size(); ++i) {
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String str = stringValue(nodes[i]);
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            idList.append(str);
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            idList.append(' ');
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String str = a.toString();
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        idList.append(str);
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
33302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
334197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TreeScope& contextScope = context.node->treeScope();
335d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtrWillBeRawPtr<NodeSet> result(NodeSet::create());
336197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    WillBeHeapHashSet<RawPtrWillBeMember<Node> > resultSet;
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned startPos = 0;
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned length = idList.length();
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (true) {
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (startPos < length && isWhitespace(idList[startPos]))
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++startPos;
34302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (startPos == length)
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t endPos = startPos;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (endPos < length && !isWhitespace(idList[endPos]))
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++endPos;
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If there are several nodes with the same id, id() should return the first one.
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In WebKit, getElementById behaves so, too, although its behavior in this case is formally undefined.
35309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Node* node = contextScope.getElementById(AtomicString(idList.substring(startPos, endPos - startPos)));
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (node && resultSet.add(node).isNewEntry)
355d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            result->append(node);
35602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        startPos = endPos;
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
35902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
360d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    result->markSorted(false);
36102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
362d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return Value(result.release(), Value::adopt);
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline String expandedNameLocalPart(Node* node)
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The local part of an XPath expanded-name matches DOM local name for most node types, except for namespace nodes and processing instruction nodes.
36809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // But note that Blink does not support namespace nodes.
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
3708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return toProcessingInstruction(node)->target();
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node->localName().string();
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline String expandedName(Node* node)
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
37609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    AtomicString prefix;
37709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
37809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    switch (node->nodeType()) {
37909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case Node::ELEMENT_NODE:
38009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        prefix = toElement(node)->prefix();
38109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
38209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case Node::ATTRIBUTE_NODE:
38309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        prefix = toAttr(node)->prefix();
38409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
38509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    default:
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
38709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
38809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return prefix.isEmpty() ? expandedNameLocalPart(node) : prefix + ":" + expandedNameLocalPart(node);
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
392197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunLocalName::evaluate(EvaluationContext& context) const
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (argCount() > 0) {
395197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Value a = arg(0)->evaluate(context);
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!a.isNodeSet())
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return "";
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
399197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Node* node = a.toNodeSet(&context).firstNode();
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return node ? expandedNameLocalPart(node) : "";
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
403197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return expandedNameLocalPart(context.node.get());
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
406197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunNamespaceURI::evaluate(EvaluationContext& context) const
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (argCount() > 0) {
409197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Value a = arg(0)->evaluate(context);
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!a.isNodeSet())
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return "";
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
413197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Node* node = a.toNodeSet(&context).firstNode();
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return node ? node->namespaceURI().string() : "";
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
417197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return context.node->namespaceURI().string();
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
420197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunName::evaluate(EvaluationContext& context) const
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (argCount() > 0) {
423197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Value a = arg(0)->evaluate(context);
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!a.isNodeSet())
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return "";
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
427197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Node* node = a.toNodeSet(&context).firstNode();
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return node ? expandedName(node) : "";
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
431197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return expandedName(context.node.get());
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
434197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunCount::evaluate(EvaluationContext& context) const
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
436197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Value a = arg(0)->evaluate(context);
43702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
438197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return double(a.toNodeSet(&context).size());
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
441197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunString::evaluate(EvaluationContext& context) const
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!argCount())
444197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Value(context.node.get()).toString();
445197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return arg(0)->evaluate(context).toString();
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
448197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunConcat::evaluate(EvaluationContext& context) const
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.reserveCapacity(1024);
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned count = argCount();
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < count; ++i) {
455197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        String str(arg(i)->evaluate(context).toString());
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(str);
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.toString();
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
462197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunStartsWith::evaluate(EvaluationContext& context) const
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
464197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s1 = arg(0)->evaluate(context).toString();
465197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s2 = arg(1)->evaluate(context).toString();
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (s2.isEmpty())
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return s1.startsWith(s2);
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
473197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunContains::evaluate(EvaluationContext& context) const
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
475197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s1 = arg(0)->evaluate(context).toString();
476197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s2 = arg(1)->evaluate(context).toString();
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
47802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    if (s2.isEmpty())
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return s1.contains(s2) != 0;
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
484197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunSubstringBefore::evaluate(EvaluationContext& context) const
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
486197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s1 = arg(0)->evaluate(context).toString();
487197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s2 = arg(1)->evaluate(context).toString();
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (s2.isEmpty())
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t i = s1.find(s2);
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
49406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (i == kNotFound)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return s1.left(i);
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
500197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunSubstringAfter::evaluate(EvaluationContext& context) const
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
502197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s1 = arg(0)->evaluate(context).toString();
503197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s2 = arg(1)->evaluate(context).toString();
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t i = s1.find(s2);
50606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (i == kNotFound)
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return s1.substring(i + s2.length());
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
512197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunSubstring::evaluate(EvaluationContext& context) const
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
514197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s = arg(0)->evaluate(context).toString();
515197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    double doublePos = arg(1)->evaluate(context).toNumber();
516926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (std::isnan(doublePos))
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    long pos = static_cast<long>(FunRound::round(doublePos));
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool haveLength = argCount() == 3;
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    long len = -1;
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (haveLength) {
522197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        double doubleLen = arg(2)->evaluate(context).toNumber();
523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (std::isnan(doubleLen))
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return "";
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        len = static_cast<long>(FunRound::round(doubleLen));
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
52802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    if (pos > long(s.length()))
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (pos < 1) {
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (haveLength) {
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            len -= 1 - pos;
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (len < 1)
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return "";
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pos = 1;
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return s.substring(pos - 1, len);
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
543197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunStringLength::evaluate(EvaluationContext& context) const
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!argCount())
546197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Value(context.node.get()).toString().length();
547197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return arg(0)->evaluate(context).toString().length();
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
550197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunNormalizeSpace::evaluate(EvaluationContext& context) const
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!argCount()) {
553197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        String s = Value(context.node.get()).toString();
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return s.simplifyWhiteSpace();
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
557197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s = arg(0)->evaluate(context).toString();
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return s.simplifyWhiteSpace();
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
561197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunTranslate::evaluate(EvaluationContext& context) const
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
563197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s1 = arg(0)->evaluate(context).toString();
564197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s2 = arg(1)->evaluate(context).toString();
565197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String s3 = arg(2)->evaluate(context).toString();
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i1 = 0; i1 < s1.length(); ++i1) {
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        UChar ch = s1[i1];
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t i2 = s2.find(ch);
57102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
57206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (i2 == kNotFound)
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.append(ch);
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (i2 < s3.length())
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.append(s3[i2]);
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.toString();
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
581197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunBoolean::evaluate(EvaluationContext& context) const
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
583197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return arg(0)->evaluate(context).toBoolean();
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
586197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunNot::evaluate(EvaluationContext& context) const
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
588197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return !arg(0)->evaluate(context).toBoolean();
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
591197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunTrue::evaluate(EvaluationContext&) const
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
596197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunLang::evaluate(EvaluationContext& context) const
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
598197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String lang = arg(0)->evaluate(context).toString();
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Attribute* languageAttribute = 0;
601197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Node* node = context.node.get();
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (node) {
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (node->isElementNode()) {
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            Element* element = toElement(node);
605c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            languageAttribute = element->attributes().find(XMLNames::langAttr);
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (languageAttribute)
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        node = node->parentNode();
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!languageAttribute)
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String langValue = languageAttribute->value();
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (true) {
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (equalIgnoringCase(langValue, lang))
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Remove suffixes one by one.
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t index = langValue.reverseFind('-');
62206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (index == kNotFound)
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        langValue = langValue.left(index);
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
630197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunFalse::evaluate(EvaluationContext&) const
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunNumber::evaluate(EvaluationContext& context) const
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!argCount())
638197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Value(context.node.get()).toNumber();
639197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return arg(0)->evaluate(context).toNumber();
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
642197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunSum::evaluate(EvaluationContext& context) const
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
644197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Value a = arg(0)->evaluate(context);
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!a.isNodeSet())
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0.0;
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double sum = 0.0;
649197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const NodeSet& nodes = a.toNodeSet(&context);
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // To be really compliant, we should sort the node-set, as floating point addition is not associative.
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // However, this is unlikely to ever become a practical issue, and sorting is slow.
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < nodes.size(); i++)
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        sum += Value(stringValue(nodes[i])).toNumber();
65502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return sum;
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
659197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunFloor::evaluate(EvaluationContext& context) const
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
661197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return floor(arg(0)->evaluate(context).toNumber());
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
664197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunCeiling::evaluate(EvaluationContext& context) const
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
666197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return ceil(arg(0)->evaluate(context).toNumber());
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double FunRound::round(double val)
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!std::isnan(val) && !std::isinf(val)) {
672926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (std::signbit(val) && val >= -0.5)
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            val *= 0; // negative zero
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            val = floor(val + 0.5);
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return val;
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
680197021e6b966cfb06891637935ef33fff06433d1Ben MurdochValue FunRound::evaluate(EvaluationContext& context) const
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
682197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return round(arg(0)->evaluate(context).toNumber());
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct FunctionMapping {
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const char* name;
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FunctionRec function;
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void createFunctionMap()
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static const FunctionMapping functions[] = {
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "boolean", { &createFunBoolean, 1 } },
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "ceiling", { &createFunCeiling, 1 } },
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "concat", { &createFunConcat, Interval(2, Interval::Inf) } },
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "contains", { &createFunContains, 2 } },
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "count", { &createFunCount, 1 } },
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "false", { &createFunFalse, 0 } },
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "floor", { &createFunFloor, 1 } },
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "id", { &createFunId, 1 } },
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "lang", { &createFunLang, 1 } },
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "last", { &createFunLast, 0 } },
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "local-name", { &createFunLocalName, Interval(0, 1) } },
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "name", { &createFunName, Interval(0, 1) } },
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "namespace-uri", { &createFunNamespaceURI, Interval(0, 1) } },
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "normalize-space", { &createFunNormalizeSpace, Interval(0, 1) } },
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "not", { &createFunNot, 1 } },
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "number", { &createFunNumber, Interval(0, 1) } },
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "position", { &createFunPosition, 0 } },
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "round", { &createFunRound, 1 } },
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "starts-with", { &createFunStartsWith, 2 } },
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "string", { &createFunString, Interval(0, 1) } },
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "string-length", { &createFunStringLength, Interval(0, 1) } },
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "substring", { &createFunSubstring, Interval(2, 3) } },
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "substring-after", { &createFunSubstringAfter, 2 } },
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "substring-before", { &createFunSubstringBefore, 2 } },
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "sum", { &createFunSum, 1 } },
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "translate", { &createFunTranslate, 3 } },
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        { "true", { &createFunTrue, 0 } },
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    functionMap = new HashMap<String, FunctionRec>;
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < WTF_ARRAY_LENGTH(functions); ++i)
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        functionMap->set(functions[i].name, functions[i].function);
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
727bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
728bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)Function* createFunction(const String& name)
729bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){
730d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WillBeHeapVector<OwnPtrWillBeMember<Expression> > args;
731bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return createFunction(name, args);
732bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}
733bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
734d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)Function* createFunction(const String& name, WillBeHeapVector<OwnPtrWillBeMember<Expression> >& args)
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!functionMap)
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        createFunctionMap();
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashMap<String, FunctionRec>::iterator functionMapIter = functionMap->find(name);
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FunctionRec* functionRec = 0;
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (functionMapIter == functionMap->end() || !(functionRec = &functionMapIter->value)->args.contains(args.size()))
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Function* function = functionRec->factoryFn();
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function->setArguments(args);
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function->setName(name);
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return function;
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
753