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

📄 ustring.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            d[0] = c;            m_rep = Rep::create(d, 1);            m_rep->baseString()->capacity = newCapacity;        }    } else if (m_rep == base && m_rep->rc == 1) {        // this is direct and has refcount of 1 (so we can just alter it directly)        expandCapacity(thisOffset + length + 1);        UChar* d = m_rep->data();        if (d) {            d[length] = c;            m_rep->len = length + 1;            m_rep->_hash = 0;        }    } else if (thisOffset + length == base->usedCapacity && length >= minShareSize) {        // this reaches the end of the string - extend it and share        expandCapacity(thisOffset + length + 1);        UChar* d = m_rep->data();        if (d) {            d[length] = c;            m_rep = Rep::create(m_rep, 0, length + 1);        }    } else {        // this is shared with someone using more capacity, gotta make a whole new string        size_t newCapacity = expandedSize(length + 1, 0);        UChar* d = allocChars(newCapacity);        if (!d)            makeNull();        else {            copyChars(d, data(), length);            d[length] = c;            m_rep = Rep::create(d, length + 1);            m_rep->baseString()->capacity = newCapacity;        }    }    m_rep->checkConsistency();    return *this;}bool UString::getCString(CStringBuffer& buffer) const{    int length = size();    int neededSize = length + 1;    buffer.resize(neededSize);    char* buf = buffer.data();    UChar ored = 0;    const UChar* p = data();    char* q = buf;    const UChar* limit = p + length;    while (p != limit) {        UChar c = p[0];        ored |= c;        *q = static_cast<char>(c);        ++p;        ++q;    }    *q = '\0';    return !(ored & 0xFF00);}char* UString::ascii() const{    int length = size();    int neededSize = length + 1;    delete[] statBuffer;    statBuffer = new char[neededSize];    const UChar* p = data();    char* q = statBuffer;    const UChar* limit = p + length;    while (p != limit) {        *q = static_cast<char>(p[0]);        ++p;        ++q;    }    *q = '\0';    return statBuffer;}UString& UString::operator=(const char* c){    if (!c) {        m_rep = &Rep::null();        return *this;    }    if (!c[0]) {        m_rep = &Rep::empty();        return *this;    }    int l = static_cast<int>(strlen(c));    UChar* d;    BaseString* base = m_rep->baseString();    if (m_rep->rc == 1 && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {        d = base->buf;        m_rep->_hash = 0;        m_rep->len = l;    } else {        d = allocChars(l);        if (!d) {            makeNull();            return *this;        }        m_rep = Rep::create(d, l);    }    for (int i = 0; i < l; i++)        d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend    return *this;}bool UString::is8Bit() const{    const UChar* u = data();    const UChar* limit = u + size();    while (u < limit) {        if (u[0] > 0xFF)            return false;        ++u;    }    return true;}UChar UString::operator[](int pos) const{    if (pos >= size())        return '\0';    return data()[pos];}double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const{    if (size() == 1) {        UChar c = data()[0];        if (isASCIIDigit(c))            return c - '0';        if (isASCIISpace(c) && tolerateEmptyString)            return 0;        return NaN;    }    // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk    // after the number, so this is too strict a check.    CStringBuffer s;    if (!getCString(s))        return NaN;    const char* c = s.data();    // skip leading white space    while (isASCIISpace(*c))        c++;    // empty string ?    if (*c == '\0')        return tolerateEmptyString ? 0.0 : NaN;    double d;    // hex number ?    if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) {        const char* firstDigitPosition = c + 2;        c++;        d = 0.0;        while (*(++c)) {            if (*c >= '0' && *c <= '9')                d = d * 16.0 + *c - '0';            else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))                d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;            else                break;        }        if (d >= mantissaOverflowLowerBound)            d = parseIntOverflow(firstDigitPosition, c - firstDigitPosition, 16);    } else {        // regular number ?        char* end;        d = WTF::strtod(c, &end);        if ((d != 0.0 || end != c) && d != Inf && d != -Inf) {            c = end;        } else {            double sign = 1.0;            if (*c == '+')                c++;            else if (*c == '-') {                sign = -1.0;                c++;            }            // We used strtod() to do the conversion. However, strtod() handles            // infinite values slightly differently than JavaScript in that it            // converts the string "inf" with any capitalization to infinity,            // whereas the ECMA spec requires that it be converted to NaN.            if (c[0] == 'I' && c[1] == 'n' && c[2] == 'f' && c[3] == 'i' && c[4] == 'n' && c[5] == 'i' && c[6] == 't' && c[7] == 'y') {                d = sign * Inf;                c += 8;            } else if ((d == Inf || d == -Inf) && *c != 'I' && *c != 'i')                c = end;            else                return NaN;        }    }    // allow trailing white space    while (isASCIISpace(*c))        c++;    // don't allow anything after - unless tolerant=true    if (!tolerateTrailingJunk && *c != '\0')        d = NaN;    return d;}double UString::toDouble(bool tolerateTrailingJunk) const{    return toDouble(tolerateTrailingJunk, true);}double UString::toDouble() const{    return toDouble(false, true);}uint32_t UString::toUInt32(bool* ok) const{    double d = toDouble();    bool b = true;    if (d != static_cast<uint32_t>(d)) {        b = false;        d = 0;    }    if (ok)        *ok = b;    return static_cast<uint32_t>(d);}uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const{    double d = toDouble(false, tolerateEmptyString);    bool b = true;    if (d != static_cast<uint32_t>(d)) {        b = false;        d = 0;    }    if (ok)        *ok = b;    return static_cast<uint32_t>(d);}uint32_t UString::toStrictUInt32(bool* ok) const{    if (ok)        *ok = false;    // Empty string is not OK.    int len = m_rep->len;    if (len == 0)        return 0;    const UChar* p = m_rep->data();    unsigned short c = p[0];    // If the first digit is 0, only 0 itself is OK.    if (c == '0') {        if (len == 1 && ok)            *ok = true;        return 0;    }    // Convert to UInt32, checking for overflow.    uint32_t i = 0;    while (1) {        // Process character, turning it into a digit.        if (c < '0' || c > '9')            return 0;        const unsigned d = c - '0';        // Multiply by 10, checking for overflow out of 32 bits.        if (i > 0xFFFFFFFFU / 10)            return 0;        i *= 10;        // Add in the digit, checking for overflow out of 32 bits.        const unsigned max = 0xFFFFFFFFU - d;        if (i > max)            return 0;        i += d;        // Handle end of string.        if (--len == 0) {            if (ok)                *ok = true;            return i;        }        // Get next character.        c = *(++p);    }}int UString::find(const UString& f, int pos) const{    int fsz = f.size();    if (pos < 0)        pos = 0;    if (fsz == 1) {        UChar ch = f[0];        const UChar* end = data() + size();        for (const UChar* c = data() + pos; c < end; c++) {            if (*c == ch)                return static_cast<int>(c - data());        }        return -1;    }    int sz = size();    if (sz < fsz)        return -1;    if (fsz == 0)        return pos;    const UChar* end = data() + sz - fsz;    int fsizeminusone = (fsz - 1) * sizeof(UChar);    const UChar* fdata = f.data();    unsigned short fchar = fdata[0];    ++fdata;    for (const UChar* c = data() + pos; c <= end; c++) {        if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))            return static_cast<int>(c - data());    }    return -1;}int UString::find(UChar ch, int pos) const{    if (pos < 0)        pos = 0;    const UChar* end = data() + size();    for (const UChar* c = data() + pos; c < end; c++) {        if (*c == ch)            return static_cast<int>(c - data());    }        return -1;}int UString::rfind(const UString& f, int pos) const{    int sz = size();    int fsz = f.size();    if (sz < fsz)        return -1;    if (pos < 0)        pos = 0;    if (pos > sz - fsz)        pos = sz - fsz;    if (fsz == 0)        return pos;    int fsizeminusone = (fsz - 1) * sizeof(UChar);    const UChar* fdata = f.data();    for (const UChar* c = data() + pos; c >= data(); c--) {        if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))            return static_cast<int>(c - data());    }    return -1;}int UString::rfind(UChar ch, int pos) const{    if (isEmpty())        return -1;    if (pos + 1 >= size())        pos = size() - 1;    for (const UChar* c = data() + pos; c >= data(); c--) {        if (*c == ch)            return static_cast<int>(c - data());    }    return -1;}UString UString::substr(int pos, int len) const{    int s = size();    if (pos < 0)        pos = 0;    else if (pos >= s)        pos = s;    if (len < 0)        len = s;    if (pos + len >= s)        len = s - pos;    if (pos == 0 && len == s)        return *this;    return UString(Rep::create(m_rep, pos, len));}bool operator==(const UString& s1, const UString& s2){    int size = s1.size();    switch (size) {        case 0:            return !s2.size();        case 1:            return s2.size() == 1 && s1.data()[0] == s2.data()[0];        default:            return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;    }}bool operator==(const UString& s1, const char *s2){    if (s2 == 0)        return s1.isEmpty();    const UChar* u = s1.data();    const UChar* uend = u + s1.size();    while (u != uend && *s2) {        if (u[0] != (unsigned char)*s2)            return false;        s2++;        u++;    }    return u == uend && *s2 == 0;}bool operator<(const UString& s1, const UString& s2){    const int l1 = s1.size();    const int l2 = s2.size();    const int lmin = l1 < l2 ? l1 : l2;    const UChar* c1 = s1.data();    const UChar* c2 = s2.data();    int l = 0;    while (l < lmin && *c1 == *c2) {        c1++;        c2++;        l++;    }    if (l < lmin)        return (c1[0] < c2[0]);    return (l1 < l2);}bool operator>(const UString& s1, const UString& s2){    const int l1 = s1.size();    const int l2 = s2.size();    const int lmin = l1 < l2 ? l1 : l2;    const UChar* c1 = s1.data();    const UChar* c2 = s2.data();    int l = 0;    while (l < lmin && *c1 == *c2) {        c1++;        c2++;        l++;    }    if (l < lmin)        return (c1[0] > c2[0]);    return (l1 > l2);}int compare(const UString& s1, const UString& s2){    const int l1 = s1.size();    const int l2 = s2.size();    const int lmin = l1 < l2 ? l1 : l2;    const UChar* c1 = s1.data();    const UChar* c2 = s2.data();    int l = 0;    while (l < lmin && *c1 == *c2) {        c1++;        c2++;        l++;    }    if (l < lmin)        return (c1[0] > c2[0]) ? 1 : -1;    if (l1 == l2)        return 0;    return (l1 > l2) ? 1 : -1;}bool equal(const UString::Rep* r, const UString::Rep* b){    int length = r->len;    if (length != b->len)        return false;    const UChar* d = r->data();    const UChar* s = b->data();    for (int i = 0; i != length; ++i) {        if (d[i] != s[i])            return false;    }    return true;}CString UString::UTF8String(bool strict) const{    // Allocate a buffer big enough to hold all the characters.    const int length = size();    Vector<char, 1024> buffer(length * 3);    // Convert to runs of 8-bit characters.    char* p = buffer.data();    const UChar* d = reinterpret_cast<const UChar*>(&data()[0]);    ConversionResult result = convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size(), strict);    if (result != conversionOK)        return CString();    return CString(buffer.data(), p - buffer.data());}// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.NEVER_INLINE void UString::makeNull(){    m_rep = &Rep::null();}// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.NEVER_INLINE UString::Rep* UString::nullRep(){    return &Rep::null();}} // namespace JSC

⌨️ 快捷键说明

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