📄 kwqstring.cpp
字号:
_maxAscii = QS_INTERNAL_BUFFER_CHARS; _ascii = _internalBuffer; if (a) memcpy(_internalBuffer, a, l); _internalBuffer[l] = 0; }}KWQStringData::KWQStringData(KWQStringData &o) : refCount(1) , _length(o._length) , _unicode(o._unicode) , _ascii(o._ascii) , _maxUnicode(o._maxUnicode) , _isUnicodeValid(o._isUnicodeValid) , _isHeapAllocated(0) , _maxAscii(o._maxAscii) , _isAsciiValid(o._isAsciiValid){ // Handle the case where either the Unicode or 8-bit pointer was // pointing to the internal buffer. We need to point at the // internal buffer in the new object, and copy the characters. if (_unicode == reinterpret_cast<QChar *>(o._internalBuffer)) { if (_isUnicodeValid) { ASSERT(!_isAsciiValid || _ascii != o._internalBuffer); ASSERT(_length <= QS_INTERNAL_BUFFER_UCHARS); memcpy(_internalBuffer, o._internalBuffer, _length * sizeof(QChar)); _unicode = reinterpret_cast<QChar *>(_internalBuffer); } else { _unicode = 0; } } if (_ascii == o._internalBuffer) { if (_isAsciiValid) { ASSERT(_length <= QS_INTERNAL_BUFFER_CHARS); memcpy(_internalBuffer, o._internalBuffer, _length); _internalBuffer[_length] = 0; _ascii = _internalBuffer; } else { _ascii = 0; } } // Clean up the other KWQStringData just enough so that it can be destroyed // cleanly. It's not in a good enough state to use, but that's OK. It just // needs to be in a state where ~KWQStringData won't do anything harmful, // and setting these to 0 will do that (preventing any double-free problems). o._unicode = 0; o._ascii = 0;}KWQStringData *QString::makeSharedNull(){ if (!shared_null) { shared_null = new KWQStringData; shared_null->ref(); shared_null->_maxAscii = 0; shared_null->_maxUnicode = 0; shared_null->_unicode = (QChar *)&shared_null->_internalBuffer[0]; shared_null->_isUnicodeValid = 1; } return shared_null;}KWQStringData **QString::makeSharedNullHandle(){ if (!shared_null_handle) { shared_null_handle = allocateHandle(); *shared_null_handle = makeSharedNull(); } return shared_null_handle;}KWQStringData::~KWQStringData(){ ASSERT(refCount == 0); if (_unicode && !isUnicodeInternal()) DELETE_QCHAR(_unicode); if (_ascii && !isAsciiInternal()) DELETE_CHAR(_ascii);}void KWQStringData::increaseAsciiSize(uint size){ ASSERT(this != QString::shared_null); uint newSize = (uint)ALLOC_CHAR_GOOD_SIZE((size * 3 + 1) / 2); if (!_isAsciiValid) makeAscii(); ASSERT(_isAsciiValid); if (isAsciiInternal()) { char *newAscii = ALLOC_CHAR(newSize); if (_length) memcpy(newAscii, _ascii, _length); _ascii = newAscii; } else { _ascii = REALLOC_CHAR(_ascii, newSize); } _maxAscii = newSize; _isAsciiValid = 1; _isUnicodeValid = 0;}void KWQStringData::increaseUnicodeSize(uint size){ ASSERT(size > _length); ASSERT(this != QString::shared_null); uint newSize = (uint)ALLOC_QCHAR_GOOD_SIZE((size * 3 + 1) / 2); if (!_isUnicodeValid) makeUnicode(); ASSERT(_isUnicodeValid); if (isUnicodeInternal()) { QChar *newUni = ALLOC_QCHAR(newSize); if (_length) memcpy(newUni, _unicode, _length*sizeof(QChar)); _unicode = newUni; } else { _unicode = REALLOC_QCHAR(_unicode, newSize); } _maxUnicode = newSize; _isUnicodeValid = 1; _isAsciiValid = 0;}char *KWQStringData::makeAscii(){ ASSERT(this != QString::shared_null); if (_isUnicodeValid){ QChar copyBuf[QS_INTERNAL_BUFFER_CHARS]; QChar *str; if (_ascii && !isAsciiInternal()) DELETE_QCHAR(_ascii); if (_length < QS_INTERNAL_BUFFER_CHARS){ if (isUnicodeInternal()) { uint i = _length; QChar *tp = ©Buf[0], *fp = _unicode; while (i--) *tp++ = *fp++; str = ©Buf[0]; _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); _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"); 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); _maxUnicode = newSize; str = _ascii; } uint i = _length; QChar *cp = _unicode; while ( i-- ) *cp++ = *str++; _isUnicodeValid = 1; } else if (!_isUnicodeValid) FATAL("invalid character cache"); 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;}#if !KWIQvoid QString::setBufferFromCFString(CFStringRef cfs){ if (!cfs) { return; } CFIndex size = CFStringGetLength(cfs); UniChar fixedSizeBuffer[1024]; UniChar *buffer; if (size > (CFIndex)(sizeof(fixedSizeBuffer) / sizeof(UniChar))) { buffer = (UniChar *)malloc(size * sizeof(UniChar)); } else { buffer = fixedSizeBuffer; } CFStringGetCharacters(cfs, CFRangeMake (0, size), buffer); setUnicode((const QChar *)buffer, (uint)size); if (buffer != fixedSizeBuffer) { free(buffer); }}QString QString::fromUtf8(const char *chs){ return QTextCodec(kCFStringEncodingUTF8).toUnicode(chs, strlen(chs));}QString QString::fromUtf8(const char *chs, int len){ return QTextCodec(kCFStringEncodingUTF8).toUnicode(chs, len);}QString QString::fromCFString(CFStringRef cfs){ QString qs; qs.setBufferFromCFString(cfs); return qs;}QString QString::fromNSString(NSString *nss){ QString qs; qs.setBufferFromCFString((CFStringRef)nss); return qs;}NSString *QString::getNSString() const{ // The Cocoa calls in this method don't need exceptions blocked // because they are simple NSString calls that can't throw. if (dataHandle[0]->_isUnicodeValid) { return [NSString stringWithCharacters:(const unichar *)unicode() length:dataHandle[0]->_length]; } if (dataHandle[0]->_isAsciiValid) { return [(NSString *)CFStringCreateWithCString(kCFAllocatorDefault, ascii(), kCFStringEncodingISOLatin1) autorelease]; } FATAL("invalid character cache"); return nil;}#else/* FIXME: when QTextCodec is written to support optimized utf8->utf16, use it like above * QString::fromUtf8 --ktkinnun */QString QString::fromUtf8(const char *chs){ return fromUtf8(chs, -1);}QString QString::fromUtf8(const char *chs,int len){ glong read, written; GError* err = NULL; if ( !chs || len == 0 || (len == -1 && (*chs=='\0'))) return QString(); gunichar2 *res = g_utf8_to_utf16(chs, len, &read, &written, &err); if (err != NULL){ REPORT_G_CONV_ERROR(err); g_error_free(err); return QString(); } QString str(reinterpret_cast<QChar*>(res), written); // FIXME: off by one here? g_free(res); return str;}#endifinline void QString::detachInternal(){ KWQStringData *oldData = *dataHandle; KWQStringData *newData = new KWQStringData(*oldData); newData->_isHeapAllocated = 1; newData->refCount = oldData->refCount - 1; oldData->refCount = 1; *dataHandle = newData; }inline void QString::detachIfInternal(){ KWQStringData *oldData = *dataHandle; if (oldData->refCount > 1 && oldData == &internalData) { detachInternal(); }}QString::~QString(){ KWQStringData **oldHandle = dataHandle; KWQStringData *oldData = *oldHandle; ASSERT(oldHandle); ASSERT(oldData->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 = oldData->refCount == 1 && oldData != 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. oldData->deref(); ASSERT(oldData != &internalData || oldData->refCount == 0); if (needToFreeHandle) freeHandle(oldHandle); dataHandle = 0;}QString::QString(){#ifdef QSTRING_DEBUG_ALLOCATIONS countInstance(&dataHandle);#endif internalData.deref(); dataHandle = makeSharedNullHandle(); dataHandle[0]->ref();}// Careful, just used by QConstStringQString::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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -