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

📄 ustring.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    rep->checkConsistency();    int thisSize = rep->size();    int thisOffset = rep->offset;    int length = thisSize + tSize;    UString::BaseString* base = rep->baseString();    // possible cases:    if (tSize == 0) {        // t is empty    } else if (thisSize == 0) {        // this is empty        rep = UString::Rep::createCopying(tData, tSize);    } else if (rep == base && rep->rc == 1) {        // this is direct and has refcount of 1 (so we can just alter it directly)        if (!expandCapacity(rep.get(), thisOffset + length))            rep = &UString::Rep::null();        if (rep->data()) {            copyChars(rep->data() + thisSize, tData, tSize);            rep->len = length;            rep->_hash = 0;        }    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {        // this reaches the end of the buffer - extend it if it's long enough to append to        if (!expandCapacity(rep.get(), thisOffset + length))            rep = &UString::Rep::null();        if (rep->data()) {            copyChars(rep->data() + thisSize, tData, tSize);            rep = UString::Rep::create(rep, 0, length);        }    } else {        // this is shared with someone using more capacity, gotta make a whole new string        size_t newCapacity = expandedSize(length, 0);        UChar* d = allocChars(newCapacity);        if (!d)            rep = &UString::Rep::null();        else {            copyChars(d, rep->data(), thisSize);            copyChars(d + thisSize, tData, tSize);            rep = UString::Rep::create(d, length);            rep->baseString()->capacity = newCapacity;        }    }    rep->checkConsistency();    return rep.release();}static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const char* t){    RefPtr<UString::Rep> rep = r;    rep->checkConsistency();    int thisSize = rep->size();    int thisOffset = rep->offset;    int tSize = static_cast<int>(strlen(t));    int length = thisSize + tSize;    UString::BaseString* base = rep->baseString();    // possible cases:    if (thisSize == 0) {        // this is empty        rep = createRep(t);    } else if (tSize == 0) {        // t is empty, we'll just return *this below.    } else if (rep == base && rep->rc == 1) {        // this is direct and has refcount of 1 (so we can just alter it directly)        expandCapacity(rep.get(), thisOffset + length);        UChar* d = rep->data();        if (d) {            for (int i = 0; i < tSize; ++i)                d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend            rep->len = length;            rep->_hash = 0;        }    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {        // this string reaches the end of the buffer - extend it        expandCapacity(rep.get(), thisOffset + length);        UChar* d = rep->data();        if (d) {            for (int i = 0; i < tSize; ++i)                d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend            rep = UString::Rep::create(rep, 0, length);        }    } else {        // this is shared with someone using more capacity, gotta make a whole new string        size_t newCapacity = expandedSize(length, 0);        UChar* d = allocChars(newCapacity);        if (!d)            rep = &UString::Rep::null();        else {            copyChars(d, rep->data(), thisSize);            for (int i = 0; i < tSize; ++i)                d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend            rep = UString::Rep::create(d, length);            rep->baseString()->capacity = newCapacity;        }    }    rep->checkConsistency();    return rep.release();}PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b){    a->checkConsistency();    b->checkConsistency();    int aSize = a->size();    int aOffset = a->offset;    int bSize = b->size();    int bOffset = b->offset;    int length = aSize + bSize;    // possible cases:    // a is empty    if (aSize == 0)        return b;    // b is empty    if (bSize == 0)        return a;    UString::BaseString* aBase = a->baseString();    if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + length <= aBase->capacity) {        // b is a single character (common fast case)        aBase->usedCapacity = aOffset + length;        a->data()[aSize] = b->data()[0];        return UString::Rep::create(a, 0, length);    }    UString::BaseString* bBase = b->baseString();    if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize        && (-bOffset != bBase->usedPreCapacity || aSize >= bSize)) {        // - a reaches the end of its buffer so it qualifies for shared append        // - also, it's at least a quarter the length of b - appending to a much shorter        //   string does more harm than good        // - however, if b qualifies for prepend and is longer than a, we'd rather prepend        UString x(a);        x.expandCapacity(aOffset + length);        if (!a->data() || !x.data())            return 0;        copyChars(a->data() + aSize, b->data(), bSize);        PassRefPtr<UString::Rep> result = UString::Rep::create(a, 0, length);        a->checkConsistency();        b->checkConsistency();        result->checkConsistency();        return result;    }    if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {        // - b reaches the beginning of its buffer so it qualifies for shared prepend        // - also, it's at least a quarter the length of a - prepending to a much shorter        //   string does more harm than good        UString y(b);        y.expandPreCapacity(-bOffset + aSize);        if (!b->data() || !y.data())            return 0;        copyChars(b->data() - aSize, a->data(), aSize);        PassRefPtr<UString::Rep> result = UString::Rep::create(b, -aSize, length);        a->checkConsistency();        b->checkConsistency();        result->checkConsistency();        return result;    }    // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string    size_t newCapacity = expandedSize(length, 0);    UChar* d = allocChars(newCapacity);    if (!d)        return 0;    copyChars(d, a->data(), aSize);    copyChars(d + aSize, b->data(), bSize);    PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);    result->baseString()->capacity = newCapacity;    a->checkConsistency();    b->checkConsistency();    result->checkConsistency();    return result;}PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, int i){    UChar buf[1 + sizeof(i) * 3];    UChar* end = buf + sizeof(buf) / sizeof(UChar);    UChar* p = end;      if (i == 0)        *--p = '0';    else if (i == INT_MIN) {        char minBuf[1 + sizeof(i) * 3];        sprintf(minBuf, "%d", INT_MIN);        return concatenate(rep, minBuf);    } else {        bool negative = false;        if (i < 0) {            negative = true;            i = -i;        }        while (i) {            *--p = static_cast<unsigned short>((i % 10) + '0');            i /= 10;        }        if (negative)            *--p = '-';    }    return concatenate(rep, p, static_cast<int>(end - p));}PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d){    // avoid ever printing -NaN, in JS conceptually there is only one NaN value    if (isnan(d))        return concatenate(rep, "NaN");    if (d == 0.0) // stringify -0 as 0        d = 0.0;    char buf[80];    int decimalPoint;    int sign;    char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);    int length = static_cast<int>(strlen(result));      int i = 0;    if (sign)        buf[i++] = '-';      if (decimalPoint <= 0 && decimalPoint > -6) {        buf[i++] = '0';        buf[i++] = '.';        for (int j = decimalPoint; j < 0; j++)            buf[i++] = '0';        strcpy(buf + i, result);    } else if (decimalPoint <= 21 && decimalPoint > 0) {        if (length <= decimalPoint) {            strcpy(buf + i, result);            i += length;            for (int j = 0; j < decimalPoint - length; j++)                buf[i++] = '0';            buf[i] = '\0';        } else {            strncpy(buf + i, result, decimalPoint);            i += decimalPoint;            buf[i++] = '.';            strcpy(buf + i, result + decimalPoint);        }    } else if (result[0] < '0' || result[0] > '9')        strcpy(buf + i, result);    else {        buf[i++] = result[0];        if (length > 1) {            buf[i++] = '.';            strcpy(buf + i, result + 1);            i += length - 1;        }                buf[i++] = 'e';        buf[i++] = (decimalPoint >= 0) ? '+' : '-';        // decimalPoint can't be more than 3 digits decimal given the        // nature of float representation        int exponential = decimalPoint - 1;        if (exponential < 0)            exponential = -exponential;        if (exponential >= 100)            buf[i++] = static_cast<char>('0' + exponential / 100);        if (exponential >= 10)            buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);        buf[i++] = static_cast<char>('0' + exponential % 10);        buf[i++] = '\0';    }      WTF::freedtoa(result);  return concatenate(rep, buf);}UString UString::from(int i){    UChar buf[1 + sizeof(i) * 3];    UChar* end = buf + sizeof(buf) / sizeof(UChar);    UChar* p = end;      if (i == 0)        *--p = '0';    else if (i == INT_MIN) {        char minBuf[1 + sizeof(i) * 3];        sprintf(minBuf, "%d", INT_MIN);        return UString(minBuf);    } else {        bool negative = false;        if (i < 0) {            negative = true;            i = -i;        }        while (i) {            *--p = static_cast<unsigned short>((i % 10) + '0');            i /= 10;        }        if (negative)            *--p = '-';    }    return UString(p, static_cast<int>(end - p));}UString UString::from(unsigned int u){    UChar buf[sizeof(u) * 3];    UChar* end = buf + sizeof(buf) / sizeof(UChar);    UChar* p = end;        if (u == 0)        *--p = '0';    else {        while (u) {            *--p = static_cast<unsigned short>((u % 10) + '0');            u /= 10;        }    }        return UString(p, static_cast<int>(end - p));}UString UString::from(long l){    UChar buf[1 + sizeof(l) * 3];    UChar* end = buf + sizeof(buf) / sizeof(UChar);    UChar* p = end;    if (l == 0)        *--p = '0';    else if (l == LONG_MIN) {        char minBuf[1 + sizeof(l) * 3];        sprintf(minBuf, "%ld", LONG_MIN);        return UString(minBuf);    } else {        bool negative = false;        if (l < 0) {            negative = true;            l = -l;        }        while (l) {            *--p = static_cast<unsigned short>((l % 10) + '0');            l /= 10;        }        if (negative)            *--p = '-';    }    return UString(p, static_cast<int>(end - p));}UString UString::from(double d){    // avoid ever printing -NaN, in JS conceptually there is only one NaN value    if (isnan(d))        return "NaN";    char buf[80];    int decimalPoint;    int sign;    char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);    int length = static_cast<int>(strlen(result));      int i = 0;    if (sign)        buf[i++] = '-';      if (decimalPoint <= 0 && decimalPoint > -6) {        buf[i++] = '0';        buf[i++] = '.';        for (int j = decimalPoint; j < 0; j++)            buf[i++] = '0';        strcpy(buf + i, result);    } else if (decimalPoint <= 21 && decimalPoint > 0) {        if (length <= decimalPoint) {            strcpy(buf + i, result);            i += length;            for (int j = 0; j < decimalPoint - length; j++)                buf[i++] = '0';            buf[i] = '\0';        } else {            strncpy(buf + i, result, decimalPoint);            i += decimalPoint;            buf[i++] = '.';            strcpy(buf + i, result + decimalPoint);        }    } else if (result[0] < '0' || result[0] > '9')        strcpy(buf + i, result);    else {        buf[i++] = result[0];        if (length > 1) {            buf[i++] = '.';            strcpy(buf + i, result + 1);            i += length - 1;        }                buf[i++] = 'e';        buf[i++] = (decimalPoint >= 0) ? '+' : '-';        // decimalPoint can't be more than 3 digits decimal given the        // nature of float representation        int exponential = decimalPoint - 1;        if (exponential < 0)            exponential = -exponential;        if (exponential >= 100)            buf[i++] = static_cast<char>('0' + exponential / 100);        if (exponential >= 10)            buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);        buf[i++] = static_cast<char>('0' + exponential % 10);        buf[i++] = '\0';    }      WTF::freedtoa(result);  return UString(buf);}UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const{    m_rep->checkConsistency();    if (rangeCount == 1 && separatorCount == 0) {        int thisSize = size();        int position = substringRanges[0].position;        int length = substringRanges[0].length;        if (position <= 0 && length >= thisSize)            return *this;        return UString::Rep::create(m_rep, max(0, position), min(thisSize, length));    }    int totalLength = 0;    for (int i = 0; i < rangeCount; i++)        totalLength += substringRanges[i].length;    for (int i = 0; i < separatorCount; i++)        totalLength += separators[i].size();    if (totalLength == 0)        return "";    UChar* buffer = allocChars(totalLength);    if (!buffer)        return null();    int maxCount = max(rangeCount, separatorCount);    int bufferPos = 0;    for (int i = 0; i < maxCount; i++) {        if (i < rangeCount) {            copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);            bufferPos += substringRanges[i].length;        }        if (i < separatorCount) {            copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());            bufferPos += separators[i].size();        }    }    return UString::Rep::create(buffer, totalLength);}UString& UString::append(const UString &t){    m_rep->checkConsistency();    t.rep()->checkConsistency();    int thisSize = size();    int thisOffset = m_rep->offset;    int tSize = t.size();    int length = thisSize + tSize;    BaseString* base = m_rep->baseString();    // possible cases:    if (thisSize == 0) {        // this is empty        *this = t;    } else if (tSize == 0) {        // t is empty    } 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);        if (data()) {            copyChars(m_rep->data() + thisSize, t.data(), tSize);            m_rep->len = length;            m_rep->_hash = 0;        }    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {        // this reaches the end of the buffer - extend it if it's long enough to append to        expandCapacity(thisOffset + length);        if (data()) {            copyChars(m_rep->data() + thisSize, t.data(), tSize);            m_rep = Rep::create(m_rep, 0, length);        }    } else {        // this is shared with someone using more capacity, gotta make a whole new string        size_t newCapacity = expandedSize(length, 0);        UChar* d = allocChars(newCapacity);        if (!d)            makeNull();        else {            copyChars(d, data(), thisSize);            copyChars(d + thisSize, t.data(), tSize);            m_rep = Rep::create(d, length);            m_rep->baseString()->capacity = newCapacity;        }    }    m_rep->checkConsistency();    t.rep()->checkConsistency();    return *this;}UString& UString::append(const UChar* tData, int tSize){    m_rep = concatenate(m_rep.release(), tData, tSize);    return *this;}UString& UString::append(const char* t){    m_rep = concatenate(m_rep.release(), t);    return *this;}UString& UString::append(UChar c){    m_rep->checkConsistency();    int thisOffset = m_rep->offset;    int length = size();    BaseString* base = m_rep->baseString();    // possible cases:    if (length == 0) {        // this is empty - must make a new m_rep because we don't want to pollute the shared empty one         size_t newCapacity = expandedSize(1, 0);        UChar* d = allocChars(newCapacity);        if (!d)            makeNull();        else {

⌨️ 快捷键说明

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