📄 kwqstring.cpp
字号:
}QString &QString::operator=(const QString &qs){ if (this == &qs) return *this; // Free our handle if it isn't the shared null handle, and if no-one else is using it. bool needToFreeHandle = dataHandle != shared_null_handle && dataHandle[0]->refCount == 1; qs.dataHandle[0]->ref(); deref(); if (needToFreeHandle) freeHandle(dataHandle); dataHandle = qs.dataHandle; return *this;}QString &QString::operator=(const QCString &qcs){ return setLatin1(qcs);}QString &QString::operator=(const char *chs){ return setLatin1(chs);}QString &QString::operator=(QChar qc){ return *this = QString(qc);}QString &QString::operator=(char ch){ return *this = QString(QChar(ch));}QChar QString::at(uint i) const{ KWQStringData *thisData = *dataHandle; if (i >= thisData->_length) return QChar::null; if (thisData->_isAsciiValid) { return thisData->_ascii[i]; } ASSERT(thisData->_isUnicodeValid); return thisData->_unicode[i];}int QString::compare(const QString& s) const{ if (dataHandle[0]->_isAsciiValid && s.dataHandle[0]->_isAsciiValid) return strcmp(ascii(), s.ascii()); return ucstrcmp(*this,s);}int QString::compare(const char *chs) const{ if (!chs) return isEmpty() ? 0 : 1; KWQStringData *d = dataHandle[0]; if (d->_isAsciiValid) return strcmp(ascii(), chs); const QChar *s = unicode(); uint len = d->_length; for (uint i = 0; i != len; ++i) { char c2 = chs[i]; if (!c2) return 1; QChar c1 = s[i]; if (c1 < c2) return -1; if (c1 > c2) return 1; } return chs[len] ? -1 : 0;}bool QString::startsWith( const QString& s ) const{ if (dataHandle[0]->_isAsciiValid){ const char *asc = ascii(); for ( int i =0; i < (int) s.dataHandle[0]->_length; i++ ) { if ( i >= (int) dataHandle[0]->_length || asc[i] != s[i] ) return FALSE; } } else if (dataHandle[0]->_isUnicodeValid){ const QChar *uni = unicode(); for ( int i =0; i < (int) s.dataHandle[0]->_length; i++ ) { if ( i >= (int) dataHandle[0]->_length || uni[i] != s[i] ) return FALSE; } } else FATAL("invalid character cache"); return TRUE;}bool QString::startsWith(const char *prefix) const{ KWQStringData *data = *dataHandle; uint prefixLength = strlen(prefix); if (data->_isAsciiValid) { return strncmp(prefix, data->_ascii, prefixLength) == 0; } else { ASSERT(data->_isUnicodeValid); if (prefixLength > data->_length) { return false; } const QChar *uni = data->_unicode; for (uint i = 0; i < prefixLength; ++i) { if (uni[i] != prefix[i]) { return false; } } return true; }}bool QString::startsWith(const char *prefix, bool caseSensitive) const{ if (caseSensitive) { return startsWith(prefix); } KWQStringData *data = *dataHandle; uint prefixLength = strlen(prefix); if (data->_isAsciiValid) { return strncasecmp(prefix, data->_ascii, prefixLength) == 0; } else { ASSERT(data->_isUnicodeValid); if (prefixLength > data->_length) { return false; } const QChar *uni = data->_unicode; for (uint i = 0; i < prefixLength; ++i) { if (!equalCaseInsensitive(uni[i], prefix[i])) { return false; } } return true; }}bool QString::endsWith(const QString& s) const{ const QChar *uni = unicode(); int length = dataHandle[0]->_length; int slength = s.dataHandle[0]->_length; if (length < slength) return false; for (int i = length - slength, j = 0; i < length; i++, j++) { if (uni[i] != s[j]) return false; } return true;}#if !KWIQQCString QString::utf8() const{ uint len = dataHandle[0]->_length; if (len == 0) { return QCString(); } CFStringRef s = getCFString(); CFIndex utf8Size; CFStringGetBytes(s, CFRangeMake(0, len), kCFStringEncodingUTF8, '?', false, 0, 0, &utf8Size); length = utf8Size; QCString qcs(utf8Size + 1); CFStringGetCString(s, qcs.data(), utf8Size + 1, kCFStringEncodingUTF8); return qcs;}#elseQCString QString::utf8(int &len) const{ len = dataHandle[0]->_length; if (len == 0) return QCString(); glong read, written; GError* err = NULL; const QChar* start = unicode(); gchar* res_str = g_utf16_to_utf8(reinterpret_cast<const gunichar2*>(start), dataHandle[0]->_length, &read, &written, &err); if (err != NULL) { REPORT_G_CONV_ERROR(err); g_error_free(err); return QCString(); } QCString qcs(res_str, written+1); // FIXME: off by one here ? g_free(res_str); return qcs;}#endifQCString QString::local8Bit() const{ return utf8();}bool QString::isNull() const{ return dataHandle == shared_null_handle;}int QString::find(QChar qc, int index) const{ if (dataHandle[0]->_isAsciiValid) { if (!IS_ASCII_QCHAR(qc)) { return -1; } return find((char)qc, index); } return find(QString(qc), index, true);}int QString::find(char ch, int index) const{ if (dataHandle[0]->_isAsciiValid){ const char *cp = ascii(); if ( index < 0 ) index += dataHandle[0]->_length; if (index >= (int)dataHandle[0]->_length) return -1; for (int i = index; i < (int)dataHandle[0]->_length; i++) if (cp[i] == ch) return i; } else if (dataHandle[0]->_isUnicodeValid) return find(QChar(ch), index, TRUE); else FATAL("invalid character cache"); return -1;}int QString::find(const QString &str, int index, bool caseSensitive) const{ // FIXME, use the first character algorithm /* We use some weird hashing for efficiency's sake. Instead of comparing strings, we compare the sum of str with that of a part of this QString. Only if that matches, we call memcmp or ucstrnicmp. The hash value of a string is the sum of the cells of its QChars. */ if ( index < 0 ) index += dataHandle[0]->_length; int lstr = str.dataHandle[0]->_length; int lthis = dataHandle[0]->_length - index; if ( (uint)lthis > dataHandle[0]->_length ) return -1; int delta = lthis - lstr; if ( delta < 0 ) return -1; const QChar *uthis = unicode() + index; const QChar *ustr = str.unicode(); uint hthis = 0; uint hstr = 0; int i; if ( caseSensitive ) { for ( i = 0; i < lstr; i++ ) { hthis += uthis[i].unicode(); hstr += ustr[i].unicode(); } i = 0; while ( TRUE ) { if ( hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(QChar)) == 0 ) return index + i; if ( i == delta ) return -1; hthis += uthis[i + lstr].unicode(); hthis -= uthis[i].unicode(); i++; } } else { for ( i = 0; i < lstr; i++ ) { hthis += g_unichar_tolower(uthis[i].unicode()); hstr += g_unichar_tolower(ustr[i].unicode()); } i = 0; while ( TRUE ) { if ( hthis == hstr && equalCaseInsensitive(uthis + i, ustr, lstr) ) return index + i; if ( i == delta ) return -1; hthis += g_unichar_tolower(uthis[i + lstr].unicode()); hthis -= g_unichar_tolower(uthis[i].unicode()); i++; } }}// This function should be as fast as possible, every little bit helps.// Our usage patterns are typically small strings. In time trials// this simplistic algorithm is much faster than Boyer-Moore or hash// based algorithms.int QString::find(const char *chs, int index, bool caseSensitive) const{ if (!chs || index < 0) return -1; KWQStringData *data = *dataHandle; int chsLength = strlen(chs); int n = data->_length - index; if (n < 0) return -1; n -= chsLength - 1; if (n <= 0) return -1; const char *chsPlusOne = chs + 1; int chsLengthMinusOne = chsLength - 1; if (data->_isAsciiValid) { char *ptr = data->_ascii + index - 1; if (caseSensitive) { char c = *chs; do { if (*++ptr == c && memcmp(ptr + 1, chsPlusOne, chsLengthMinusOne) == 0) { return data->_length - chsLength - n + 1; } } while (--n); } else { guint lc = g_unichar_tolower(*chs); do { if (g_unichar_tolower(*++ptr) == lc && equalCaseInsensitive(ptr + 1, chsPlusOne, chsLengthMinusOne)) { return data->_length - chsLength - n + 1; } } while (--n); } } else { ASSERT(data->_isUnicodeValid); const QChar *ptr = data->_unicode + index - 1; if (caseSensitive) { QChar c = *chs; do { if (*++ptr == c && equal(ptr + 1, chsPlusOne, chsLengthMinusOne)) { return data->_length - chsLength - n + 1; } } while (--n); } else { guint lc = g_unichar_tolower((unsigned char)*chs); do { if (g_unichar_tolower((++ptr)->unicode()) == lc && equalCaseInsensitive(ptr + 1, chsPlusOne, chsLengthMinusOne)) { return data->_length - chsLength - n + 1; } } while (--n); } } return -1;}int QString::find(const QRegExp &qre, int index) const{ if ( index < 0 ) index += dataHandle[0]->_length; return qre.match( *this, index );}int QString::findRev(char ch, int index) const{ if (dataHandle[0]->_isAsciiValid){ const char *cp = ascii(); if (index < 0) index += dataHandle[0]->_length; if (index > (int)dataHandle[0]->_length) return -1; for (int i = index; i >= 0; i--) { if (cp[i] == ch) return i; } } else if (dataHandle[0]->_isUnicodeValid) return findRev(QString(QChar(ch)), index); else FATAL("invalid character cache"); return -1;}int QString::findRev(const char *chs, int index) const{ return findRev(QString(chs), index);}int QString::findRev( const QString& str, int index, bool cs ) const{ // FIXME, use the first character algorithm /* See QString::find() for explanations. */ int lthis = dataHandle[0]->_length; if ( index < 0 ) index += lthis; int lstr = str.dataHandle[0]->_length; int delta = lthis - lstr; if ( index < 0 || index > lthis || delta < 0 ) return -1; if ( index > delta ) index = delta; const QChar *uthis = unicode(); const QChar *ustr = str.unicode(); uint hthis = 0; uint hstr = 0; int i; if ( cs ) { for ( i = 0; i < lstr; i++ ) { hthis += uthis[index + i].cell(); hstr += ustr[i].cell(); } i = index; while ( TRUE ) { if ( hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(QChar)) == 0 ) return i; if ( i == 0 ) return -1; i--; hthis -= uthis[i + lstr].cell(); hthis += uthis[i].cell(); } } else { for ( i = 0; i < lstr; i++ ) { hthis += uthis[index + i].lower().cell(); hstr += ustr[i].lower().cell(); } i = index; while ( TRUE ) { if ( hthis == hstr && equalCaseInsensitive(uthis + i, ustr, lstr) ) return i; if ( i == 0 ) return -1; i--; hthis -= uthis[i + lstr].lower().cell(); hthis += uthis[i].lower().cell(); } } // Should never get here. return -1;}#ifdef DEBUG_CONTAINS_COUNTERstatic int containsCount = 0;#endifint QString::contains(QChar c, bool cs) const{ int count = 0; KWQStringData *data = *dataHandle; if (data->_isAsciiValid) { if (!IS_ASCII_QCHAR(c)) return 0; const char *cPtr = data->_ascii; int n = data->_length; char ac = c.unicode(); if (cs) { // case sensitive while (n--) count += *cPtr++ == ac; } else { // case insensitive guint lc = g_unichar_tolower(ac); while (n--) { count += g_unichar_tolower(*cPtr++) == lc; } } } else { ASSERT(data->_isUnicodeValid); const QChar *uc = data->_unicode; int n = data->_length; if (cs) { // case sensitive while ( n-- ) count += *uc++ == c; } else { // case insensitive
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -