コード例 #1
0
ファイル: XPathFunctions.cpp プロジェクト: 13W/phantomjs
Value FunStartsWith::evaluate() const
{
    String s1 = arg(0)->evaluate().toString();
    String s2 = arg(1)->evaluate().toString();

    if (s2.isEmpty())
        return BOOL_TO_VALUE_CAST true;

    return BOOL_TO_VALUE_CAST (s1.startsWith(s2));
}
コード例 #2
0
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 BOOL_TO_VALUE_CAST lhsBool;

    return BOOL_TO_VALUE_CAST (subExpr(1)->evaluate().toBoolean());
}
コード例 #3
0
ファイル: XPathFunctions.cpp プロジェクト: 13W/phantomjs
Value FunNot::evaluate() const
{
    return BOOL_TO_VALUE_CAST (!arg(0)->evaluate().toBoolean());
}
コード例 #4
0
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(BOOL_TO_VALUE_CAST (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, BOOL_TO_VALUE_CAST (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;
}