NEVER_INLINE unsigned StringImpl::hashSlowCase() const { if (is8Bit()) setHash(StringHasher::computeHashAndMaskTop8Bits(characters8(), m_length)); else setHash(StringHasher::computeHashAndMaskTop8Bits(characters16(), m_length)); return existingHash(); }
void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) { if (!m_impl) { if (!charactersToAppend) return; m_impl = StringImpl::create(charactersToAppend, lengthToAppend); return; } if (!lengthToAppend) return; unsigned strLength = m_impl->length(); ASSERT(charactersToAppend); RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLength); UChar* data; RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data); if (m_impl->is8Bit()) StringImpl::copyChars(data, characters8(), strLength); else StringImpl::copyChars(data, characters16(), strLength); StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); m_impl = newImpl.release(); }
RetainPtr<CFStringRef> StringImpl::createCFString() { // Since garbage collection isn't compatible with custom allocators, we // can't use the NoCopy variants of CFStringCreate*() when GC is enabled. if (!m_length || !isMainThread() || garbageCollectionEnabled()) { if (is8Bit()) return adoptCF(CFStringCreateWithBytes(0, reinterpret_cast<const UInt8*>(characters8()), m_length, kCFStringEncodingISOLatin1, false)); return adoptCF(CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(characters16()), m_length)); } CFAllocatorRef allocator = StringWrapperCFAllocator::allocator(); // Put pointer to the StringImpl in a global so the allocator can store it with the CFString. ASSERT(!StringWrapperCFAllocator::currentString); StringWrapperCFAllocator::currentString = this; CFStringRef string; if (is8Bit()) string = CFStringCreateWithBytesNoCopy(allocator, reinterpret_cast<const UInt8*>(characters8()), m_length, kCFStringEncodingISOLatin1, false, kCFAllocatorNull); else string = CFStringCreateWithCharactersNoCopy(allocator, reinterpret_cast<const UniChar*>(characters16()), m_length, kCFAllocatorNull); // CoreFoundation might not have to allocate anything, we clear currentString in case we did not execute allocate(). StringWrapperCFAllocator::currentString = 0; return adoptCF(string); }
unsigned String::copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const { unsigned length = this->length(); RELEASE_ASSERT(pos <= length); unsigned numCharacters = std::min(length - pos, maxLength); if (!numCharacters) return 0; if (is8Bit()) StringImpl::copyChars(buffer, characters8() + pos, numCharacters); else StringImpl::copyChars(buffer, characters16() + pos, numCharacters); return numCharacters; }
void String::remove(unsigned position, int lengthToRemove) { if (lengthToRemove <= 0) return; if (position >= length()) return; if (static_cast<unsigned>(lengthToRemove) > length() - position) lengthToRemove = length() - position; if (is8Bit()) { removeInternal(characters8(), position, lengthToRemove); return; } removeInternal(characters16(), position, lengthToRemove); }
String::operator QString() const { if (!m_impl) return QString(); if (QStringData* qStringData = m_impl->qStringData()) { // The WTF string was adopted from a QString at some point, so we // can just adopt the QStringData like a regular QString copy. qStringData->ref.ref(); QStringDataPtr qStringDataPointer = { qStringData }; return QString(qStringDataPointer); } if (is8Bit() && !m_impl->has16BitShadow()) { // Asking for characters() of an 8-bit string will make a 16-bit copy internally // in WTF::String. Since we're going to copy the data to QStringData anyways, we // can do the conversion ourselves and save one copy. return QString::fromLatin1(reinterpret_cast<const char*>(characters8()), length()); } return QString(reinterpret_cast<const QChar*>(characters()), length()); }