15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/SharedBuffer.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/PurgeableBuffer.h" 317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/PassOwnPtr.h" 327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/unicode/Unicode.h" 337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/unicode/UTF8.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#undef SHARED_BUFFER_STATS 36521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 37521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 38521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/DataLog.h" 39521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/MainThread.h" 40521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 41521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const unsigned segmentSize = 0x1000; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const unsigned segmentPositionMask = 0x0FFF; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline unsigned segmentIndex(unsigned position) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return position / segmentSize; 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline unsigned offsetInSegment(unsigned position) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return position & segmentPositionMask; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline char* allocateSegment() 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return static_cast<char*>(fastMalloc(segmentSize)); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void freeSegment(char* p) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fastFree(p); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 69521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 70521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 71521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static Mutex& statsMutex() 72521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 73521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) DEFINE_STATIC_LOCAL(Mutex, mutex, ()); 74521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return mutex; 75521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 76521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 77521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static HashSet<SharedBuffer*>& liveBuffers() 78521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 79521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<SharedBuffer*>, buffers, ()); 80521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return buffers; 81521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 82521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 83521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static bool sizeComparator(SharedBuffer* a, SharedBuffer* b) 84521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 85521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return a->size() > b->size(); 86521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 87521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 88521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static CString snippetForBuffer(SharedBuffer* sharedBuffer) 89521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 90521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) const unsigned kMaxSnippetLength = 64; 91521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) char* snippet = 0; 92521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) unsigned snippetLength = std::min(sharedBuffer->size(), kMaxSnippetLength); 93521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) CString result = CString::newUninitialized(snippetLength, snippet); 94521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 95521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) const char* segment; 96521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) unsigned offset = 0; 97521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) while (unsigned segmentLength = sharedBuffer->getSomeData(segment, offset)) { 98521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) unsigned length = std::min(segmentLength, snippetLength - offset); 99521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) memcpy(snippet + offset, segment, length); 100521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) offset += segmentLength; 101521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (offset >= snippetLength) 102521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) break; 103521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 104521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 105521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) for (unsigned i = 0; i < snippetLength; ++i) { 106521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!isASCIIPrintable(snippet[i])) 107521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) snippet[i] = '?'; 108521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 109521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 110521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return result; 111521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 112521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 113521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static void printStats(void*) 114521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 115521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) MutexLocker locker(statsMutex()); 116521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) Vector<SharedBuffer*> buffers; 117521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) for (HashSet<SharedBuffer*>::const_iterator iter = liveBuffers().begin(); iter != liveBuffers().end(); ++iter) 118521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) buffers.append(*iter); 119521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) std::sort(buffers.begin(), buffers.end(), sizeComparator); 120521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 121521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) dataLogF("---- Shared Buffer Stats ----\n"); 122521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) for (size_t i = 0; i < buffers.size() && i < 64; ++i) { 123521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) CString snippet = snippetForBuffer(buffers[i]); 124521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) dataLogF("Buffer size=%8u %s\n", buffers[i]->size(), snippet.data()); 125521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 126521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 127521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 128521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static void didCreateSharedBuffer(SharedBuffer* buffer) 129521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 130521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) MutexLocker locker(statsMutex()); 131521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) liveBuffers().add(buffer); 132521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 133521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) callOnMainThread(printStats, 0); 134521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 135521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 136521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static void willDestroySharedBuffer(SharedBuffer* buffer) 137521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 138521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) MutexLocker locker(statsMutex()); 139521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) liveBuffers().remove(buffer); 140521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 141521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 142521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 143521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SharedBuffer::SharedBuffer() 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_size(0) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 147521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 148521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) didCreateSharedBuffer(this); 149521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SharedBuffer::SharedBuffer(size_t size) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_size(size) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_buffer(size) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 156521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 157521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) didCreateSharedBuffer(this); 158521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SharedBuffer::SharedBuffer(const char* data, int size) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_size(0) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Use unsigned consistently, and check for invalid casts when calling into SharedBuffer from other code. 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (size < 0) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CRASH(); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(data, size); 169521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 170521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 171521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) didCreateSharedBuffer(this); 172521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SharedBuffer::SharedBuffer(const unsigned char* data, int size) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_size(0) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Use unsigned consistently, and check for invalid casts when calling into SharedBuffer from other code. 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (size < 0) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CRASH(); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(reinterpret_cast<const char*>(data), size); 183521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 184521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 185521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) didCreateSharedBuffer(this); 186521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SharedBuffer::~SharedBuffer() 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clear(); 192521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 193521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifdef SHARED_BUFFER_STATS 194521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) willDestroySharedBuffer(this); 195521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<SharedBuffer> SharedBuffer::adoptVector(Vector<char>& vector) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<SharedBuffer> buffer = create(); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer->m_buffer.swap(vector); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer->m_size = buffer->m_buffer.size(); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return buffer.release(); 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20602772c6a72f1ee0b226341a4f4439970c29fc861Ben MurdochPassRefPtr<SharedBuffer> SharedBuffer::adoptPurgeableBuffer(PassOwnPtr<PurgeableBuffer> purgeableBuffer) 20702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!purgeableBuffer->isPurgeable()); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<SharedBuffer> buffer = create(); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buffer->m_purgeableBuffer = purgeableBuffer; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return buffer.release(); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned SharedBuffer::size() const 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_purgeableBuffer) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_purgeableBuffer->size(); 21802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_size; 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SharedBuffer::createPurgeableBuffer() const 223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_purgeableBuffer) 225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_purgeableBuffer = PurgeableBuffer::create(buffer().data(), m_size); 228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* SharedBuffer::data() const 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_purgeableBuffer) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_purgeableBuffer->data(); 23402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return this->buffer().data(); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 238e6d4491e48613634a83c1957c72759da80987961Ben Murdochvoid SharedBuffer::moveTo(Vector<char>& result) 239e6d4491e48613634a83c1957c72759da80987961Ben Murdoch{ 240e6d4491e48613634a83c1957c72759da80987961Ben Murdoch ASSERT(result.isEmpty()); 241e6d4491e48613634a83c1957c72759da80987961Ben Murdoch if (m_purgeableBuffer) { 242e6d4491e48613634a83c1957c72759da80987961Ben Murdoch result.reserveCapacity(m_purgeableBuffer->size()); 243e6d4491e48613634a83c1957c72759da80987961Ben Murdoch result.append(m_purgeableBuffer->data(), m_purgeableBuffer->size()); 244e6d4491e48613634a83c1957c72759da80987961Ben Murdoch clear(); 245e6d4491e48613634a83c1957c72759da80987961Ben Murdoch return; 246e6d4491e48613634a83c1957c72759da80987961Ben Murdoch } 247e6d4491e48613634a83c1957c72759da80987961Ben Murdoch 248e6d4491e48613634a83c1957c72759da80987961Ben Murdoch unsigned bufferSize = m_buffer.size(); 249e6d4491e48613634a83c1957c72759da80987961Ben Murdoch if (m_size == bufferSize) { 250e6d4491e48613634a83c1957c72759da80987961Ben Murdoch m_buffer.swap(result); 251e6d4491e48613634a83c1957c72759da80987961Ben Murdoch clear(); 252e6d4491e48613634a83c1957c72759da80987961Ben Murdoch return; 253e6d4491e48613634a83c1957c72759da80987961Ben Murdoch } 254e6d4491e48613634a83c1957c72759da80987961Ben Murdoch 255e6d4491e48613634a83c1957c72759da80987961Ben Murdoch result.reserveCapacity(m_size); 256e6d4491e48613634a83c1957c72759da80987961Ben Murdoch 257e6d4491e48613634a83c1957c72759da80987961Ben Murdoch const char* segment = 0; 258e6d4491e48613634a83c1957c72759da80987961Ben Murdoch unsigned position = 0; 259e6d4491e48613634a83c1957c72759da80987961Ben Murdoch while (unsigned segmentSize = getSomeData(segment, position)) { 260e6d4491e48613634a83c1957c72759da80987961Ben Murdoch result.append(segment, segmentSize); 261e6d4491e48613634a83c1957c72759da80987961Ben Murdoch position += segmentSize; 262e6d4491e48613634a83c1957c72759da80987961Ben Murdoch } 263e6d4491e48613634a83c1957c72759da80987961Ben Murdoch ASSERT(result.size() == m_size); 264e6d4491e48613634a83c1957c72759da80987961Ben Murdoch clear(); 265e6d4491e48613634a83c1957c72759da80987961Ben Murdoch return; 266e6d4491e48613634a83c1957c72759da80987961Ben Murdoch} 267e6d4491e48613634a83c1957c72759da80987961Ben Murdoch 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SharedBuffer::append(SharedBuffer* data) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* segment; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t position = 0; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (size_t length = data->getSomeData(segment, position)) { 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(segment, length); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) position += length; 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SharedBuffer::append(const char* data, unsigned length) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_purgeableBuffer); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!length) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned positionInSegment = offsetInSegment(m_size - m_buffer.size()); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_size += length; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_size <= segmentSize) { 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // No need to use segments for small resource data 289926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_buffer.isEmpty()) 290926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_buffer.reserveInitialCapacity(length); 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_buffer.append(data, length); 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) char* segment; 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!positionInSegment) { 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) segment = allocateSegment(); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_segments.append(segment); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) segment = m_segments.last() + positionInSegment; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned segmentFreeSpace = segmentSize - positionInSegment; 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned bytesToCopy = min(length, segmentFreeSpace); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (;;) { 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(segment, data, bytesToCopy); 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (static_cast<unsigned>(length) == bytesToCopy) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) length -= bytesToCopy; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data += bytesToCopy; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) segment = allocateSegment(); 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_segments.append(segment); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bytesToCopy = min(length, segmentSize); 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SharedBuffer::append(const Vector<char>& data) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(data.data(), data.size()); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SharedBuffer::clear() 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_segments.size(); ++i) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) freeSegment(m_segments[i]); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_segments.clear(); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_size = 0; 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_buffer.clear(); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_purgeableBuffer.clear(); 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<SharedBuffer> SharedBuffer::copy() const 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer)); 33853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (m_purgeableBuffer) { 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clone->append(data(), size()); 340e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return clone.release(); 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clone->m_size = m_size; 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clone->m_buffer.reserveCapacity(m_size); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clone->m_buffer.append(m_buffer.data(), m_buffer.size()); 346e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!m_segments.isEmpty()) { 347e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch const char* segment = 0; 348e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch unsigned position = m_buffer.size(); 349e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch while (unsigned segmentSize = getSomeData(segment, position)) { 350e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch clone->m_buffer.append(segment, segmentSize); 351e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch position += segmentSize; 352e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 353e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(position == clone->size()); 354e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 355e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return clone.release(); 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassOwnPtr<PurgeableBuffer> SharedBuffer::releasePurgeableBuffer() 35902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 36002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch ASSERT(hasOneRef()); 36102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch return m_purgeableBuffer.release(); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const Vector<char>& SharedBuffer::buffer() const 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned bufferSize = m_buffer.size(); 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_size > bufferSize) { 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_buffer.resize(m_size); 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) char* destination = m_buffer.data() + bufferSize; 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned bytesLeft = m_size - bufferSize; 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_segments.size(); ++i) { 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned bytesToCopy = min(bytesLeft, segmentSize); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(destination, m_segments[i], bytesToCopy); 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination += bytesToCopy; 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bytesLeft -= bytesToCopy; 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) freeSegment(m_segments[i]); 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_segments.clear(); 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_buffer; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned totalSize = size(); 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (position >= totalSize) { 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) someData = 0; 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 39153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (m_purgeableBuffer) { 392926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(position < size()); 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) someData = data() + position; 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return totalSize - position; 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 397926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(position < m_size); 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned consecutiveSize = m_buffer.size(); 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (position < consecutiveSize) { 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) someData = m_buffer.data() + position; 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return consecutiveSize - position; 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 40302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) position -= consecutiveSize; 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned segments = m_segments.size(); 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned maxSegmentedSize = segments * segmentSize; 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned segment = segmentIndex(position); 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (segment < segments) { 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned bytesLeft = totalSize - consecutiveSize; 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned segmentedSize = min(maxSegmentedSize, bytesLeft); 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned positionInSegment = offsetInSegment(position); 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) someData = m_segments[segment] + positionInSegment; 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment; 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)PassRefPtr<ArrayBuffer> SharedBuffer::getAsArrayBuffer() const 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::createUninitialized(static_cast<unsigned>(size()), 1); 4235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 4245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) const char* segment = 0; 4255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) unsigned position = 0; 4265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) while (unsigned segmentSize = getSomeData(segment, position)) { 4275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment, segmentSize); 4285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) position += segmentSize; 4295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 4305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 4315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (position != arrayBuffer->byteLength()) { 4325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ASSERT_NOT_REACHED(); 4335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // Don't return the incomplete ArrayBuffer. 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return arrayBuffer; 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 441