📄 kwqstring.cpp
字号:
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",0);
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 += tolower(uthis[i].unicode());
hstr += 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 += tolower(uthis[i + lstr].unicode());
hthis -= 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 {
int lc = tolower(*chs);
do {
if (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 {
int lc = tolower((unsigned char)*chs);
do {
if (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",0);
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_COUNTER
static int containsCount = 0;
#endif
int 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
int lc = tolower(ac);
while (n--) {
count += 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
int lc = tolower(c.unicode());
while (n--) {
count += tolower(uc->unicode()) == lc;
uc++;
}
}
}
return count;
}
int QString::contains(char ch) const
{
return contains(QChar(ch), true);
}
int QString::contains(const char *str, bool caseSensitive) const
{
if (!str)
return 0;
int len = strlen(str);
char c = *str;
KWQStringData *data = *dataHandle;
int n = data->_length;
n -= len - 1;
if (n <= 0)
return 0;
int count = 0;
if (data->_isAsciiValid) {
const char *p = data->_ascii;
if (caseSensitive) {
do {
count += *p == c && memcmp(p + 1, str + 1, len - 1) == 0;
p++;
} while (--n);
} else {
int lc = tolower(c);
do {
count += tolower(*p) == lc && equalCaseInsensitive(p + 1, str + 1, len - 1);
p++;
} while (--n);
}
} else {
ASSERT(data->_isUnicodeValid);
const QChar *p = data->_unicode;
if (caseSensitive) {
do {
count += *p == c && equal(p + 1, str + 1, len - 1);
p++;
} while (--n);
} else {
int lc = tolower(c);
do {
count += tolower(p->unicode()) == lc && equalCaseInsensitive(p + 1, str + 1, len - 1);
p++;
} while (--n);
}
}
return count;
}
int QString::contains(const QString &str, bool caseSensitive) const
{
if (str.isEmpty())
return 0;
const QChar *strP = str.unicode();
int len = str.dataHandle[0]->_length;
QChar c = *strP;
const QChar *p = unicode();
int n = dataHandle[0]->_length;
n -= len - 1;
if (n <= 0)
return 0;
int count = 0;
if (caseSensitive) {
int byteCount = len * sizeof(QChar);
do {
count += *p == c && memcmp(p, strP, byteCount) == 0;
++p;
} while (--n);
} else {
do {
count += p->lower() == c && equalCaseInsensitive(p, strP, len) == 0;
++p;
} while (--n);
}
return count;
}
bool QString::isAllASCII() const
{
KWQStringData *data = *dataHandle;
int n = data->_length;
if (data->_isAsciiValid) {
const char *p = data->_ascii;
while (n--) {
unsigned char c = *p++;
if (c > 0x7F) {
return false;
}
}
} else {
ASSERT(data->_isUnicodeValid);
const QChar *p = data->_unicode;
while (n--) {
if ((*p++).unicode() > 0x7F) {
return false;
}
}
}
return true;
}
bool QString::isAllLatin1() const
{
KWQStringData *data = *dataHandle;
if (data->_isAsciiValid) {
return true;
}
ASSERT(data->_isUnicodeValid);
int n = data->_length;
const QChar *p = data->_unicode;
while (n--) {
if ((*p++).unicode() > 0xFF) {
return false;
}
}
return true;
}
bool QString::hasFastLatin1() const
{
KWQStringData *data = *dataHandle;
return data->_isAsciiValid;
}
void QString::copyLatin1(char *buffer, uint position, uint maxLength) const
{
KWQStringData *data = *dataHandle;
int length = data->_length;
if (position > static_cast<uint>(length))
length = 0;
else
length -= position;
if (static_cast<uint>(length) > maxLength)
length = static_cast<int>(maxLength);
buffer[length] = 0;
if (data->_isAsciiValid) {
memcpy(buffer, data->_ascii + position, length);
return;
}
ASSERT(data->_isUnicodeValid);
const QChar *uc = data->_unicode + position;
while (length--)
*buffer++ = *uc++;
}
short QString::toShort(bool *ok, int base) const
{
long v = toLong( ok, base );
if ( ok && *ok && (v < -32768 || v > 32767) ) {
*ok = FALSE;
v = 0;
}
return (short)v;
}
ushort QString::toUShort(bool *ok, int base) const
{
ulong v = toULong( ok, base );
if ( ok && *ok && (v > 65535) ) {
*ok = FALSE;
v = 0;
}
return (ushort)v;
}
int QString::toInt(bool *ok, int base) const
{
return (int)toLong( ok, base );
}
uint QString::toUInt(bool *ok, int base) const
{
return (uint)toULong( ok, base );
}
long QString::toLong(bool *ok, int base) const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -