⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpathfunctions.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }    if (!node)        node = evaluationContext().node.get();    return node->namespaceURI().string();}Value FunName::evaluate() const{    Node* node = 0;    if (argCount() > 0) {        Value a = arg(0)->evaluate();        if (!a.isNodeSet())            return "";        node = a.toNodeSet().firstNode();        if (!node)            return "";    }    if (!node)        node = evaluationContext().node.get();    const AtomicString& prefix = node->prefix();    return prefix.isEmpty() ? node->localName().string() : prefix + ":" + node->localName();}Value FunCount::evaluate() const{    Value a = arg(0)->evaluate();        if (!a.isNodeSet())        return 0.0;        return double(a.toNodeSet().size());}Value FunString::evaluate() const{    if (!argCount())        return Value(Expression::evaluationContext().node.get()).toString();    return arg(0)->evaluate().toString();}Value FunConcat::evaluate() const{    Vector<UChar, 1024> result;    unsigned count = argCount();    for (unsigned i = 0; i < count; ++i) {        String str(arg(i)->evaluate().toString());        result.append(str.characters(), str.length());    }    return String(result.data(), result.size());}Value FunStartsWith::evaluate() const{    String s1 = arg(0)->evaluate().toString();    String s2 = arg(1)->evaluate().toString();    if (s2.isEmpty())        return true;    return s1.startsWith(s2);}Value FunContains::evaluate() const{    String s1 = arg(0)->evaluate().toString();    String s2 = arg(1)->evaluate().toString();    if (s2.isEmpty())         return true;    return s1.contains(s2) != 0;}Value FunSubstringBefore::evaluate() const{    String s1 = arg(0)->evaluate().toString();    String s2 = arg(1)->evaluate().toString();    if (s2.isEmpty())        return "";    int i = s1.find(s2);    if (i == -1)        return "";    return s1.left(i);}Value FunSubstringAfter::evaluate() const{    String s1 = arg(0)->evaluate().toString();    String s2 = arg(1)->evaluate().toString();    int i = s1.find(s2);    if (i == -1)        return "";    return s1.substring(i + s2.length());}Value FunSubstring::evaluate() const{    String s = arg(0)->evaluate().toString();    long pos = static_cast<long>(FunRound::round(arg(1)->evaluate().toNumber()));    bool haveLength = argCount() == 3;    long len = -1;    if (haveLength) {        double doubleLen = arg(2)->evaluate().toNumber();        if (isnan(doubleLen))            return "";        len = static_cast<long>(FunRound::round(doubleLen));    }    if (pos > long(s.length()))         return "";    if (haveLength && pos < 1) {        len -= 1 - pos;        pos = 1;        if (len < 1)            return "";    }    return s.substring(pos - 1, len);}Value FunStringLength::evaluate() const{    if (!argCount())        return Value(Expression::evaluationContext().node.get()).toString().length();    return arg(0)->evaluate().toString().length();}Value FunNormalizeSpace::evaluate() const{    if (!argCount()) {        String s = Value(Expression::evaluationContext().node.get()).toString();        return s.simplifyWhiteSpace();    }    String s = arg(0)->evaluate().toString();    return s.simplifyWhiteSpace();}Value FunTranslate::evaluate() const{    String s1 = arg(0)->evaluate().toString();    String s2 = arg(1)->evaluate().toString();    String s3 = arg(2)->evaluate().toString();    String newString;    // FIXME: Building a String a character at a time is quite slow.    for (unsigned i1 = 0; i1 < s1.length(); ++i1) {        UChar ch = s1[i1];        int i2 = s2.find(ch);                if (i2 == -1)            newString += String(&ch, 1);        else if ((unsigned)i2 < s3.length()) {            UChar c2 = s3[i2];            newString += String(&c2, 1);        }    }    return newString;}Value FunBoolean::evaluate() const{    return arg(0)->evaluate().toBoolean();}Value FunNot::evaluate() const{    return !arg(0)->evaluate().toBoolean();}Value FunTrue::evaluate() const{    return true;}Value FunLang::evaluate() const{    String lang = arg(0)->evaluate().toString();    Attribute* languageAttribute = 0;    Node* node = evaluationContext().node.get();    while (node) {        NamedAttrMap* attrs = node->attributes();        if (attrs)            languageAttribute = attrs->getAttributeItem(XMLNames::langAttr);        if (languageAttribute)            break;        node = node->parentNode();    }    if (!languageAttribute)        return false;    String langValue = languageAttribute->value();    while (true) {        if (equalIgnoringCase(langValue, lang))            return true;        // Remove suffixes one by one.        int index = langValue.reverseFind('-');        if (index == -1)            break;        langValue = langValue.left(index);    }    return false;}Value FunFalse::evaluate() const{    return false;}Value FunNumber::evaluate() const{    if (!argCount())        return Value(Expression::evaluationContext().node.get()).toNumber();    return arg(0)->evaluate().toNumber();}Value FunSum::evaluate() const{    Value a = arg(0)->evaluate();    if (!a.isNodeSet())        return 0.0;    double sum = 0.0;    const NodeSet& nodes = a.toNodeSet();    // To be really compliant, we should sort the node-set, as floating point addition is not associative.    // However, this is unlikely to ever become a practical issue, and sorting is slow.    for (unsigned i = 0; i < nodes.size(); i++)        sum += Value(stringValue(nodes[i])).toNumber();        return sum;}Value FunFloor::evaluate() const{    return floor(arg(0)->evaluate().toNumber());}Value FunCeiling::evaluate() const{    return ceil(arg(0)->evaluate().toNumber());}double FunRound::round(double val){    if (!isnan(val) && !isinf(val)) {        if (signbit(val) && val >= -0.5)            val *= 0; // negative zero        else            val = floor(val + 0.5);    }    return val;}Value FunRound::evaluate() const{    return round(arg(0)->evaluate().toNumber());}static void createFunctionMap(){    struct FunctionMapping {        const char *name;        FunctionRec function;    };    static const FunctionMapping functions[] = {        { "boolean", { &createFunBoolean, 1 } },        { "ceiling", { &createFunCeiling, 1 } },        { "concat", { &createFunConcat, Interval(2, Interval::Inf) } },        { "contains", { &createFunContains, 2 } },        { "count", { &createFunCount, 1 } },        { "false", { &createFunFalse, 0 } },        { "floor", { &createFunFloor, 1 } },        { "id", { &createFunId, 1 } },        { "lang", { &createFunLang, 1 } },        { "last", { &createFunLast, 0 } },        { "local-name", { &createFunLocalName, Interval(0, 1) } },        { "name", { &createFunName, Interval(0, 1) } },        { "namespace-uri", { &createFunNamespaceURI, Interval(0, 1) } },        { "normalize-space", { &createFunNormalizeSpace, Interval(0, 1) } },        { "not", { &createFunNot, 1 } },        { "number", { &createFunNumber, Interval(0, 1) } },        { "position", { &createFunPosition, 0 } },        { "round", { &createFunRound, 1 } },        { "starts-with", { &createFunStartsWith, 2 } },        { "string", { &createFunString, Interval(0, 1) } },        { "string-length", { &createFunStringLength, Interval(0, 1) } },        { "substring", { &createFunSubstring, Interval(2, 3) } },        { "substring-after", { &createFunSubstringAfter, 2 } },        { "substring-before", { &createFunSubstringBefore, 2 } },        { "sum", { &createFunSum, 1 } },        { "translate", { &createFunTranslate, 3 } },        { "true", { &createFunTrue, 0 } },    };    const unsigned int numFunctions = sizeof(functions) / sizeof(functions[0]);    functionMap = new HashMap<String, FunctionRec>;    for (unsigned i = 0; i < numFunctions; ++i)        functionMap->set(functions[i].name, functions[i].function);}Function* createFunction(const String& name, const Vector<Expression*>& args){    if (!functionMap)        createFunctionMap();    HashMap<String, FunctionRec>::iterator functionMapIter = functionMap->find(name);    FunctionRec* functionRec = 0;    if (functionMapIter == functionMap->end() || !(functionRec = &functionMapIter->second)->args.contains(args.size()))        return 0;    Function* function = functionRec->factoryFn();    function->setArguments(args);    function->setName(name);    return function;}}}#endif // ENABLE(XPATH)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -