unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
{
    if (hasPlatformData() || m_purgeableBuffer) {
        someData = data() + position;
        return size() - position;
    }

    if (position >= m_size) {
        someData = 0;
        return 0;
    }

    unsigned consecutiveSize = m_buffer.size();
    if (position < consecutiveSize) {
        someData = m_buffer.data() + position;
        return consecutiveSize - position;
    }
 
    position -= consecutiveSize;
    unsigned segmentedSize = m_size - consecutiveSize;
    unsigned segments = m_segments.size();
    unsigned segment = segmentIndex(position);
    ASSERT(segment < segments);

    unsigned positionInSegment = offsetInSegment(position);
    someData = m_segments[segment] + positionInSegment;
    return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
}
Esempio n. 2
0
// Try to create a PurgeableBuffer. We can fail to create one for any of the
// following reasons:
//   - shouldUsePurgeableMemory is set to false.
//   - the size of the buffer is less than the minimum size required by
//     PurgeableBuffer (currently 16k).
//   - PurgeableBuffer::createUninitialized() call fails.
void SharedBuffer::createPurgeableBuffer() const
{
    if (m_purgeableBuffer)
        return;

    if (hasPlatformData())
        return;

#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    if (singleDataArrayBuffer())
        return;
#endif

    if (!m_buffer->hasOneRef())
        return;

    if (!m_shouldUsePurgeableMemory)
        return;

    char* destination = 0;
    m_purgeableBuffer = PurgeableBuffer::createUninitialized(m_size, destination);
    if (!m_purgeableBuffer)
        return;
    unsigned bufferSize = m_buffer->data.size();
    if (bufferSize) {
        memcpy(destination, m_buffer->data.data(), bufferSize);
        destination += bufferSize;
        (const_cast<SharedBuffer*>(this))->clearDataBuffer();
    }
    copyBufferAndClear(destination, m_size - bufferSize);
}
Esempio n. 3
0
unsigned SharedBuffer::size() const
{
    if (hasPlatformData())
        return platformDataSize();
    
    return m_size;
}
Esempio n. 4
0
const char* SharedBuffer::data() const
{
    if (hasPlatformData())
        return platformData();
    
    if (m_purgeableBuffer)
        return m_purgeableBuffer->data();
    
    return buffer().data();
}
Esempio n. 5
0
unsigned SharedBuffer::size() const
{
    if (hasPlatformData())
        return platformDataSize();
    
    if (m_purgeableBuffer)
        return m_purgeableBuffer->size();
    
    return m_size;
}
Esempio n. 6
0
const char* SharedBuffer::data() const
{

    if (hasPlatformData())
        return platformData();

#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    if (const char* buffer = singleDataArrayBuffer())
        return buffer;
#endif

    return this->buffer().data();
}
Esempio n. 7
0
unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
{
    unsigned totalSize = size();
    if (position >= totalSize) {
        someData = 0;
        return 0;
    }

#if ENABLE(DISK_IMAGE_CACHE)
    ASSERT(position < size());
    if (isMemoryMapped()) {
        const char* data = static_cast<const char*>(diskImageCache().dataForItem(m_diskImageCacheId));
        someData = data + position;
        return size() - position;
    }
#endif

    if (hasPlatformData() || m_purgeableBuffer) {
        ASSERT_WITH_SECURITY_IMPLICATION(position < size());
        someData = data() + position;
        return totalSize - position;
    }

    ASSERT_WITH_SECURITY_IMPLICATION(position < m_size);
    unsigned consecutiveSize = m_buffer->data.size();
    if (position < consecutiveSize) {
        someData = m_buffer->data.data() + position;
        return consecutiveSize - position;
    }
 
    position -= consecutiveSize;
#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    unsigned segments = m_segments.size();
    unsigned maxSegmentedSize = segments * segmentSize;
    unsigned segment = segmentIndex(position);
    if (segment < segments) {
        unsigned bytesLeft = totalSize - consecutiveSize;
        unsigned segmentedSize = std::min(maxSegmentedSize, bytesLeft);

        unsigned positionInSegment = offsetInSegment(position);
        someData = m_segments[segment] + positionInSegment;
        return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
    }
    ASSERT_NOT_REACHED();
    return 0;
#else
    return copySomeDataFromDataArray(someData, position);
#endif
}
Esempio n. 8
0
PassRefPtr<SharedBuffer> SharedBuffer::copy() const
{
    RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer));
    if (m_purgeableBuffer || hasPlatformData()) {
        clone->append(data(), size());
        return clone;
    }

    clone->m_size = m_size;
    clone->m_buffer.reserveCapacity(m_size);
    clone->m_buffer.append(m_buffer.data(), m_buffer.size());
    for (unsigned i = 0; i < m_segments.size(); ++i)
        clone->m_buffer.append(m_segments[i], segmentSize);
    return clone;
}
Esempio n. 9
0
void SharedBuffer::createPurgeableBuffer() const
{
    if (m_purgeableBuffer)
        return;

    if (hasPlatformData())
        return;

#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    if (singleDataArrayBuffer())
        return;
#endif

    m_purgeableBuffer = PurgeableBuffer::create(buffer().data(), m_size);
}
Esempio n. 10
0
unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
{
    unsigned totalSize = size();
    if (position >= totalSize) {
        someData = 0;
        return 0;
    }

    if (hasPlatformData() || m_purgeableBuffer) {
        ASSERT(position < size());
        someData = data() + position;
        return totalSize - position;
    }

    ASSERT(position < m_size);
    unsigned consecutiveSize = m_buffer.size();
    if (position < consecutiveSize) {
        someData = m_buffer.data() + position;
        return consecutiveSize - position;
    }
 
    position -= consecutiveSize;
    unsigned segments = m_segments.size();
    unsigned maxSegmentedSize = segments * segmentSize;
    unsigned segment = segmentIndex(position);
    if (segment < segments) {
        unsigned bytesLeft = totalSize - consecutiveSize;
        unsigned segmentedSize = min(maxSegmentedSize, bytesLeft);

        unsigned positionInSegment = offsetInSegment(position);
        someData = m_segments[segment] + positionInSegment;
        return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
    }
#if HAVE(NETWORK_CFDATA_ARRAY_CALLBACK)
    ASSERT(maxSegmentedSize <= position);
    position -= maxSegmentedSize;
    return copySomeDataFromDataArray(someData, position);
#else
    ASSERT_NOT_REACHED();
    return 0;
#endif
}
Esempio n. 11
0
PassRefPtr<SharedBuffer> SharedBuffer::copy() const
{
    RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer));
    if (m_purgeableBuffer || hasPlatformData()) {
        clone->append(data(), size());
        return clone;
    }

    clone->m_size = m_size;
    clone->m_buffer->data.reserveCapacity(m_size);
    clone->m_buffer->data.append(m_buffer->data.data(), m_buffer->data.size());
#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    for (unsigned i = 0; i < m_segments.size(); ++i)
        clone->m_buffer->data.append(m_segments[i], segmentSize);
#else
    for (unsigned i = 0; i < m_dataArray.size(); ++i)
        clone->append(m_dataArray[i].get());
#endif
    return clone;
}
Esempio n. 12
0
unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
{
    unsigned totalSize = size();
    if (position >= totalSize) {
        someData = 0;
        return 0;
    }

    if (hasPlatformData()) {
        ASSERT_WITH_SECURITY_IMPLICATION(position < size());
        someData = data() + position;
        return totalSize - position;
    }

    ASSERT_WITH_SECURITY_IMPLICATION(position < m_size);
    unsigned consecutiveSize = m_buffer->data.size();
    if (position < consecutiveSize) {
        someData = m_buffer->data.data() + position;
        return consecutiveSize - position;
    }
 
    position -= consecutiveSize;
#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    unsigned segments = m_segments.size();
    unsigned maxSegmentedSize = segments * segmentSize;
    unsigned segment = segmentIndex(position);
    if (segment < segments) {
        unsigned bytesLeft = totalSize - consecutiveSize;
        unsigned segmentedSize = std::min(maxSegmentedSize, bytesLeft);

        unsigned positionInSegment = offsetInSegment(position);
        someData = m_segments[segment] + positionInSegment;
        return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
    }
    ASSERT_NOT_REACHED();
    return 0;
#else
    return copySomeDataFromDataArray(someData, position);
#endif
}
Esempio n. 13
0
const char* SharedBuffer::data() const
{
#if ENABLE(DISK_IMAGE_CACHE)
    if (isMemoryMapped())
        return static_cast<const char*>(diskImageCache().dataForItem(m_diskImageCacheId));
#endif

    if (hasPlatformData())
        return platformData();

#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    if (const char* buffer = singleDataArrayBuffer())
        return buffer;
#endif

    createPurgeableBuffer();

    if (m_purgeableBuffer)
        return m_purgeableBuffer->data();
    
    return this->buffer().data();
}
Esempio n. 14
0
PassRefPtr<SharedBuffer> SharedBuffer::copy() const
{
    RefPtr<SharedBuffer> clone { adoptRef(*new SharedBuffer) };
    if (hasPlatformData()) {
        clone->append(data(), size());
        return clone.release();
    }

    clone->m_size = m_size;
    clone->m_buffer->data.reserveCapacity(m_size);
    clone->m_buffer->data.append(m_buffer->data.data(), m_buffer->data.size());

#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    for (char* segment : m_segments)
        clone->m_buffer->data.append(segment, segmentSize);
#else
    for (auto& data : m_dataArray)
        clone->m_dataArray.append(data.get());
#endif
    ASSERT(clone->size() == size());

    return clone.release();
}