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

📄 string.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            operator delete(_rep);            _rep = 0;        }        if (cstr._rep)        {            size_t n = strlen(cstr._rep) + 1;            _rep = (char*)operator new(n);            memcpy(_rep, cstr._rep, n);        }    }    return *this;}//==============================================================================//// class StringRep////==============================================================================StringRep StringRep::_emptyRep;inline StringRep* StringRep::alloc(size_t cap){    // Check for potential overflow in cap    PEGASUS_CHECK_CAPACITY_OVERFLOW(cap);    StringRep* rep = (StringRep*)::operator new(        sizeof(StringRep) + cap * sizeof(Uint16));    rep->cap = cap;    new(&rep->refs) AtomicInt(1);    return rep;}static inline void _reserve(StringRep*& rep, Uint32 cap){    if (cap > rep->cap || rep->refs.get() != 1)    {        size_t n = _roundUpToPow2(cap);        StringRep* newRep = StringRep::alloc(n);        newRep->size = rep->size;        _copy(newRep->data, rep->data, rep->size + 1);        StringRep::unref(rep);        rep = newRep;    }}StringRep* StringRep::create(const Uint16* data, size_t size){    StringRep* rep = StringRep::alloc(size);    rep->size = size;    _copy(rep->data, data, size);    rep->data[size] = '\0';    return rep;}StringRep* StringRep::copyOnWrite(StringRep* rep){    // Return a new copy of rep. Release rep.    StringRep* newRep = StringRep::alloc(rep->size);    newRep->size = rep->size;    _copy(newRep->data, rep->data, rep->size);    newRep->data[newRep->size] = '\0';    StringRep::unref(rep);    return newRep;}StringRep* StringRep::create(const char* data, size_t size){    StringRep* rep = StringRep::alloc(size);    size_t utf8_error_index;    rep->size = _convert((Uint16*)rep->data, data, size, utf8_error_index);    if (rep->size == size_t(-1))    {        StringRep::free(rep);        _StringThrowBadUTF8(utf8_error_index);    }    rep->data[rep->size] = '\0';    return rep;}Uint32 StringRep::length(const Uint16* str){    // Note: We could unroll this but it is rarely called.    const Uint16* end = (Uint16*)str;    while (*end++)        ;    return end - str - 1;}//==============================================================================//// class String////==============================================================================const String String::EMPTY;String::String(const String& str, Uint32 n){    _checkBounds(n, str._rep->size);    _rep = StringRep::create(str._rep->data, n);}String::String(const Char16* str){    _checkNullPointer(str);    _rep = StringRep::create((Uint16*)str, StringRep::length((Uint16*)str));}String::String(const Char16* str, Uint32 n){    _checkNullPointer(str);    _rep = StringRep::create((Uint16*)str, n);}String::String(const char* str){    _checkNullPointer(str);    // Set this just in case create() throws an exception.    _rep = &StringRep::_emptyRep;    _rep = StringRep::create(str, strlen(str));}String::String(const char* str, Uint32 n){    _checkNullPointer(str);    // Set this just in case create() throws an exception.    _rep = &StringRep::_emptyRep;    _rep = StringRep::create(str, n);}String::String(const String& s1, const String& s2){    size_t n1 = s1._rep->size;    size_t n2 = s2._rep->size;    size_t n = n1 + n2;    _rep = StringRep::alloc(n);    _copy(_rep->data, s1._rep->data, n1);    _copy(_rep->data + n1, s2._rep->data, n2);    _rep->size = n;    _rep->data[n] = '\0';}String::String(const String& s1, const char* s2){    _checkNullPointer(s2);    size_t n1 = s1._rep->size;    size_t n2 = strlen(s2);    _rep = StringRep::alloc(n1 + n2);    _copy(_rep->data, s1._rep->data, n1);    size_t utf8_error_index;    size_t tmp = _convert((Uint16*)_rep->data + n1, s2, n2, utf8_error_index);    if (tmp == size_t(-1))    {        StringRep::free(_rep);        _rep = &StringRep::_emptyRep;        _StringThrowBadUTF8(utf8_error_index);    }    _rep->size = n1 + tmp;    _rep->data[_rep->size] = '\0';}String::String(const char* s1, const String& s2){    _checkNullPointer(s1);    size_t n1 = strlen(s1);    size_t n2 = s2._rep->size;    _rep = StringRep::alloc(n1 + n2);    size_t utf8_error_index;    size_t tmp = _convert((Uint16*)_rep->data, s1, n1, utf8_error_index);    if (tmp ==  size_t(-1))    {        StringRep::free(_rep);        _rep = &StringRep::_emptyRep;        _StringThrowBadUTF8(utf8_error_index);    }    _rep->size = n2 + tmp;    _copy(_rep->data + n1, s2._rep->data, n2);    _rep->data[_rep->size] = '\0';}String& String::assign(const String& str){    if (_rep != str._rep)    {        StringRep::unref(_rep);        StringRep::ref(_rep = str._rep);    }    return *this;}String& String::assign(const Char16* str, Uint32 n){    _checkNullPointer(str);    if (n > _rep->cap || _rep->refs.get() != 1)    {        StringRep::unref(_rep);        _rep = StringRep::alloc(n);    }    _rep->size = n;    _copy(_rep->data, (Uint16*)str, n);    _rep->data[n] = '\0';    return *this;}String& String::assign(const char* str, Uint32 n){    _checkNullPointer(str);    if (n > _rep->cap || _rep->refs.get() != 1)    {        StringRep::unref(_rep);        _rep = StringRep::alloc(n);    }    size_t utf8_error_index;    _rep->size = _convert(_rep->data, str, n, utf8_error_index);    if (_rep->size ==  size_t(-1))    {        StringRep::free(_rep);        _rep = &StringRep::_emptyRep;        _StringThrowBadUTF8(utf8_error_index);    }    _rep->data[_rep->size] = 0;    return *this;}void String::clear(){    if (_rep->size)    {        if (_rep->refs.get() == 1)        {            _rep->size = 0;            _rep->data[0] = '\0';        }        else        {            StringRep::unref(_rep);            _rep = &StringRep::_emptyRep;        }    }}void String::reserveCapacity(Uint32 cap){    _reserve(_rep, cap);}CString String::getCString() const{    // A UTF8 string can have three times as many characters as its UTF16    // counterpart, so we allocate extra memory for the worst case. In the    // best case, we may need only one third of the memory allocated. But    // downsizing the string afterwards is expensive and unecessary since    // CString objects are usually short-lived (disappearing after only a few    // instructions). CString objects are typically created on the stack as    // means to obtain a char* pointer.#ifdef PEGASUS_STRING_NO_UTF8    char* str = (char*)operator new(_rep->size + 1);    _copy(str, _rep->data, _rep->size);    str[_rep->size] = '\0';    return CString(str);#else    Uint32 n = 3 * _rep->size;    char* str = (char*)operator new(n + 1);    size_t size = _copyToUTF8(str, _rep->data, _rep->size);    str[size] = '\0';    return CString(str);#endif}String& String::append(const Char16* str, Uint32 n){    _checkNullPointer(str);    size_t oldSize = _rep->size;    size_t newSize = oldSize + n;    _reserve(_rep, newSize);    _copy(_rep->data + oldSize, (Uint16*)str, n);    _rep->size = newSize;    _rep->data[newSize] = '\0';    return *this;}String& String::append(const String& str){    return append((Char16*)(&(str._rep->data[0])), str._rep->size);}String& String::append(const char* str, Uint32 size){    _checkNullPointer(str);    size_t oldSize = _rep->size;    size_t cap = oldSize + size;    _reserve(_rep, cap);    size_t utf8_error_index;    size_t tmp = _convert(        (Uint16*)_rep->data + oldSize, str, size, utf8_error_index);    if (tmp ==  size_t(-1))    {        StringRep::free(_rep);        _rep = &StringRep::_emptyRep;        _StringThrowBadUTF8(utf8_error_index);    }    _rep->size += tmp;    _rep->data[_rep->size] = '\0';    return *this;}void String::remove(Uint32 index, Uint32 n){    if (n == PEG_NOT_FOUND)        n = _rep->size - index;    _checkBounds(index + n, _rep->size);    if (_rep->refs.get() != 1)        _rep = StringRep::copyOnWrite(_rep);    PEGASUS_ASSERT(index + n <= _rep->size);    size_t rem = _rep->size - (index + n);    Uint16* data = _rep->data;    if (rem)        memmove(data + index, data + index + n, rem * sizeof(Uint16));    _rep->size -= n;    data[_rep->size] = '\0';}String String::subString(Uint32 index, Uint32 n) const{    // Note: this implementation is very permissive but used for    // backwards compatibility.    if (index < _rep->size)    {        if (n == PEG_NOT_FOUND || n > _rep->size - index)            n = _rep->size - index;        return String((Char16*)(_rep->data + index), n);    }    return String();}Uint32 String::find(Char16 c) const{    Uint16* p = (Uint16*)_find(_rep->data, _rep->size, c);    if (p)        return static_cast<Uint32>(p - _rep->data);    return PEG_NOT_FOUND;}Uint32 String::find(Uint32 index, Char16 c) const{    _checkBounds(index, _rep->size);    if (index >= _rep->size)        return PEG_NOT_FOUND;    Uint16* p = (Uint16*)_find(_rep->data + index, _rep->size - index, c);    if (p)        return static_cast<Uint32>(p - _rep->data);    return PEG_NOT_FOUND;}Uint32 StringFindAux(    const StringRep* _rep, const Char16* s, Uint32 n){    _checkNullPointer(s);    const Uint16* data = _rep->data;    size_t rem = _rep->size;    while (n <= rem)    {        Uint16* p = (Uint16*)_find(data, rem, s[0]);        if (!p)            break;        if (memcmp(p, s, n * sizeof(Uint16)) == 0)            return static_cast<Uint32>(p - _rep->data);        p++;        rem -= p - data;        data = p;    }    return PEG_NOT_FOUND;}Uint32 String::find(const char* s) const{    _checkNullPointer(s);    // Note: could optimize away creation of temporary, but this is rarely    // called.    return find(String(s));}Uint32 String::reverseFind(Char16 c) const{    Uint16 x = c;    Uint16* p = _rep->data;    Uint16* q = _rep->data + _rep->size;    while (q != p)    {        if (*--q == x)            return static_cast<Uint32>(q - p);    }    return PEG_NOT_FOUND;}void String::toLower(){#ifdef PEGASUS_HAS_ICU    if (InitializeICU::initICUSuccessful())    {        if (_rep->refs.get() != 1)            _rep = StringRep::copyOnWrite(_rep);        // This will do a locale-insensitive, but context-sensitive convert.        // Since context-sensitive casing looks at adjacent chars, this        // prevents optimizations where the us-ascii is converted before        // calling ICU.        // The string may shrink or expand after the convert.        //// First calculate size of resulting string. u_strToLower() returns        //// only the size when zero is passed as the destination size argument.        UErrorCode err = U_ZERO_ERROR;        int32_t newSize = u_strToLower(            NULL, 0, (UChar*)_rep->data, _rep->size, NULL, &err);        err = U_ZERO_ERROR;        //// Reserve enough space for the result.        if ((Uint32)newSize > _rep->cap)            _reserve(_rep, newSize);        //// Perform the conversion (overlapping buffers are allowed).        u_strToLower((UChar*)_rep->data, newSize,            (UChar*)_rep->data, _rep->size, NULL, &err);        _rep->size = newSize;        return;    }#endif /* PEGASUS_HAS_ICU */    if (_rep->refs.get() != 1)        _rep = StringRep::copyOnWrite(_rep);    Uint16* p = _rep->data;    size_t n = _rep->size;    for (; n--; p++)    {

⌨️ 快捷键说明

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