JSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    int len = s.size();

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);

    double start = a0.toNumber(exec);
    double end = a1.toNumber(exec);
    if (isnan(start))
        start = 0;
    if (isnan(end))
        end = 0;
    if (start < 0)
        start = 0;
    if (end < 0)
        end = 0;
    if (start > len)
        start = len;
    if (end > len)
        end = len;
    if (a1.isUndefined())
        end = len;
    if (start > end) {
        double temp = end;
        end = start;
        start = temp;
    }
    return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(end) - static_cast<unsigned>(start));
}
JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    JSValue a0 = args.at(0);
    UString linkText = a0.toString(exec);

    unsigned linkTextSize = linkText.size();
    unsigned stringSize = s.size();
    unsigned bufferSize = 15 + linkTextSize + stringSize;
    UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
    if (!buffer)
        return jsUndefined();
    buffer[0] = '<';
    buffer[1] = 'a';
    buffer[2] = ' ';
    buffer[3] = 'h';
    buffer[4] = 'r';
    buffer[5] = 'e';
    buffer[6] = 'f';
    buffer[7] = '=';
    buffer[8] = '"';
    memcpy(&buffer[9], linkText.data(), linkTextSize * sizeof(UChar));
    buffer[9 + linkTextSize] = '"';
    buffer[10 + linkTextSize] = '>';
    memcpy(&buffer[11 + linkTextSize], s.data(), stringSize * sizeof(UChar));
    buffer[11 + linkTextSize + stringSize] = '<';
    buffer[12 + linkTextSize + stringSize] = '/';
    buffer[13 + linkTextSize + stringSize] = 'a';
    buffer[14 + linkTextSize + stringSize] = '>';
    return jsNontrivialString(exec, UString(buffer, bufferSize, false));
}
JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    if (args.size() < 1)
      return jsNumber(exec, 0);

    UString s = thisValue.toThisString(exec);
    JSValue a0 = args.at(0);
    return jsNumber(exec, localeCompare(s, a0.toString(exec)));
}
JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);

    ArgList::const_iterator end = args.end();
    for (ArgList::const_iterator it = args.begin(); it != end; ++it)
        s += (*it).toString(exec);
    return jsString(exec, s);
}
JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);

    JSValue a0 = args.at(0);

    UString u = s;
    RefPtr<RegExp> reg;
    RegExpObject* imp = 0;
    if (a0.isObject(&RegExpObject::info))
        reg = asRegExpObject(a0)->regExp();
    else {
        /*
         *  ECMA 15.5.4.12 String.prototype.search (regexp)
         *  If regexp is not an object whose [[Class]] property is "RegExp", it is
         *  replaced with the result of the expression new RegExp(regexp).
         */
        reg = RegExp::create(&exec->globalData(), a0.toString(exec));
    }
    RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
    int pos;
    int matchLength;
    regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
    if (!(reg->global())) {
        // case without 'g' flag is handled like RegExp.prototype.exec
        if (pos < 0)
            return jsNull();
        return regExpConstructor->arrayOfMatches(exec);
    }

    // return array of matches
    MarkedArgumentBuffer list;
    int lastIndex = 0;
    while (pos >= 0) {
        list.append(jsSubstring(exec, u, pos, matchLength));
        lastIndex = pos;
        pos += matchLength == 0 ? 1 : matchLength;
        regExpConstructor->performMatch(reg.get(), u, pos, pos, matchLength);
    }
    if (imp)
        imp->setLastIndex(lastIndex);
    if (list.isEmpty()) {
        // if there are no matches at all, it's important to return
        // Null instead of an empty array, because this matches
        // other browsers and because Null is a false value.
        return jsNull();
    }

    return constructArray(exec, list);
}
JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    int len = s.size();

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);

    UString u2 = a0.toString(exec);
    double dpos = a1.toIntegerPreserveNaN(exec);
    if (dpos < 0)
        dpos = 0;
    else if (!(dpos <= len)) // true for NaN
        dpos = len;
    return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
}
JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    unsigned len = s.size();
    JSValue a0 = args.at(0);
    if (a0.isUInt32Fast()) {
        uint32_t i = a0.getUInt32Fast();
        if (i < len)
            return jsSingleCharacterSubstring(exec, s, i);
        return jsEmptyString(exec);
    }
    double dpos = a0.toInteger(exec);
    if (dpos >= 0 && dpos < len)
        return jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos));
    return jsEmptyString(exec);
}
JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    unsigned len = s.size();
    JSValue a0 = args.at(0);
    if (a0.isUInt32Fast()) {
        uint32_t i = a0.getUInt32Fast();
        if (i < len)
            return jsNumber(exec, s.data()[i]);
        return jsNaN(exec);
    }
    double dpos = a0.toInteger(exec);
    if (dpos >= 0 && dpos < len)
        return jsNumber(exec, s[static_cast<int>(dpos)]);
    return jsNaN(exec);
}
JSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    int len = s.size();

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);

    double start = a0.toInteger(exec);
    double length = a1.isUndefined() ? len : a1.toInteger(exec);
    if (start >= len || length <= 0)
        return jsEmptyString(exec);
    if (start < 0) {
        start += len;
        if (start < 0)
            start = 0;
    }
    if (start + length > len)
        length = len - start;
    return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(length));
}
Example #10
0
JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    JSValue a0 = args.at(0);

    uint32_t smallInteger;
    if (a0.getUInt32(smallInteger) && smallInteger <= 9) {
        unsigned stringSize = s.size();
        unsigned bufferSize = 22 + stringSize;
        UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
        if (!buffer)
            return jsUndefined();
        buffer[0] = '<';
        buffer[1] = 'f';
        buffer[2] = 'o';
        buffer[3] = 'n';
        buffer[4] = 't';
        buffer[5] = ' ';
        buffer[6] = 's';
        buffer[7] = 'i';
        buffer[8] = 'z';
        buffer[9] = 'e';
        buffer[10] = '=';
        buffer[11] = '"';
        buffer[12] = '0' + smallInteger;
        buffer[13] = '"';
        buffer[14] = '>';
        memcpy(&buffer[15], s.data(), stringSize * sizeof(UChar));
        buffer[15 + stringSize] = '<';
        buffer[16 + stringSize] = '/';
        buffer[17 + stringSize] = 'f';
        buffer[18 + stringSize] = 'o';
        buffer[19 + stringSize] = 'n';
        buffer[20 + stringSize] = 't';
        buffer[21 + stringSize] = '>';
        return jsNontrivialString(exec, UString(buffer, bufferSize, false));
    }

    return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
}
Example #11
0
JSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    int len = s.size();

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);

    // The arg processing is very much like ArrayProtoFunc::Slice
    double start = a0.toInteger(exec);
    double end = a1.isUndefined() ? len : a1.toInteger(exec);
    double from = start < 0 ? len + start : start;
    double to = end < 0 ? len + end : end;
    if (to > from && to > 0 && from < len) {
        if (from < 0)
            from = 0;
        if (to > len)
            to = len;
        return jsSubstring(exec, s, static_cast<unsigned>(from), static_cast<unsigned>(to) - static_cast<unsigned>(from));
    }

    return jsEmptyString(exec);
}
Example #12
0
JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    int len = s.size();

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);
    UString u2 = a0.toString(exec);
    int pos;
    if (a1.isUndefined())
        pos = 0;
    else if (a1.isUInt32Fast())
        pos = min<uint32_t>(a1.getUInt32Fast(), len);
    else {
        double dpos = a1.toInteger(exec);
        if (dpos < 0)
            dpos = 0;
        else if (dpos > len)
            dpos = len;
        pos = static_cast<int>(dpos);
    }

    return jsNumber(exec, s.find(u2, pos));
}
Example #13
0
JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);

    JSValue a0 = args.at(0);

    UString u = s;
    RefPtr<RegExp> reg;
    if (a0.isObject(&RegExpObject::info))
        reg = asRegExpObject(a0)->regExp();
    else { 
        /*
         *  ECMA 15.5.4.12 String.prototype.search (regexp)
         *  If regexp is not an object whose [[Class]] property is "RegExp", it is
         *  replaced with the result of the expression new RegExp(regexp).
         */
        reg = RegExp::create(&exec->globalData(), a0.toString(exec));
    }
    RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
    int pos;
    int matchLength;
    regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
    return jsNumber(exec, pos);
}
Example #14
0
JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);

    JSArray* result = constructEmptyArray(exec);
    unsigned i = 0;
    int p0 = 0;
    unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
    if (a0.isObject(&RegExpObject::info)) {
        RegExp* reg = asRegExpObject(a0)->regExp();
        if (s.isEmpty() && reg->match(s, 0) >= 0) {
            // empty string matched by regexp -> empty array
            return result;
        }
        int pos = 0;
        while (i != limit && pos < s.size()) {
            OwnArrayPtr<int> ovector;
            int mpos = reg->match(s, pos, &ovector);
            if (mpos < 0)
                break;
            int mlen = ovector[1] - ovector[0];
            pos = mpos + (mlen == 0 ? 1 : mlen);
            if (mpos != p0 || mlen) {
                result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0));
                p0 = mpos + mlen;
            }
            for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) {
                int spos = ovector[si * 2];
                if (spos < 0)
                    result->put(exec, i++, jsUndefined());
                else
                    result->put(exec, i++, jsSubstring(exec, s, spos, ovector[si * 2 + 1] - spos));
            }
        }
    } else {
        UString u2 = a0.toString(exec);
        if (u2.isEmpty()) {
            if (s.isEmpty()) {
                // empty separator matches empty string -> empty array
                return result;
            }
            while (i != limit && p0 < s.size() - 1)
                result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++));
        } else {
            int pos;
            while (i != limit && (pos = s.find(u2, p0)) >= 0) {
                result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0));
                p0 = pos + u2.size();
            }
        }
    }

    // add remaining string
    if (i != limit)
        result->put(exec, i++, jsSubstring(exec, s, p0, s.size() - p0));

    return result;
}
Example #15
0
JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);
    JSValue a0 = args.at(0);
    return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
}
Example #16
0
JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
    UString s = thisValue.toThisString(exec);
    return jsNontrivialString(exec, "<sup>" + s + "</sup>");
}
Example #17
0
JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
    UString s = thisValue.toThisString(exec);
    return jsString(exec, "<tt>" + s + "</tt>");
}