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; }
// 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); }
unsigned SharedBuffer::size() const { if (hasPlatformData()) return platformDataSize(); return m_size; }
const char* SharedBuffer::data() const { if (hasPlatformData()) return platformData(); if (m_purgeableBuffer) return m_purgeableBuffer->data(); return buffer().data(); }
unsigned SharedBuffer::size() const { if (hasPlatformData()) return platformDataSize(); if (m_purgeableBuffer) return m_purgeableBuffer->size(); return m_size; }
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(); }
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 }
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; }
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); }
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 }
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; }
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 }
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(); }
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(); }