1/* 2 * Copyright (C) 2006 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "SharedBuffer.h" 28 29#include "WebCoreObjCExtras.h" 30#include <runtime/InitializeThreading.h> 31#include <string.h> 32#include <wtf/MainThread.h> 33#include <wtf/PassRefPtr.h> 34 35using namespace WebCore; 36 37@interface WebCoreSharedBufferData : NSData 38{ 39 RefPtr<SharedBuffer::DataBuffer> sharedBufferDataBuffer; 40#if ENABLE(DISK_IMAGE_CACHE) 41 RefPtr<SharedBuffer> sharedBuffer; 42#endif 43} 44 45- (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer; 46#if ENABLE(DISK_IMAGE_CACHE) 47- (id)initWithMemoryMappedSharedBuffer:(SharedBuffer&)memoryMappedSharedBuffer; 48#endif 49@end 50 51@implementation WebCoreSharedBufferData 52 53+ (void)initialize 54{ 55#if !USE(WEB_THREAD) 56 JSC::initializeThreading(); 57 WTF::initializeMainThreadToProcessMainThread(); 58#endif // !USE(WEB_THREAD) 59 WebCoreObjCFinalizeOnMainThread(self); 60} 61 62- (void)dealloc 63{ 64 if (WebCoreObjCScheduleDeallocateOnMainThread([WebCoreSharedBufferData class], self)) 65 return; 66 67 [super dealloc]; 68} 69 70- (void)finalize 71{ 72 [super finalize]; 73} 74 75- (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer 76{ 77 self = [super init]; 78 79 if (self) 80 sharedBufferDataBuffer = dataBuffer; 81 82 return self; 83} 84 85#if ENABLE(DISK_IMAGE_CACHE) 86- (id)initWithMemoryMappedSharedBuffer:(SharedBuffer&)memoryMappedSharedBuffer 87{ 88 ASSERT(memoryMappedSharedBuffer.isMemoryMapped()); 89 self = [super init]; 90 91 if (!self) 92 return nil; 93 94 sharedBuffer = &memoryMappedSharedBuffer; 95 return self; 96} 97#endif 98 99- (NSUInteger)length 100{ 101#if ENABLE(DISK_IMAGE_CACHE) 102 if (sharedBuffer) 103 return sharedBuffer->size(); 104#endif 105 return sharedBufferDataBuffer->data.size(); 106} 107 108- (const void *)bytes 109{ 110#if ENABLE(DISK_IMAGE_CACHE) 111 if (sharedBuffer) 112 return sharedBuffer->data(); 113#endif 114 return sharedBufferDataBuffer->data.data(); 115} 116 117@end 118 119namespace WebCore { 120 121PassRefPtr<SharedBuffer> SharedBuffer::wrapNSData(NSData *nsData) 122{ 123 return adoptRef(new SharedBuffer((CFDataRef)nsData)); 124} 125 126RetainPtr<NSData> SharedBuffer::createNSData() 127{ 128 return adoptNS((NSData *)createCFData().leakRef()); 129} 130 131CFDataRef SharedBuffer::existingCFData() 132{ 133 if (m_cfData) 134 return m_cfData.get(); 135 136#if USE(NETWORK_CFDATA_ARRAY_CALLBACK) 137 if (m_dataArray.size() == 1) 138 return m_dataArray.at(0).get(); 139#endif 140 141 return nullptr; 142} 143 144RetainPtr<CFDataRef> SharedBuffer::createCFData() 145{ 146 if (CFDataRef cfData = existingCFData()) 147 return cfData; 148 149#if ENABLE(DISK_IMAGE_CACHE) 150 if (isMemoryMapped()) 151 return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithMemoryMappedSharedBuffer:*this]).leakRef()); 152#endif 153 154 data(); // Force data into m_buffer from segments or data array. 155 if (hasPurgeableBuffer()) { 156 RefPtr<SharedBuffer::DataBuffer> copiedBuffer = adoptRef(new DataBuffer); 157 copiedBuffer->data.append(data(), size()); 158 return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:copiedBuffer.get()]).leakRef()); 159 } 160 161 return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.get()]).leakRef()); 162} 163 164PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath) 165{ 166 NSData *resourceData = [NSData dataWithContentsOfFile:filePath]; 167 if (resourceData) 168 return SharedBuffer::wrapNSData(resourceData); 169 return 0; 170} 171 172} 173