📄 kwqstring.cpp
字号:
_isUnicodeValid = 0;
}
else
str = _unicode;
_ascii = _internalBuffer;
_maxAscii = QS_INTERNAL_BUFFER_CHARS;
}
else {
uint newSize = ALLOC_CHAR_GOOD_SIZE(_length+1);
_ascii = ALLOC_CHAR(newSize);
if( !_ascii )
{
_maxAscii = 0;
return 0;
}
_maxAscii = newSize;
str = _unicode;
}
uint i = _length;
char *cp = _ascii;
while ( i-- )
*cp++ = *str++;
*cp = 0;
_isAsciiValid = 1;
}
else if (!_isAsciiValid)
FATAL("ASCII character cache not valid",0);
return _ascii;
}
QChar *KWQStringData::makeUnicode()
{
ASSERT(this != QString::shared_null);
if (_isAsciiValid){
char copyBuf[QS_INTERNAL_BUFFER_CHARS];
char *str;
if (_unicode && !isUnicodeInternal())
DELETE_QCHAR(_unicode);
if (_length <= QS_INTERNAL_BUFFER_UCHARS){
if (isAsciiInternal()) {
uint i = _length;
char *tp = ©Buf[0], *fp = _ascii;
while (i--)
*tp++ = *fp++;
str = ©Buf[0];
_isAsciiValid = 0;
}
else
str = _ascii;
_unicode = (QChar *)_internalBuffer;
_maxUnicode = QS_INTERNAL_BUFFER_UCHARS;
}
else {
uint newSize = ALLOC_QCHAR_GOOD_SIZE(_length);
_unicode = ALLOC_QCHAR(newSize);
if( !_unicode )
{
_maxUnicode = 0;
return 0;
}
_maxUnicode = newSize;
str = _ascii;
}
uint i = _length;
QChar *cp = _unicode;
while ( i-- )
*cp++ = *str++;
_isUnicodeValid = 1;
}
else if (!_isUnicodeValid)
FATAL("invalid character cache",0);
return _unicode;
}
// -------------------------------------------------------------------------
// QString
// -------------------------------------------------------------------------
QString QString::number(int n)
{
QString qs;
qs.setNum(n);
return qs;
}
QString QString::number(uint n)
{
QString qs;
qs.setNum(n);
return qs;
}
QString QString::number(long n)
{
QString qs;
qs.setNum(n);
return qs;
}
QString QString::number(ulong n)
{
QString qs;
qs.setNum(n);
return qs;
}
QString QString::number(double n)
{
QString qs;
qs.setNum(n);
return qs;
}
void QString::SetBufferFromDes(const TDesC& des)
{
int size = des.Length();
setUnicode((const QChar *)des.Ptr(), (uint)size);
}
QString QString::fromUtf8(const char *chs)
{
return QTextCodec(KCharacterSetIdentifierUtf8).toUnicode(chs, strlen(chs));
}
QString QString::fromUtf8(const char *chs, int len)
{
return QTextCodec(KCharacterSetIdentifierUtf8).toUnicode(chs, len);
}
QString QString::FromDes(const TDesC& des)
{
QString s;
s.SetBufferFromDes(des);
return s;
}
TPtrC QString::Des() const
{
if (!dataHandle[0]->_isUnicodeValid) {
dataHandle[0]->makeUnicode();
}
TPtrC tstr((const TUint16 *)unicode(), dataHandle[0]->_length);
return tstr;
}
inline void QString::detachIfInternal()
{
KWQStringData *oldData = *dataHandle;
if (oldData->refCount > 1 && oldData == &internalData) {
KWQStringData *newData = new KWQStringData(*oldData);
newData->_isHeapAllocated = 1;
newData->refCount = oldData->refCount;
oldData->refCount = 1;
oldData->deref();
*dataHandle = newData;
}
}
const QChar *QString::stableUnicode()
{
// if we're using the internal data of another string, detach now
if (!dataHandle[0]->_isHeapAllocated && *dataHandle != &internalData) {
detach();
}
return unicode();
}
QString::~QString()
{
ASSERT(dataHandle);
ASSERT(dataHandle[0]->refCount != 0);
// Only free the handle if no other string has a reference to the
// data. The handle will be freed by the string that has the
// last reference to data.
bool needToFreeHandle = dataHandle[0]->refCount == 1 && *dataHandle != shared_null;
// Copy our internal data if necessary, other strings still need it.
detachIfInternal();
// Remove our reference. This should always be the last reference
// if *dataHandle points to our internal KWQStringData. If we just detached,
// this will remove the extra ref from the new handle.
dataHandle[0]->deref();
ASSERT(*dataHandle != &internalData || dataHandle[0]->refCount == 0);
if (needToFreeHandle)
freeHandle(dataHandle);
dataHandle = 0;
}
QString::QString()
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance(&dataHandle);
#endif
internalData.deref();
dataHandle = makeSharedNullHandle();
dataHandle[0]->ref();
}
// Careful, just used by QConstString
QString::QString(KWQStringData *constData, bool /*dummy*/)
{
internalData.deref();
dataHandle = allocateHandle();
*dataHandle = constData;
// The QConstString constructor allocated the KWQStringData.
constData->_isHeapAllocated = 1;
}
QString::QString(QChar qc)
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
dataHandle = allocateHandle();
// Copy the QChar.
if (IS_ASCII_QCHAR(qc)) {
char c = (char)qc;
*dataHandle = &internalData;
internalData.initialize( &c, 1 );
}
else {
*dataHandle = &internalData;
internalData.initialize( &qc, 1 );
}
}
QString::QString(const QByteArray &qba)
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
dataHandle = allocateHandle();
// Copy data
*dataHandle = &internalData;
internalData.initialize(qba.data(),qba.size());
}
QString::QString(const QChar *unicode, uint length)
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
if (!unicode && !length) {
internalData.deref();
dataHandle = makeSharedNullHandle();
dataHandle[0]->ref();
} else {
dataHandle = allocateHandle();
// Copy the QChar *
*dataHandle = &internalData;
internalData.initialize(unicode, length);
}
}
QString::QString(const char *chs)
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
if (chs) {
internalData.initialize(chs,strlen(chs));
dataHandle = allocateHandle();
*dataHandle = &internalData;
} else {
internalData.deref();
dataHandle = makeSharedNullHandle();
dataHandle[0]->ref();
}
}
QString::QString(const char *chs, int len)
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
dataHandle = allocateHandle();
*dataHandle = &internalData;
internalData.initialize(chs,len);
}
QString::QString(const QString &qs) : dataHandle(qs.dataHandle)
{
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
internalData.deref();
dataHandle[0]->ref();
}
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",0);
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;
}
QCString QString::utf8(int &length) const
{
QCString res = QTextCodec(KCharacterSetIdentifierUtf8).fromUnicode(*this);
length = res.length();
return res;
}
QCString QString::local8Bit() const
{
return utf8();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -