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