📄 kwqstring.cpp
字号:
{ if ( isEmpty() ) // nothing to do return *this; if ( !at(0).isSpace() && !at(dataHandle[0]->_length-1).isSpace() ) return *this; int start = 0; int end = dataHandle[0]->_length - 1; QString result = fromLatin1(""); while ( start<=end && at(start).isSpace() ) // skip white space from start start++; if ( start > end ) { // only white space return result; } while ( end && at(end).isSpace() ) // skip white space from end end--; int l = end - start + 1; if (dataHandle[0]->_isAsciiValid){ result.setLength( l ); if ( l ) memcpy( (char *)result.dataHandle[0]->ascii(), &ascii()[start], l ); } else if (dataHandle[0]->_isUnicodeValid){ result.setLength( l ); if ( l ) memcpy(result.forceUnicode(), &unicode()[start], sizeof(QChar)*l ); } else FATAL("invalid character cache"); return result;}QString QString::simplifyWhiteSpace() const{ if ( isEmpty() ) // nothing to do return *this; QString result; if (dataHandle[0]->_isAsciiValid){ result.setLength( dataHandle[0]->_length ); const char *from = ascii(); const char *fromend = from + dataHandle[0]->_length; int outc=0; char *to = (char *)result.ascii(); while ( TRUE ) { while ( from!=fromend && QChar(*from).isSpace() ) from++; while ( from!=fromend && !QChar(*from).isSpace() ) to[outc++] = *from++; if ( from!=fromend ) to[outc++] = ' '; else break; } if ( outc > 0 && to[outc-1] == ' ' ) outc--; result.truncate( outc ); } else if (dataHandle[0]->_isUnicodeValid){ result.setLength( dataHandle[0]->_length ); const QChar *from = unicode(); const QChar *fromend = from + dataHandle[0]->_length; int outc=0; QChar *to = result.forceUnicode(); while ( TRUE ) { while ( from!=fromend && from->isSpace() ) from++; while ( from!=fromend && !from->isSpace() ) to[outc++] = *from++; if ( from!=fromend ) to[outc++] = ' '; else break; } if ( outc > 0 && to[outc-1] == ' ' ) outc--; result.truncate( outc ); } else FATAL("invalid character cache"); return result;}void QString::deref(){ dataHandle[0]->deref();}QString &QString::setUnicode(const QChar *uni, uint len){ detachAndDiscardCharacters(); // 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; if (len == 0) { deref(); if (needToFreeHandle) freeHandle(dataHandle); dataHandle = makeSharedNullHandle(); dataHandle[0]->ref(); } else if (len > dataHandle[0]->_maxUnicode || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isUnicodeValid) { deref(); if (needToFreeHandle) freeHandle(dataHandle); dataHandle = allocateHandle(); *dataHandle = new KWQStringData(uni, len); dataHandle[0]->_isHeapAllocated = 1; } else { if ( uni ) memcpy( (void *)unicode(), uni, sizeof(QChar)*len ); dataHandle[0]->_length = len; dataHandle[0]->_isAsciiValid = 0; } return *this;}QString &QString::setLatin1(const char *str, int len){ if ( str == 0 ) return setUnicode(0,0); if ( len < 0 ) len = strlen(str); detachAndDiscardCharacters(); // 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; if (len+1 > (int)dataHandle[0]->_maxAscii || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isAsciiValid) { deref(); if (needToFreeHandle) freeHandle(dataHandle); dataHandle = allocateHandle(); *dataHandle = new KWQStringData(str,len); dataHandle[0]->_isHeapAllocated = 1; } else { strcpy( (char *)ascii(), str ); dataHandle[0]->_length = len; dataHandle[0]->_isUnicodeValid = 0; } return *this;}QString &QString::setNum(short n){ return sprintf("%d", n);}QString &QString::setNum(ushort n){ return sprintf("%u", n);}QString &QString::setNum(int n){ return sprintf("%d", n);}QString &QString::setNum(uint n){ return sprintf("%u", n);}QString &QString::setNum(long n){ return sprintf("%ld", n);}QString &QString::setNum(ulong n){ return sprintf("%lu", n);}QString &QString::setNum(double n){ return sprintf("%.6lg", n);}QString &QString::sprintf(const char *format, ...){ va_list args; va_start(args, format); // Do the format once to get the length. char ch; size_t len = vsnprintf(&ch, 1, format, args); // Handle the empty string case to simplify the code below. if (len == 0) { setUnicode(0, 0); return *this; } // Arrange for storage for the resulting string. detachAndDiscardCharacters(); if (len >= dataHandle[0]->_maxAscii || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isAsciiValid) { // 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; deref(); if (needToFreeHandle) freeHandle(dataHandle); dataHandle = allocateHandle(); *dataHandle = new KWQStringData((char *)0, len); dataHandle[0]->_isHeapAllocated = 1; } else { dataHandle[0]->_length = len; dataHandle[0]->_isUnicodeValid = 0; } // Now do the formatting again, guaranteed to fit. vsprintf((char *)ascii(), format, args); return *this;}QString &QString::prepend(const QString &qs){ return insert(0, qs);}QString &QString::prepend(const QChar *characters, uint length){ return insert(0, characters, length);}QString &QString::append(const QString &qs){ return insert(dataHandle[0]->_length, qs);}QString &QString::append(const char *characters, uint length){ return insert(dataHandle[0]->_length, characters, length);}QString &QString::append(const QChar *characters, uint length){ return insert(dataHandle[0]->_length, characters, length);}QString &QString::insert(uint index, const char *insertChars, uint insertLength){ if (insertLength == 0) return *this; detach(); if (dataHandle[0]->_isAsciiValid){ uint originalLength = dataHandle[0]->_length; char *targetChars; // Ensure that we have enough space. setLength (originalLength + insertLength); targetChars = (char *)ascii(); // Move tail to make space for inserted characters. memmove (targetChars+index+insertLength, targetChars+index, originalLength-index); // Insert characters. memcpy (targetChars+index, insertChars, insertLength); dataHandle[0]->_isUnicodeValid = 0; } else if (dataHandle[0]->_isUnicodeValid){ uint originalLength = dataHandle[0]->_length; QChar *targetChars; // Ensure that we have enough space. setLength (originalLength + insertLength); targetChars = (QChar *)unicode(); // Move tail to make space for inserted characters. memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(QChar)); // Insert characters. uint i = insertLength; QChar *target = targetChars+index; while (i--) *target++ = *insertChars++; } else FATAL("invalid character cache"); return *this;}QString &QString::insert(uint index, const QString &qs){ if (qs.dataHandle[0]->_length == 0) return *this; #ifdef QSTRING_DEBUG_UNICODE forceUnicode();#endif if (dataHandle[0]->_isAsciiValid && qs.isAllLatin1()) { insert(index, qs.latin1(), qs.length()); } else { uint insertLength = qs.dataHandle[0]->_length; uint originalLength = dataHandle[0]->_length; QChar *targetChars; // Ensure that we have enough space. setLength (originalLength + insertLength); targetChars = forceUnicode(); // Move tail to make space for inserted characters. memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(QChar)); // Insert characters. if (qs.dataHandle[0]->_isAsciiValid){ uint i = insertLength; QChar *target = targetChars+index; char *a = (char *)qs.ascii(); while (i--) *target++ = *a++; } else { QChar *insertChars = (QChar *)qs.unicode(); memcpy (targetChars+index, insertChars, insertLength*sizeof(QChar)); } dataHandle[0]->_isAsciiValid = 0; } return *this;}QString &QString::insert(uint index, const QChar *insertChars, uint insertLength){ if (insertLength == 0) return *this; forceUnicode(); uint originalLength = dataHandle[0]->_length; setLength(originalLength + insertLength); QChar *targetChars = const_cast<QChar *>(unicode()); if (originalLength > index) { memmove(targetChars + index + insertLength, targetChars + index, (originalLength - index) * sizeof(QChar)); } memcpy(targetChars + index, insertChars, insertLength * sizeof(QChar)); return *this;}QString &QString::insert(uint index, QChar qc){ detach(); if (dataHandle[0]->_isAsciiValid && IS_ASCII_QCHAR(qc)){ uint originalLength = dataHandle[0]->_length; char insertChar = (char)qc; char *targetChars; // Ensure that we have enough space. setLength (originalLength + 1); targetChars = (char *)ascii(); // Move tail to make space for inserted character. memmove (targetChars+index+1, targetChars+index, originalLength-index); // Insert character. targetChars[index] = insertChar; targetChars[dataHandle[0]->_length] = 0; dataHandle[0]->_isUnicodeValid = 0; } else { uint originalLength = dataHandle[0]->_length; QChar *targetChars; // Ensure that we have enough space. setLength (originalLength + 1); targetChars = forceUnicode(); // Move tail to make space for inserted character. memmove (targetChars+(index+1), targetChars+index, (originalLength-index)*sizeof(QChar)); targetChars[index] = qc; } return *this;}QString &QString::insert(uint index, char ch){ detach(); if (dataHandle[0]->_isAsciiValid) { uint originalLength = dataHandle[0]->_length; char *targetChars; // Ensure that we have enough space. setLength (originalLength + 1); targetChars = (char *)ascii(); // Move tail to make space for inserted character. memmove (targetChars+index+1, targetChars+index, originalLength-index); // Insert character. targetChars[index] = ch; targetChars[dataHandle[0]->_length] = 0; dataHandle[0]->_isUnicodeValid = 0; } else if (dataHandle[0]->_isUnicodeValid){ uint originalLength = dataHandle[0]->_length; QChar *targetChars; // Ensure that we have enough space. setLength (originalLength + 1); targetChars = (QChar *)unicode(); // Move tail to make space for inserted character. memmove (targetChars+(index+1), targetChars+index, (originalLength-index)*sizeof(QChar)); targetChars[index] = (QChar)ch; } else FATAL("invalid character cache"); return *this;}// Copy KWQStringData if necessary. Must be called before the string data is mutated.void QString::detach(){ KWQStringData *oldData = *dataHandle; if (oldData->refCount == 1 && oldData != shared_null) return;#ifdef QSTRING_DEBUG_ALLOCATIONS stringDataDetachments++;#endif // Copy data for this string so we can safely mutate it. KWQStringData *newData; if (oldData->_isAsciiValid) newData = new KWQStringData(oldData->ascii(), oldData->_length); else newData = new KWQStringData(oldData->unicode(), oldData->_length); newData->_isHeapAllocated = 1; // There is now one less client for the old data. oldData->deref(); // If the old data is our internal data, then we'll keep that. // This decreases the chance we'll have to do a detachInternal later // when this object is destroyed. if (oldData == &internalData) { newData->refCount = oldData->refCount; oldData->refCount = 1; *dataHandle = newData; newData = oldData; } // Create a new handle. dataHandle = allocateHandle(); *dataHandle = newData;}void QString::detachAndDiscardCharacters(){ // Missing optimization: Don't bother copying the old data if we detach. detach();}QString &QString::remove(uint index, uint len){ uint olen = dataHandle[0]->_length; if ( index >= olen ) { // range problems } else if ( index + len >= olen ) { // index ok setLength( index ); } else if ( len != 0 ) { // Missing optimization: Could avoid copying characters we are going to remove // by making a special version of detach(). detach(); #ifdef QSTRING_DEBUG_UNICODE forceUnicode();#endif if (dataHandle[0]->_isAsciiValid){ memmove( dataHandle[0]->ascii()+index, dataHandle[0]->ascii()+index+len, sizeof(char)*(olen-index-len) ); setLength( olen-len ); dataHandle[0]->_isUnicodeValid = 0; } else if (dataHandle[0]->_isUnicodeValid){ memmove( dataHandle[0]->unicode()+index, dataHandle[0]->unicode()+index+len, sizeof(QChar)*(olen-index-len) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -