1/* 2 * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "ShareableResource.h" 28 29#include "ArgumentCoders.h" 30#include <WebCore/SharedBuffer.h> 31 32using namespace WebCore; 33 34namespace WebKit { 35 36ShareableResource::Handle::Handle() 37{ 38} 39 40void ShareableResource::Handle::encode(CoreIPC::ArgumentEncoder& encoder) const 41{ 42 encoder << m_handle; 43 encoder << m_offset; 44 encoder << m_size; 45} 46 47bool ShareableResource::Handle::decode(CoreIPC::ArgumentDecoder& decoder, Handle& handle) 48{ 49 if (!decoder.decode(handle.m_handle)) 50 return false; 51 if (!decoder.decode(handle.m_offset)) 52 return false; 53 if (!decoder.decode(handle.m_size)) 54 return false; 55 return true; 56} 57 58static void shareableResourceDeallocate(void *ptr, void *info) 59{ 60 (static_cast<ShareableResource*>(info))->deref(); // Balanced by ref() in createShareableResourceDeallocator() 61} 62 63static CFAllocatorRef createShareableResourceDeallocator(ShareableResource* resource) 64{ 65 resource->ref(); // Balanced by deref in shareableResourceDeallocate() 66 67 CFAllocatorContext context = { 0, 68 resource, 69 NULL, // retain 70 NULL, // release 71 NULL, // copyDescription 72 NULL, // allocate 73 NULL, // reallocate 74 shareableResourceDeallocate, 75 NULL, // preferredSize 76 }; 77 78 return CFAllocatorCreate(kCFAllocatorDefault, &context); 79} 80 81PassRefPtr<SharedBuffer> ShareableResource::Handle::tryWrapInSharedBuffer() const 82{ 83 RefPtr<ShareableResource> resource = ShareableResource::create(*this); 84 if (!resource) { 85 LOG_ERROR("Failed to recreate ShareableResource from handle."); 86 return 0; 87 } 88 89 RetainPtr<CFAllocatorRef> deallocator = adoptCF(createShareableResourceDeallocator(resource.get())); 90 RetainPtr<CFDataRef> data = adoptCF(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(resource->data()), static_cast<CFIndex>(resource->size()), deallocator.get())); 91 92 return SharedBuffer::wrapCFData(data.get()); 93} 94 95PassRefPtr<ShareableResource> ShareableResource::create(PassRefPtr<SharedMemory> sharedMemory, unsigned offset, unsigned size) 96{ 97 return adoptRef(new ShareableResource(sharedMemory, offset, size)); 98} 99 100PassRefPtr<ShareableResource> ShareableResource::create(const Handle& handle) 101{ 102 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle.m_handle, SharedMemory::ReadOnly); 103 if (!sharedMemory) 104 return 0; 105 106 return create(sharedMemory.release(), handle.m_offset, handle.m_size); 107} 108 109ShareableResource::ShareableResource(PassRefPtr<SharedMemory> sharedMemory, unsigned offset, unsigned size) 110 : m_sharedMemory(sharedMemory) 111 , m_offset(offset) 112 , m_size(size) 113{ 114 ASSERT(m_sharedMemory); 115 ASSERT(m_offset + m_size <= m_sharedMemory->size()); 116 117 // FIXME (NetworkProcess): This data was received from another process. If it is bogus, should we assume that process is compromised and we should kill it? 118} 119 120ShareableResource::~ShareableResource() 121{ 122} 123 124bool ShareableResource::createHandle(Handle& handle) 125{ 126 if (!m_sharedMemory->createHandle(handle.m_handle, SharedMemory::ReadOnly)) 127 return false; 128 129 handle.m_offset = m_offset; 130 handle.m_size = m_size; 131 132 return true; 133} 134 135const char* ShareableResource::data() const 136{ 137 return static_cast<const char*>(m_sharedMemory->data()) + m_offset; 138} 139 140unsigned ShareableResource::size() const 141{ 142 return m_size; 143} 144 145} // namespace WebKit 146