diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /WebCore/xml/XPathPredicate.cpp | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_webkit-cad810f21b803229eb11403f9209855525a25d57.zip external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2 |
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'WebCore/xml/XPathPredicate.cpp')
-rw-r--r-- | WebCore/xml/XPathPredicate.cpp | 282 |
1 files changed, 0 insertions, 282 deletions
diff --git a/WebCore/xml/XPathPredicate.cpp b/WebCore/xml/XPathPredicate.cpp deleted file mode 100644 index 2a6482f..0000000 --- a/WebCore/xml/XPathPredicate.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2005 Frerich Raabe <raabe@kde.org> - * Copyright (C) 2006 Apple Computer, Inc. - * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(XPATH) - -#include "XPathPredicate.h" - -#include "Node.h" -#include "XPathFunctions.h" -#include "XPathUtil.h" -#include "XPathValue.h" -#include <math.h> -#include <wtf/MathExtras.h> - -namespace WebCore { -namespace XPath { - -Number::Number(double value) - : m_value(value) -{ -} - -Value Number::evaluate() const -{ - return m_value; -} - -StringExpression::StringExpression(const String& value) - : m_value(value) -{ -} - -Value StringExpression::evaluate() const -{ - return m_value; -} - -Value Negative::evaluate() const -{ - Value p(subExpr(0)->evaluate()); - return -p.toNumber(); -} - -NumericOp::NumericOp(Opcode opcode, Expression* lhs, Expression* rhs) - : m_opcode(opcode) -{ - addSubExpression(lhs); - addSubExpression(rhs); -} - -Value NumericOp::evaluate() const -{ - Value lhs(subExpr(0)->evaluate()); - Value rhs(subExpr(1)->evaluate()); - - double leftVal = lhs.toNumber(); - double rightVal = rhs.toNumber(); - - switch (m_opcode) { - case OP_Add: - return leftVal + rightVal; - case OP_Sub: - return leftVal - rightVal; - case OP_Mul: - return leftVal * rightVal; - case OP_Div: - return leftVal / rightVal; - case OP_Mod: - return fmod(leftVal, rightVal); - } - ASSERT_NOT_REACHED(); - return 0.0; -} - -EqTestOp::EqTestOp(Opcode opcode, Expression* lhs, Expression* rhs) - : m_opcode(opcode) -{ - addSubExpression(lhs); - addSubExpression(rhs); -} - -bool EqTestOp::compare(const Value& lhs, const Value& rhs) const -{ - if (lhs.isNodeSet()) { - const NodeSet& lhsSet = lhs.toNodeSet(); - if (rhs.isNodeSet()) { - // If both objects to be compared are node-sets, then the comparison will be true if and only if - // there is a node in the first node-set and a node in the second node-set such that the result of - // performing the comparison on the string-values of the two nodes is true. - const NodeSet& rhsSet = rhs.toNodeSet(); - for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) - for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) - if (compare(stringValue(lhsSet[lindex]), stringValue(rhsSet[rindex]))) - return true; - return false; - } - if (rhs.isNumber()) { - // If one object to be compared is a node-set and the other is a number, then the comparison will be true - // if and only if there is a node in the node-set such that the result of performing the comparison on the number - // to be compared and on the result of converting the string-value of that node to a number using the number function is true. - for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) - if (compare(Value(stringValue(lhsSet[lindex])).toNumber(), rhs)) - return true; - return false; - } - if (rhs.isString()) { - // If one object to be compared is a node-set and the other is a string, then the comparison will be true - // if and only if there is a node in the node-set such that the result of performing the comparison on - // the string-value of the node and the other string is true. - for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) - if (compare(stringValue(lhsSet[lindex]), rhs)) - return true; - return false; - } - if (rhs.isBoolean()) { - // If one object to be compared is a node-set and the other is a boolean, then the comparison will be true - // if and only if the result of performing the comparison on the boolean and on the result of converting - // the node-set to a boolean using the boolean function is true. - return compare(lhs.toBoolean(), rhs); - } - ASSERT(0); - } - if (rhs.isNodeSet()) { - const NodeSet& rhsSet = rhs.toNodeSet(); - if (lhs.isNumber()) { - for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) - if (compare(lhs, Value(stringValue(rhsSet[rindex])).toNumber())) - return true; - return false; - } - if (lhs.isString()) { - for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) - if (compare(lhs, stringValue(rhsSet[rindex]))) - return true; - return false; - } - if (lhs.isBoolean()) - return compare(lhs, rhs.toBoolean()); - ASSERT(0); - } - - // Neither side is a NodeSet. - switch (m_opcode) { - case OP_EQ: - case OP_NE: - bool equal; - if (lhs.isBoolean() || rhs.isBoolean()) - equal = lhs.toBoolean() == rhs.toBoolean(); - else if (lhs.isNumber() || rhs.isNumber()) - equal = lhs.toNumber() == rhs.toNumber(); - else - equal = lhs.toString() == rhs.toString(); - - if (m_opcode == OP_EQ) - return equal; - return !equal; - case OP_GT: - return lhs.toNumber() > rhs.toNumber(); - case OP_GE: - return lhs.toNumber() >= rhs.toNumber(); - case OP_LT: - return lhs.toNumber() < rhs.toNumber(); - case OP_LE: - return lhs.toNumber() <= rhs.toNumber(); - } - ASSERT(0); - return false; -} - -Value EqTestOp::evaluate() const -{ - Value lhs(subExpr(0)->evaluate()); - Value rhs(subExpr(1)->evaluate()); - - return compare(lhs, rhs); -} - -LogicalOp::LogicalOp(Opcode opcode, Expression* lhs, Expression* rhs) - : m_opcode(opcode) -{ - addSubExpression(lhs); - addSubExpression(rhs); -} - -bool LogicalOp::shortCircuitOn() const -{ - if (m_opcode == OP_And) - return false; //false and foo - - return true; //true or bar -} - -Value LogicalOp::evaluate() const -{ - Value lhs(subExpr(0)->evaluate()); - - // This is not only an optimization, http://www.w3.org/TR/xpath - // dictates that we must do short-circuit evaluation - bool lhsBool = lhs.toBoolean(); - if (lhsBool == shortCircuitOn()) - return lhsBool; - - return subExpr(1)->evaluate().toBoolean(); -} - -Value Union::evaluate() const -{ - Value lhsResult = subExpr(0)->evaluate(); - Value rhs = subExpr(1)->evaluate(); - - NodeSet& resultSet = lhsResult.modifiableNodeSet(); - const NodeSet& rhsNodes = rhs.toNodeSet(); - - HashSet<Node*> nodes; - for (size_t i = 0; i < resultSet.size(); ++i) - nodes.add(resultSet[i]); - - for (size_t i = 0; i < rhsNodes.size(); ++i) { - Node* node = rhsNodes[i]; - if (nodes.add(node).second) - resultSet.append(node); - } - - // It is also possible to use merge sort to avoid making the result unsorted; - // but this would waste the time in cases when order is not important. - resultSet.markSorted(false); - return lhsResult; -} - -Predicate::Predicate(Expression* expr) - : m_expr(expr) -{ -} - -Predicate::~Predicate() -{ - delete m_expr; -} - -bool Predicate::evaluate() const -{ - ASSERT(m_expr != 0); - - Value result(m_expr->evaluate()); - - // foo[3] means foo[position()=3] - if (result.isNumber()) - return EqTestOp(EqTestOp::OP_EQ, createFunction("position"), new Number(result.toNumber())).evaluate().toBoolean(); - - return result.toBoolean(); -} - -} -} - -#endif // ENABLE(XPATH) |