This source file includes following definitions.
- retain
- release
- copyDescription
- allocate
- reallocate
- deallocateOnMainThread
- deallocate
- preferredSize
- create
- allocator
- createCFString
#include "config.h"
#include "wtf/text/StringImpl.h"
#if USE(CF)
#include "wtf/MainThread.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RetainPtr.h"
#include "wtf/Threading.h"
#include <CoreFoundation/CoreFoundation.h>
namespace WTF {
namespace StringWrapperCFAllocator {
static StringImpl* currentString;
static const void* retain(const void* info)
{
return info;
}
NO_RETURN_DUE_TO_ASSERT
static void release(const void*)
{
ASSERT_NOT_REACHED();
}
static CFStringRef copyDescription(const void*)
{
return CFSTR("WTF::String-based allocator");
}
static void* allocate(CFIndex size, CFOptionFlags, void*)
{
StringImpl* underlyingString = 0;
if (isMainThread()) {
underlyingString = currentString;
if (underlyingString) {
currentString = 0;
underlyingString->ref();
}
}
StringImpl** header = static_cast<StringImpl**>(fastMalloc(sizeof(StringImpl*) + size));
*header = underlyingString;
return header + 1;
}
static void* reallocate(void* pointer, CFIndex newSize, CFOptionFlags, void*)
{
size_t newAllocationSize = sizeof(StringImpl*) + newSize;
StringImpl** header = static_cast<StringImpl**>(pointer) - 1;
ASSERT(!*header);
header = static_cast<StringImpl**>(fastRealloc(header, newAllocationSize));
return header + 1;
}
static void deallocateOnMainThread(void* headerPointer)
{
StringImpl** header = static_cast<StringImpl**>(headerPointer);
StringImpl* underlyingString = *header;
ASSERT(underlyingString);
underlyingString->deref();
fastFree(header);
}
static void deallocate(void* pointer, void*)
{
StringImpl** header = static_cast<StringImpl**>(pointer) - 1;
StringImpl* underlyingString = *header;
if (!underlyingString) {
fastFree(header);
} else {
if (!isMainThread()) {
callOnMainThread(deallocateOnMainThread, header);
} else {
underlyingString->deref();
fastFree(header);
}
}
}
static CFIndex preferredSize(CFIndex size, CFOptionFlags, void*)
{
return size;
}
static CFAllocatorRef create()
{
CFAllocatorContext context = { 0, 0, retain, release, copyDescription, allocate, reallocate, deallocate, preferredSize };
return CFAllocatorCreate(0, &context);
}
static CFAllocatorRef allocator()
{
static CFAllocatorRef allocator = create();
return allocator;
}
}
RetainPtr<CFStringRef> StringImpl::createCFString()
{
if (!m_length || !isMainThread()) {
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();
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);
StringWrapperCFAllocator::currentString = 0;
return adoptCF(string);
}
}
#endif