Reduce copies and allocations in SharedBuffer::append
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Apr 2017 17:31:05 +0000 (17:31 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Apr 2017 17:31:05 +0000 (17:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170956

Reviewed by Andreas Kling.

Source/JavaScriptCore:

* runtime/ArrayBuffer.h:

Source/WebCore:

SharedBuffer was a mess of different data structures added over the years.
SharedBuffer::append would allocate large Vector<char>s and call memcpy, and that
is inefficient and causes crashes when large allocations fail, and the allocations
and copies aren't even necessary.  There were also const correctness problems in
ResourceLoader::addDataOrBuffer, and iterating a SharedBuffer was strange because
sometimes we don't want to add unnecessary copies.

These problems are solved by making SharedBuffer a Vector of read-only data segments,
which can be contained in various ways but we don't care because all we want to do is
read them.  Appending SharedBuffers is now const correct because we just add to a
Vector<Ref<DataSegment>> and neither SharedBuffer can write to the data.  Sometimes,
though, we want all the data to be in continuous memory, and if there are multiple
segments then the data needs to be copied once to a new segment.  We should audit the
call sites of SharedBuffer::data and see if this is really necessary.

No change in functional behavior.  Fewer copies of the data are made when buffering
data in the NetworkProcess.  No extra memory is allocated for bytes we think we might
need to append in the future.  Data is now only copied into one buffer lazily as needed,
which could slightly change when small delays from memcpy happen, but it's an overall
improvement.  We could have a performance hit if we were to call append() then data()
then append() then data() etc. but that doesn't happen in WebKit because we call append
repeatedly when buffering the data then call data() once when reading the data.

* editing/cocoa/EditorCocoa.mm:
(WebCore::archivedDataForAttributedString):
(WebCore::Editor::selectionInWebArchiveFormat):
(WebCore::Editor::dataInRTFDFormat):
(WebCore::Editor::dataInRTFFormat):
* editing/ios/EditorIOS.mm:
(WebCore::Editor::WebContentReader::readURL):
* editing/mac/EditorMac.mm:
(WebCore::Editor::imageInWebArchiveFormat):
* loader/TextTrackLoader.cpp:
(WebCore::TextTrackLoader::processNewCueData):
* loader/archive/cf/LegacyWebArchive.cpp:
(WebCore::LegacyWebArchive::createResource):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::tryReplaceEncodedData):
* loader/cocoa/DiskCacheMonitorCocoa.mm:
(WebCore::DiskCacheMonitor::tryGetFileBackedSharedBufferFromCFURLCachedResponse):
* platform/SharedBuffer.cpp:
(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::combineToOneSegment):
(WebCore::SharedBuffer::data):
(WebCore::SharedBuffer::createArrayBuffer):
(WebCore::SharedBuffer::append):
(WebCore::SharedBuffer::clear):
(WebCore::SharedBuffer::copy):
(WebCore::SharedBuffer::DataSegment::data):
(WebCore::SharedBuffer::DataSegment::size):
(WebCore::segmentIndex): Deleted.
(WebCore::offsetInSegment): Deleted.
(WebCore::allocateSegment): Deleted.
(WebCore::freeSegment): Deleted.
(WebCore::SharedBuffer::~SharedBuffer): Deleted.
(WebCore::SharedBuffer::size): Deleted.
(WebCore::SharedBuffer::duplicateDataBufferIfNecessary): Deleted.
(WebCore::SharedBuffer::appendToDataBuffer): Deleted.
(WebCore::SharedBuffer::clearDataBuffer): Deleted.
(WebCore::SharedBuffer::copyBufferAndClear): Deleted.
(WebCore::SharedBuffer::buffer): Deleted.
(WebCore::SharedBuffer::getSomeData): Deleted.
(WebCore::SharedBuffer::maybeTransferMappedFileData): Deleted.
(WebCore::SharedBuffer::clearPlatformData): Deleted.
(WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
(WebCore::SharedBuffer::hasPlatformData): Deleted.
(WebCore::SharedBuffer::platformData): Deleted.
(WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
* platform/SharedBuffer.h:
(WebCore::SharedBuffer::create): Deleted.
(WebCore::SharedBuffer::isEmpty): Deleted.
* platform/SharedBufferChunkReader.cpp:
(WebCore::SharedBufferChunkReader::nextChunk):
(WebCore::SharedBufferChunkReader::peek):
* platform/SharedBufferChunkReader.h:
* platform/URLParser.cpp:
(WebCore::URLParser::URLParser):
* platform/cf/KeyedEncoderCF.cpp:
(WebCore::KeyedEncoderCF::finishEncoding):
* platform/cf/SharedBufferCF.cpp:
(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::createCFData):
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::hintMemoryNotNeededSoon):
(WebCore::SharedBuffer::append):
(WebCore::SharedBuffer::wrapCFData): Deleted.
(WebCore::SharedBuffer::hasPlatformData): Deleted.
(WebCore::SharedBuffer::platformData): Deleted.
(WebCore::SharedBuffer::platformDataSize): Deleted.
(WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
(WebCore::SharedBuffer::clearPlatformData): Deleted.
(WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.
(WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
(WebCore::SharedBuffer::copyBufferAndClear): Deleted.
(WebCore::SharedBuffer::copySomeDataFromDataArray): Deleted.
(WebCore::SharedBuffer::singleDataArrayBuffer): Deleted.
(WebCore::SharedBuffer::maybeAppendDataArray): Deleted.
* platform/cocoa/NetworkExtensionContentFilter.mm:
(WebCore::NetworkExtensionContentFilter::replacementData):
* platform/cocoa/ParentalControlsContentFilter.mm:
(WebCore::ParentalControlsContentFilter::replacementData):
* platform/cocoa/SharedBufferCocoa.mm:
(-[WebCoreSharedBufferData initWithSharedBufferDataSegment:]):
(-[WebCoreSharedBufferData length]):
(-[WebCoreSharedBufferData bytes]):
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::createCFData):
(WebCore::SharedBuffer::createFromReadingFile):
(WebCore::SharedBuffer::createNSDataArray):
(-[WebCoreSharedBufferData initWithSharedBufferDataBuffer:]): Deleted.
(WebCore::SharedBuffer::wrapNSData): Deleted.
(WebCore::SharedBuffer::existingCFData): Deleted.
* platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
(WebCore::WebCoreAVFResourceLoader::fulfillRequestWithResource):
* platform/graphics/cocoa/FontPlatformDataCocoa.mm:
(WebCore::FontPlatformData::openTypeTable):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(ResourceHandleStreamingClient::didReceiveBuffer):
* platform/graphics/mac/ImageMac.mm:
(WebCore::Image::loadPlatformResource):
* platform/image-decoders/ImageDecoder.cpp:
(WebCore::ImageDecoder::create):
* platform/image-decoders/png/PNGImageDecoder.cpp:
(WebCore::PNGImageReader::decode):
* platform/ios/PlatformPasteboardIOS.mm:
(WebCore::PlatformPasteboard::readBuffer):
* platform/mac/PasteboardMac.mm:
(WebCore::writeFileWrapperAsRTFDAttachment):
(WebCore::Pasteboard::write):
* platform/mac/PlatformPasteboardMac.mm:
(WebCore::PlatformPasteboard::bufferForType):
* platform/network/BlobResourceHandle.cpp:
(WebCore::BlobResourceHandle::notifyReceiveData):
* platform/network/MIMEHeader.cpp:
* platform/network/MIMEHeader.h:
* platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp:
(WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData):
* platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp:
(WebCore::SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData):
* platform/network/mac/WebCoreResourceHandleAsDelegate.mm:
(-[WebCoreResourceHandleAsDelegate connection:didReceiveData:lengthReceived:]):
* platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm:
(-[WebCoreResourceHandleAsOperationQueueDelegate connection:didReceiveData:lengthReceived:]):
* platform/soup/SharedBufferSoup.cpp:
(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::createSoupBuffer):
(WebCore::SharedBuffer::clearPlatformData): Deleted.
(WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
(WebCore::SharedBuffer::hasPlatformData): Deleted.
(WebCore::SharedBuffer::platformData): Deleted.
(WebCore::SharedBuffer::platformDataSize): Deleted.
(WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
(WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.

Source/WebKit/mac:

* WebView/WebArchive.mm:
(-[WebArchive initWithData:]):
* WebView/WebFrame.mm:
(-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
* WebView/WebResource.mm:
(-[WebResource initWithCoder:]):
(-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]):

Source/WebKit2:

* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
* Platform/IPC/DataReference.cpp:
(IPC::SharedBufferDataReference::encode):
* Shared/ShareableResource.cpp:
(WebKit::ShareableResource::wrapInSharedBuffer):
* UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm:
(-[WKURLSchemeHandlerTaskImpl didReceiveData:]):
* WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
(-[WKWebProcessPlugInBrowserContextController _setEditingDelegate:]):
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::addArchiveResource):
(WebKit::PDFPlugin::liveResourceData):
(WebKit::PDFPlugin::writeItemsToPasteboard):
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::redeliverManualStream):
* WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
(WebKit::WebDragClient::declareAndWriteDragImage):
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::cachedResponseDataForURL):

Tools:

* TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm:
(TestWebKitAPI::TEST_F):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215686 268f45cc-cd09-0410-ab3c-d52691b4dbfc

58 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/ArrayBuffer.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp
Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp
Source/WebCore/Modules/fetch/FetchResponse.cpp
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/editing/cocoa/EditorCocoa.mm
Source/WebCore/editing/ios/EditorIOS.mm
Source/WebCore/editing/mac/EditorMac.mm
Source/WebCore/loader/TextTrackLoader.cpp
Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/loader/cocoa/DiskCacheMonitorCocoa.mm
Source/WebCore/platform/SharedBuffer.cpp
Source/WebCore/platform/SharedBuffer.h
Source/WebCore/platform/SharedBufferChunkReader.cpp
Source/WebCore/platform/SharedBufferChunkReader.h
Source/WebCore/platform/cf/KeyedEncoderCF.cpp
Source/WebCore/platform/cf/SharedBufferCF.cpp
Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm
Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm
Source/WebCore/platform/cocoa/SharedBufferCocoa.mm
Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm
Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
Source/WebCore/platform/graphics/mac/ImageMac.mm
Source/WebCore/platform/image-decoders/ImageDecoder.cpp
Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
Source/WebCore/platform/ios/PlatformPasteboardIOS.mm
Source/WebCore/platform/mac/PasteboardMac.mm
Source/WebCore/platform/mac/PlatformPasteboardMac.mm
Source/WebCore/platform/network/BlobResourceHandle.cpp
Source/WebCore/platform/network/MIMEHeader.cpp
Source/WebCore/platform/network/MIMEHeader.h
Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp
Source/WebCore/platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp
Source/WebCore/platform/network/mac/WebCoreResourceHandleAsDelegate.mm
Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm
Source/WebCore/platform/soup/SharedBufferSoup.cpp
Source/WebCore/xml/XMLHttpRequest.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebArchive.mm
Source/WebKit/mac/WebView/WebFrame.mm
Source/WebKit/mac/WebView/WebResource.mm
Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm
Source/WebKit2/Platform/IPC/DataReference.cpp
Source/WebKit2/Shared/ShareableResource.cpp
Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm
Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm
Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm
Source/WebKit2/WebProcess/Plugins/PluginView.cpp
Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp
Tools/TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm

index 96cfa1a..9de66cc 100644 (file)
@@ -1,3 +1,12 @@
+2017-04-24  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce copies and allocations in SharedBuffer::append
+        https://bugs.webkit.org/show_bug.cgi?id=170956
+
+        Reviewed by Andreas Kling.
+
+        * runtime/ArrayBuffer.h:
+
 2017-04-24  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Switch to use ENABLE_REMOTE_INSPECTOR instead of ENABLE_INSPECTOR_SERVER for the remote inspector
index 46ffdb5..af24b33 100644 (file)
@@ -110,7 +110,7 @@ public:
     JS_EXPORT_PRIVATE static RefPtr<ArrayBuffer> tryCreate(ArrayBuffer&);
     JS_EXPORT_PRIVATE static RefPtr<ArrayBuffer> tryCreate(const void* source, unsigned byteLength);
 
-    // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::createArrayBuffer.
+    // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::tryCreateArrayBuffer.
     JS_EXPORT_PRIVATE static Ref<ArrayBuffer> createUninitialized(unsigned numElements, unsigned elementByteSize);
     JS_EXPORT_PRIVATE static RefPtr<ArrayBuffer> tryCreateUninitialized(unsigned numElements, unsigned elementByteSize);
 
index 8cd139c..bc9520f 100644 (file)
@@ -1,3 +1,165 @@
+2017-04-24  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce copies and allocations in SharedBuffer::append
+        https://bugs.webkit.org/show_bug.cgi?id=170956
+
+        Reviewed by Andreas Kling.
+
+        SharedBuffer was a mess of different data structures added over the years.
+        SharedBuffer::append would allocate large Vector<char>s and call memcpy, and that
+        is inefficient and causes crashes when large allocations fail, and the allocations
+        and copies aren't even necessary.  There were also const correctness problems in
+        ResourceLoader::addDataOrBuffer, and iterating a SharedBuffer was strange because
+        sometimes we don't want to add unnecessary copies.
+
+        These problems are solved by making SharedBuffer a Vector of read-only data segments,
+        which can be contained in various ways but we don't care because all we want to do is
+        read them.  Appending SharedBuffers is now const correct because we just add to a
+        Vector<Ref<DataSegment>> and neither SharedBuffer can write to the data.  Sometimes,
+        though, we want all the data to be in continuous memory, and if there are multiple
+        segments then the data needs to be copied once to a new segment.  We should audit the
+        call sites of SharedBuffer::data and see if this is really necessary.
+
+        No change in functional behavior.  Fewer copies of the data are made when buffering
+        data in the NetworkProcess.  No extra memory is allocated for bytes we think we might
+        need to append in the future.  Data is now only copied into one buffer lazily as needed,
+        which could slightly change when small delays from memcpy happen, but it's an overall
+        improvement.  We could have a performance hit if we were to call append() then data()
+        then append() then data() etc. but that doesn't happen in WebKit because we call append
+        repeatedly when buffering the data then call data() once when reading the data.
+
+        * editing/cocoa/EditorCocoa.mm:
+        (WebCore::archivedDataForAttributedString):
+        (WebCore::Editor::selectionInWebArchiveFormat):
+        (WebCore::Editor::dataInRTFDFormat):
+        (WebCore::Editor::dataInRTFFormat):
+        * editing/ios/EditorIOS.mm:
+        (WebCore::Editor::WebContentReader::readURL):
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::imageInWebArchiveFormat):
+        * loader/TextTrackLoader.cpp:
+        (WebCore::TextTrackLoader::processNewCueData):
+        * loader/archive/cf/LegacyWebArchive.cpp:
+        (WebCore::LegacyWebArchive::createResource):
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::tryReplaceEncodedData):
+        * loader/cocoa/DiskCacheMonitorCocoa.mm:
+        (WebCore::DiskCacheMonitor::tryGetFileBackedSharedBufferFromCFURLCachedResponse):
+        * platform/SharedBuffer.cpp:
+        (WebCore::SharedBuffer::SharedBuffer):
+        (WebCore::SharedBuffer::create):
+        (WebCore::SharedBuffer::combineToOneSegment):
+        (WebCore::SharedBuffer::data):
+        (WebCore::SharedBuffer::createArrayBuffer):
+        (WebCore::SharedBuffer::append):
+        (WebCore::SharedBuffer::clear):
+        (WebCore::SharedBuffer::copy):
+        (WebCore::SharedBuffer::DataSegment::data):
+        (WebCore::SharedBuffer::DataSegment::size):
+        (WebCore::segmentIndex): Deleted.
+        (WebCore::offsetInSegment): Deleted.
+        (WebCore::allocateSegment): Deleted.
+        (WebCore::freeSegment): Deleted.
+        (WebCore::SharedBuffer::~SharedBuffer): Deleted.
+        (WebCore::SharedBuffer::size): Deleted.
+        (WebCore::SharedBuffer::duplicateDataBufferIfNecessary): Deleted.
+        (WebCore::SharedBuffer::appendToDataBuffer): Deleted.
+        (WebCore::SharedBuffer::clearDataBuffer): Deleted.
+        (WebCore::SharedBuffer::copyBufferAndClear): Deleted.
+        (WebCore::SharedBuffer::buffer): Deleted.
+        (WebCore::SharedBuffer::getSomeData): Deleted.
+        (WebCore::SharedBuffer::maybeTransferMappedFileData): Deleted.
+        (WebCore::SharedBuffer::clearPlatformData): Deleted.
+        (WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
+        (WebCore::SharedBuffer::hasPlatformData): Deleted.
+        (WebCore::SharedBuffer::platformData): Deleted.
+        (WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
+        * platform/SharedBuffer.h:
+        (WebCore::SharedBuffer::create): Deleted.
+        (WebCore::SharedBuffer::isEmpty): Deleted.
+        * platform/SharedBufferChunkReader.cpp:
+        (WebCore::SharedBufferChunkReader::nextChunk):
+        (WebCore::SharedBufferChunkReader::peek):
+        * platform/SharedBufferChunkReader.h:
+        * platform/URLParser.cpp:
+        (WebCore::URLParser::URLParser):
+        * platform/cf/KeyedEncoderCF.cpp:
+        (WebCore::KeyedEncoderCF::finishEncoding):
+        * platform/cf/SharedBufferCF.cpp:
+        (WebCore::SharedBuffer::SharedBuffer):
+        (WebCore::SharedBuffer::createCFData):
+        (WebCore::SharedBuffer::create):
+        (WebCore::SharedBuffer::hintMemoryNotNeededSoon):
+        (WebCore::SharedBuffer::append):
+        (WebCore::SharedBuffer::wrapCFData): Deleted.
+        (WebCore::SharedBuffer::hasPlatformData): Deleted.
+        (WebCore::SharedBuffer::platformData): Deleted.
+        (WebCore::SharedBuffer::platformDataSize): Deleted.
+        (WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
+        (WebCore::SharedBuffer::clearPlatformData): Deleted.
+        (WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.
+        (WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
+        (WebCore::SharedBuffer::copyBufferAndClear): Deleted.
+        (WebCore::SharedBuffer::copySomeDataFromDataArray): Deleted.
+        (WebCore::SharedBuffer::singleDataArrayBuffer): Deleted.
+        (WebCore::SharedBuffer::maybeAppendDataArray): Deleted.
+        * platform/cocoa/NetworkExtensionContentFilter.mm:
+        (WebCore::NetworkExtensionContentFilter::replacementData):
+        * platform/cocoa/ParentalControlsContentFilter.mm:
+        (WebCore::ParentalControlsContentFilter::replacementData):
+        * platform/cocoa/SharedBufferCocoa.mm:
+        (-[WebCoreSharedBufferData initWithSharedBufferDataSegment:]):
+        (-[WebCoreSharedBufferData length]):
+        (-[WebCoreSharedBufferData bytes]):
+        (WebCore::SharedBuffer::create):
+        (WebCore::SharedBuffer::createCFData):
+        (WebCore::SharedBuffer::createFromReadingFile):
+        (WebCore::SharedBuffer::createNSDataArray):
+        (-[WebCoreSharedBufferData initWithSharedBufferDataBuffer:]): Deleted.
+        (WebCore::SharedBuffer::wrapNSData): Deleted.
+        (WebCore::SharedBuffer::existingCFData): Deleted.
+        * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
+        (WebCore::WebCoreAVFResourceLoader::fulfillRequestWithResource):
+        * platform/graphics/cocoa/FontPlatformDataCocoa.mm:
+        (WebCore::FontPlatformData::openTypeTable):
+        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
+        (ResourceHandleStreamingClient::didReceiveBuffer):
+        * platform/graphics/mac/ImageMac.mm:
+        (WebCore::Image::loadPlatformResource):
+        * platform/image-decoders/ImageDecoder.cpp:
+        (WebCore::ImageDecoder::create):
+        * platform/image-decoders/png/PNGImageDecoder.cpp:
+        (WebCore::PNGImageReader::decode):
+        * platform/ios/PlatformPasteboardIOS.mm:
+        (WebCore::PlatformPasteboard::readBuffer):
+        * platform/mac/PasteboardMac.mm:
+        (WebCore::writeFileWrapperAsRTFDAttachment):
+        (WebCore::Pasteboard::write):
+        * platform/mac/PlatformPasteboardMac.mm:
+        (WebCore::PlatformPasteboard::bufferForType):
+        * platform/network/BlobResourceHandle.cpp:
+        (WebCore::BlobResourceHandle::notifyReceiveData):
+        * platform/network/MIMEHeader.cpp:
+        * platform/network/MIMEHeader.h:
+        * platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp:
+        (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData):
+        * platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp:
+        (WebCore::SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData):
+        * platform/network/mac/WebCoreResourceHandleAsDelegate.mm:
+        (-[WebCoreResourceHandleAsDelegate connection:didReceiveData:lengthReceived:]):
+        * platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm:
+        (-[WebCoreResourceHandleAsOperationQueueDelegate connection:didReceiveData:lengthReceived:]):
+        * platform/soup/SharedBufferSoup.cpp:
+        (WebCore::SharedBuffer::SharedBuffer):
+        (WebCore::SharedBuffer::createSoupBuffer):
+        (WebCore::SharedBuffer::clearPlatformData): Deleted.
+        (WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
+        (WebCore::SharedBuffer::hasPlatformData): Deleted.
+        (WebCore::SharedBuffer::platformData): Deleted.
+        (WebCore::SharedBuffer::platformDataSize): Deleted.
+        (WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
+        (WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.
+
 2017-04-24  Dan Bernstein  <mitz@apple.com>
 
         [Cocoa] Some ivars are needlessly @protected
index 220f6db..c2f0a09 100644 (file)
@@ -599,7 +599,7 @@ void MediaKeySession::enqueueMessage(MediaKeyMessageType messageType, const Shar
     // 2. Queue a task to create an event named message that does not bubble and is not cancellable using the MediaKeyMessageEvent
     //    interface with its type attribute set to message and its isTrusted attribute initialized to true, and dispatch it at the
     //    session.
-    auto messageEvent = MediaKeyMessageEvent::create(eventNames().messageEvent, {messageType, message.createArrayBuffer()}, Event::IsTrusted::Yes);
+    auto messageEvent = MediaKeyMessageEvent::create(eventNames().messageEvent, {messageType, message.tryCreateArrayBuffer()}, Event::IsTrusted::Yes);
     m_eventQueue.enqueueEvent(WTFMove(messageEvent));
 }
 
index e82a74a..dc98758 100644 (file)
@@ -125,7 +125,7 @@ RefPtr<JSC::ArrayBuffer> FetchBodyConsumer::takeAsArrayBuffer()
     if (!m_buffer)
         return ArrayBuffer::tryCreate(nullptr, 0);
 
-    auto arrayBuffer = m_buffer->createArrayBuffer();
+    auto arrayBuffer = m_buffer->tryCreateArrayBuffer();
     m_buffer = nullptr;
     return arrayBuffer;
 }
index bf8420f..ac7d7e4 100644 (file)
@@ -278,7 +278,7 @@ void FetchResponse::consumeBodyAsStream()
 
     RefPtr<SharedBuffer> data = m_bodyLoader->startStreaming();
     if (data) {
-        if (!m_readableStreamSource->enqueue(data->createArrayBuffer())) {
+        if (!m_readableStreamSource->enqueue(data->tryCreateArrayBuffer())) {
             stop();
             return;
         }
index e27bcf3..83c8f42 100644 (file)
                37BAAE581980D1DD005DFE71 /* ProtectionSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 37BAAE571980D1DD005DFE71 /* ProtectionSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
                37C238221098C84200EF9F72 /* ComplexTextControllerCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */; };
                37D456FD1A9A50D8003330A1 /* LocalizableStrings.pm in Copy Scripts */ = {isa = PBXBuildFile; fileRef = 37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */; };
-               37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */; };
-               37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCD9313844FD50008B793 /* MIMEHeader.h */; };
                37DDCD9E13844FFA0008B793 /* Archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9D13844FFA0008B793 /* Archive.cpp */; };
-               37DDCDA51384501C0008B793 /* MHTMLArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCDA11384501C0008B793 /* MHTMLArchive.h */; };
-               37DDCDA71384501C0008B793 /* MHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCDA31384501C0008B793 /* MHTMLParser.h */; };
                37E3524B12450C5200BAF5D9 /* InputType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37E3524A12450C5200BAF5D9 /* InputType.cpp */; };
                37E3524D12450C6600BAF5D9 /* InputType.h in Headers */ = {isa = PBXBuildFile; fileRef = 37E3524C12450C6600BAF5D9 /* InputType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                37F567CE165358F400DDE92B /* PopupOpeningObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 3772B09516535856000A49CA /* PopupOpeningObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
                97AABD2714FA09D5007457AE /* WebSocketHandshake.h in Headers */ = {isa = PBXBuildFile; fileRef = 97AABD0C14FA09D5007457AE /* WebSocketHandshake.h */; };
                97AABD2C14FA09D5007457AE /* WorkerThreadableWebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97AABD1114FA09D5007457AE /* WorkerThreadableWebSocketChannel.cpp */; };
                97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 97AABD1214FA09D5007457AE /* WorkerThreadableWebSocketChannel.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               97B1F02E13B025CA00F5103F /* SharedBufferChunkReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37569E0013AF172C00CDBA8E /* SharedBufferChunkReader.cpp */; };
-               97B1F02F13B025D200F5103F /* SharedBufferChunkReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 37569E0213AF172C00CDBA8E /* SharedBufferChunkReader.h */; };
                97B38E27151C4271004622E9 /* DOMWindowNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 97B38E24151C4264004622E9 /* DOMWindowNotifications.h */; };
                97B38E28151C4273004622E9 /* DOMWindowNotifications.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97B38E23151C4264004622E9 /* DOMWindowNotifications.cpp */; };
                97B8FFD116AE7F960038388D /* CharacterReferenceParserInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 97B8FFCF16AE7F920038388D /* CharacterReferenceParserInlines.h */; };
                372ADA39197F687600FC501E /* ProtectionSpaceCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProtectionSpaceCocoa.mm; sourceTree = "<group>"; };
                372C00C3129611F1005C9575 /* TextBoundaries.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextBoundaries.cpp; sourceTree = "<group>"; };
                372C00D8129619F8005C9575 /* FindOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindOptions.h; sourceTree = "<group>"; };
-               37569E0013AF172C00CDBA8E /* SharedBufferChunkReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBufferChunkReader.cpp; sourceTree = "<group>"; };
-               37569E0213AF172C00CDBA8E /* SharedBufferChunkReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferChunkReader.h; sourceTree = "<group>"; };
                375CD231119D43C800A2A859 /* Hyphenation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hyphenation.h; sourceTree = "<group>"; };
                376DCCE013B4F966002EBEFC /* TextRun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextRun.cpp; sourceTree = "<group>"; };
                3772B09516535856000A49CA /* PopupOpeningObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupOpeningObserver.h; sourceTree = "<group>"; };
                37BAAE571980D1DD005DFE71 /* ProtectionSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtectionSpace.h; sourceTree = "<group>"; };
                37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ComplexTextControllerCoreText.mm; sourceTree = "<group>"; };
                37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = LocalizableStrings.pm; sourceTree = "<group>"; };
-               37DDCD9213844FD50008B793 /* MIMEHeader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MIMEHeader.cpp; sourceTree = "<group>"; };
-               37DDCD9313844FD50008B793 /* MIMEHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMEHeader.h; sourceTree = "<group>"; };
                37DDCD9D13844FFA0008B793 /* Archive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Archive.cpp; sourceTree = "<group>"; };
-               37DDCDA11384501C0008B793 /* MHTMLArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTMLArchive.h; sourceTree = "<group>"; };
-               37DDCDA31384501C0008B793 /* MHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTMLParser.h; sourceTree = "<group>"; };
                37E3524A12450C5200BAF5D9 /* InputType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputType.cpp; sourceTree = "<group>"; };
                37E3524C12450C6600BAF5D9 /* InputType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputType.h; sourceTree = "<group>"; };
                37F818FB0D657606005E1F05 /* WebCoreURLResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreURLResponse.h; sourceTree = "<group>"; };
                        path = opentype;
                        sourceTree = "<group>";
                };
-               37DDCD9F1384501C0008B793 /* mhtml */ = {
-                       isa = PBXGroup;
-                       children = (
-                               37DDCDA11384501C0008B793 /* MHTMLArchive.h */,
-                               37DDCDA31384501C0008B793 /* MHTMLParser.h */,
-                       );
-                       path = mhtml;
-                       sourceTree = "<group>";
-               };
                4150F9ED12B6E0990008C860 /* shadow */ = {
                        isa = PBXGroup;
                        children = (
                        isa = PBXGroup;
                        children = (
                                512DD8E90D91E6AF000F89EE /* cf */,
-                               37DDCD9F1384501C0008B793 /* mhtml */,
                                37DDCD9D13844FFA0008B793 /* Archive.cpp */,
                                512DD8EC0D91E6AF000F89EE /* Archive.h */,
                                512DD8F00D91E6AF000F89EE /* ArchiveFactory.cpp */,
                                41614A771DA64236004AD06F /* HTTPHeaderValues.h */,
                                514C765D0CE923A1007EF3CD /* HTTPParsers.cpp */,
                                514C765E0CE923A1007EF3CD /* HTTPParsers.h */,
-                               37DDCD9213844FD50008B793 /* MIMEHeader.cpp */,
-                               37DDCD9313844FD50008B793 /* MIMEHeader.h */,
                                628D214B12131ED10055DCFC /* NetworkingContext.h */,
                                8A81BF8411DCFD9000DA2B98 /* NetworkLoadMetrics.h */,
                                1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */,
                                077AF13E18F4AE400001ED61 /* SerializedPlatformRepresentation.h */,
                                1A4A954B0B4EDCCB002D8C3C /* SharedBuffer.cpp */,
                                1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */,
-                               37569E0013AF172C00CDBA8E /* SharedBufferChunkReader.cpp */,
-                               37569E0213AF172C00CDBA8E /* SharedBufferChunkReader.h */,
                                93309EA0099EB78C0056E581 /* SharedTimer.h */,
                                4B3043C60AE0370300A82647 /* Sound.h */,
                                F587866202DE3B1101EA4122 /* SSLKeyGenerator.h */,
                                75793E840D0CE0B3007FC0AC /* MessageEvent.h in Headers */,
                                E1ADECBF0E76ACF1004A1A5E /* MessagePort.h in Headers */,
                                41BF700C0FE86F49005E8DEC /* MessagePortChannel.h in Headers */,
-                               37DDCDA51384501C0008B793 /* MHTMLArchive.h in Headers */,
-                               37DDCDA71384501C0008B793 /* MHTMLParser.h in Headers */,
                                53B895AF19DC7ED9009CAA93 /* Microtasks.h in Headers */,
-                               37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */,
                                BC772C4F0C4EB3040083285F /* MIMETypeRegistry.h in Headers */,
                                52F10866162B6DA8009AC81E /* MixedContentChecker.h in Headers */,
                                CE1252491A16C3BC00864480 /* MobileGestaltSPI.h in Headers */,
                                FD45A952175D3F3E00C21EC8 /* ShapeOutsideInfo.h in Headers */,
                                FD1AF1501656F15100C6D4F7 /* ShapeValue.h in Headers */,
                                1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */,
-                               97B1F02F13B025D200F5103F /* SharedBufferChunkReader.h in Headers */,
                                93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */,
                                E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */,
                                11E067EE1E6246E500162D16 /* SimpleLineLayoutCoverage.h in Headers */,
                                75793E830D0CE0B3007FC0AC /* MessageEvent.cpp in Sources */,
                                E1ADECC00E76ACF1004A1A5E /* MessagePort.cpp in Sources */,
                                CB8CF0181A9358D4000D510B /* Microtasks.cpp in Sources */,
-                               37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */,
                                BC772C4E0C4EB3040083285F /* MIMETypeRegistry.cpp in Sources */,
                                C53D39341C978A45007F3AE9 /* MIMETypeRegistryCocoa.mm in Sources */,
                                52F10865162B6DA4009AC81E /* MixedContentChecker.cpp in Sources */,
                                1AB5EBD0194A1D170059AC70 /* ShapeValue.cpp in Sources */,
                                1A4A954D0B4EDCCB002D8C3C /* SharedBuffer.cpp in Sources */,
                                512DD8E30D91E2B4000F89EE /* SharedBufferCF.cpp in Sources */,
-                               97B1F02E13B025CA00F5103F /* SharedBufferChunkReader.cpp in Sources */,
                                1A4A95520B4EDCFF002D8C3C /* SharedBufferCocoa.mm in Sources */,
                                163E88F7118A39D200ED9231 /* SimpleFontDataCoreText.cpp in Sources */,
                                E48944A2180B57D800F165D8 /* SimpleLineLayout.cpp in Sources */,
index 05c8908..05dc8a8 100644 (file)
@@ -157,7 +157,7 @@ static RefPtr<SharedBuffer> archivedDataForAttributedString(NSAttributedString *
     if (!attributedString.length)
         return nullptr;
 
-    return SharedBuffer::wrapNSData([NSKeyedArchiver archivedDataWithRootObject:attributedString]);
+    return SharedBuffer::create([NSKeyedArchiver archivedDataWithRootObject:attributedString]);
 }
 
 void Editor::writeSelectionToPasteboard(Pasteboard& pasteboard)
@@ -205,7 +205,7 @@ RefPtr<SharedBuffer> Editor::selectionInWebArchiveFormat()
     RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(&m_frame);
     if (!archive)
         return nullptr;
-    return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
+    return SharedBuffer::create(archive->rawDataRepresentation().get());
 }
 
 // FIXME: Makes no sense that selectedTextForDataTransfer always includes alt text, but stringSelectionForPasteboard does not.
@@ -276,7 +276,7 @@ RefPtr<SharedBuffer> Editor::dataInRTFDFormat(NSAttributedString *string)
         return nullptr;
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    return SharedBuffer::wrapNSData([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
+    return SharedBuffer::create([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
     END_BLOCK_OBJC_EXCEPTIONS;
 
     return nullptr;
@@ -289,7 +289,7 @@ RefPtr<SharedBuffer> Editor::dataInRTFFormat(NSAttributedString *string)
         return nullptr;
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    return SharedBuffer::wrapNSData([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
+    return SharedBuffer::create([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
     END_BLOCK_OBJC_EXCEPTIONS;
 
     return nullptr;
index ef15cb5..805898a 100644 (file)
@@ -339,10 +339,10 @@ bool Editor::WebContentReader::readURL(const URL& url, const String&)
         RetainPtr<NSString> fileType = adoptNS((NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[localPath pathExtension], NULL));
         NSData *data = [NSData dataWithContentsOfFile:localPath];
         if (UTTypeConformsTo((CFStringRef)fileType.get(), kUTTypePNG)) {
-            addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::wrapNSData([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.png"), @"image/png", emptyString(), emptyString())));
+            addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::create([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.png"), @"image/png", emptyString(), emptyString())));
             return fragment;
         } else if (UTTypeConformsTo((CFStringRef)fileType.get(), kUTTypeJPEG)) {
-            addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::wrapNSData([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.jpg"), @"image/jpg", emptyString(), emptyString())));
+            addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::create([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.jpg"), @"image/jpg", emptyString(), emptyString())));
             return fragment;
         }
     } else {
index 60efef7..63bc3d8 100644 (file)
@@ -204,7 +204,7 @@ RefPtr<SharedBuffer> Editor::imageInWebArchiveFormat(Element& imageElement)
     RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(imageElement);
     if (!archive)
         return nullptr;
-    return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
+    return SharedBuffer::create(archive->rawDataRepresentation().get());
 }
 
 RefPtr<SharedBuffer> Editor::dataSelectionForPasteboard(const String& pasteboardType)
index 62cbdca..728fe33 100644 (file)
@@ -91,12 +91,15 @@ void TextTrackLoader::processNewCueData(CachedResource& resource)
     if (!m_cueParser)
         m_cueParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), m_scriptExecutionContext);
 
-    const char* data;
-    unsigned length;
-
-    while ((length = buffer->getSomeData(data, m_parseOffset))) {
-        m_cueParser->parseBytes(data, length);
-        m_parseOffset += length;
+    auto bytesToSkip = m_parseOffset;
+    for (const auto& segment : *buffer) {
+        if (bytesToSkip > segment->size()) {
+            bytesToSkip -= segment->size();
+            continue;
+        }
+        m_cueParser->parseBytes(segment->data() + bytesToSkip, segment->size() - bytesToSkip);
+        bytesToSkip = 0;
+        m_parseOffset += segment->size();
     }
 }
 
index 097482f..ba98a3e 100644 (file)
@@ -221,7 +221,7 @@ RefPtr<ArchiveResource> LegacyWebArchive::createResource(CFDictionaryRef diction
         response = createResourceResponseFromPropertyListData(resourceResponseData, resourceResponseVersion);
     }
 
-    return ArchiveResource::create(SharedBuffer::wrapCFData(resourceData), URL(URL(), url), mimeType, textEncoding, frameName, response);
+    return ArchiveResource::create(SharedBuffer::create(resourceData), URL(URL(), url), mimeType, textEncoding, frameName, response);
 }
 
 Ref<LegacyWebArchive> LegacyWebArchive::create()
index eee2033..25c0dfa 100644 (file)
@@ -850,8 +850,9 @@ void CachedResource::tryReplaceEncodedData(SharedBuffer& newBuffer)
     if (m_data->size() != newBuffer.size() || memcmp(m_data->data(), newBuffer.data(), m_data->size()))
         return;
 
-    if (m_data->tryReplaceContentsWithPlatformBuffer(newBuffer))
-        didReplaceSharedBufferContents();
+    m_data->clear();
+    m_data->append(newBuffer);
+    didReplaceSharedBufferContents();
 }
 
 #endif
index 6ac45a1..4825bd0 100644 (file)
@@ -48,7 +48,7 @@ RefPtr<SharedBuffer> DiskCacheMonitor::tryGetFileBackedSharedBufferFromCFURLCach
     if (!data)
         return nullptr;
 
-    return SharedBuffer::wrapCFData(data);
+    return SharedBuffer::create(data);
 }
 
 void DiskCacheMonitor::monitorFileBackingStoreCreation(const ResourceRequest& request, SessionID sessionID, CFCachedURLResponseRef cachedResponse)
index 8161f63..283e7a3 100644 (file)
 #include <algorithm>
 #include <wtf/unicode/UTF8.h>
 
-namespace WebCore {
-
-#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-
-static const unsigned segmentSize = 0x1000;
-static const unsigned segmentPositionMask = 0x0FFF;
-
-static inline unsigned segmentIndex(unsigned position)
-{
-    return position / segmentSize;
-}
-
-static inline unsigned offsetInSegment(unsigned position)
-{
-    return position & segmentPositionMask;
-}
-
-static inline char* allocateSegment() WARN_UNUSED_RETURN;
-static inline char* allocateSegment()
-{
-    return static_cast<char*>(fastMalloc(segmentSize));
-}
-
-static inline void freeSegment(char* p)
-{
-    fastFree(p);
-}
-
+#if USE(SOUP)
+#include "GUniquePtrSoup.h"
 #endif
 
-SharedBuffer::SharedBuffer()
-    : m_buffer(adoptRef(*new DataBuffer))
-{
-}
+namespace WebCore {
 
-SharedBuffer::SharedBuffer(const char* data, unsigned size)
-    : m_buffer(adoptRef(*new DataBuffer))
+SharedBuffer::SharedBuffer(const char* data, size_t size)
 {
     append(data, size);
 }
 
-SharedBuffer::SharedBuffer(const unsigned char* data, unsigned size)
-    : m_buffer(adoptRef(*new DataBuffer))
+SharedBuffer::SharedBuffer(const unsigned char* data, size_t size)
 {
     append(reinterpret_cast<const char*>(data), size);
 }
 
 SharedBuffer::SharedBuffer(MappedFileData&& fileData)
-    : m_buffer(adoptRef(*new DataBuffer))
-    , m_fileData(WTFMove(fileData))
+    : m_size(fileData.size())
 {
+    m_segments.append(DataSegment::create(WTFMove(fileData)));
 }
 
-SharedBuffer::~SharedBuffer()
+SharedBuffer::SharedBuffer(Vector<char>&& data)
 {
-    clear();
+    append(WTFMove(data));
 }
 
 RefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
@@ -102,210 +71,101 @@ RefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePa
 
 Ref<SharedBuffer> SharedBuffer::create(Vector<char>&& vector)
 {
-    auto buffer = create();
-    buffer->m_buffer->data = WTFMove(vector);
-    buffer->m_size = buffer->m_buffer->data.size();
-    return buffer;
+    return adoptRef(*new SharedBuffer(WTFMove(vector)));
 }
 
-unsigned SharedBuffer::size() const
+void SharedBuffer::combineIntoOneSegment() const
 {
-    if (hasPlatformData())
-        return platformDataSize();
-    
-    if (m_fileData)
-        return m_fileData.size();
+    if (m_segments.size() <= 1)
+        return;
 
-    return m_size;
+    Vector<char> combinedData;
+    combinedData.reserveInitialCapacity(m_size);
+    for (const auto& segment : m_segments)
+        combinedData.append(segment->data(), segment->size());
+    ASSERT(combinedData.size() == m_size);
+    m_segments.clear();
+    m_segments.append(DataSegment::create(WTFMove(combinedData)));
+    ASSERT(m_segments.size() == 1);
 }
 
 const char* SharedBuffer::data() const
 {
-    if (hasPlatformData())
-        return platformData();
-
-    if (m_fileData)
-        return static_cast<const char*>(m_fileData.data());
-
-#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    if (const char* buffer = singleDataArrayBuffer())
-        return buffer;
-#endif
-
-    return this->buffer().data();
+    if (!m_segments.size())
+        return nullptr;
+    combineIntoOneSegment();
+    return m_segments[0]->data();
 }
 
-RefPtr<ArrayBuffer> SharedBuffer::createArrayBuffer() const
+RefPtr<ArrayBuffer> SharedBuffer::tryCreateArrayBuffer() const
 {
     RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::createUninitialized(static_cast<unsigned>(size()), sizeof(char));
     if (!arrayBuffer) {
-        WTFLogAlways("SharedBuffer::createArrayBuffer Unable to create buffer. Requested size was %d x %lu\n", size(), sizeof(char));
+        WTFLogAlways("SharedBuffer::tryCreateArrayBuffer Unable to create buffer. Requested size was %d x %lu\n", size(), sizeof(char));
         return nullptr;
     }
 
-    const char* segment = 0;
-    unsigned position = 0;
-    while (unsigned segmentSize = getSomeData(segment, position)) {
-        memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment, segmentSize);
-        position += segmentSize;
-    }
-
-    if (position != arrayBuffer->byteLength()) {
-        ASSERT_NOT_REACHED();
-        // Don't return the incomplete ArrayBuffer.
-        return nullptr;
+    size_t position = 0;
+    for (const auto& segment : m_segments) {
+        memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment->data(), segment->size());
+        position += segment->size();
     }
 
+    ASSERT(position == m_size);
     return arrayBuffer;
 }
 
-void SharedBuffer::append(SharedBuffer& data)
+void SharedBuffer::append(const SharedBuffer& data)
 {
-    if (maybeAppendPlatformData(data))
-        return;
-#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    if (maybeAppendDataArray(data))
-        return;
-#endif
-
-    const char* segment;
-    size_t position = 0;
-    while (size_t length = data.getSomeData(segment, position)) {
-        append(segment, length);
-        position += length;
-    }
+    m_size += data.m_size;
+    m_segments.reserveCapacity(m_segments.size() + data.m_segments.size());
+    for (const auto& segment : data.m_segments)
+        m_segments.uncheckedAppend(segment.copyRef());
 }
 
-void SharedBuffer::append(const char* data, unsigned length)
+void SharedBuffer::append(const char* data, size_t length)
 {
-    if (!length)
-        return;
-
-    maybeTransferMappedFileData();
-    maybeTransferPlatformData();
-
-#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    unsigned positionInSegment = offsetInSegment(m_size - m_buffer->data.size());
-    m_size += length;
-
-    if (m_size <= segmentSize) {
-        // No need to use segments for small resource data
-        if (m_buffer->data.isEmpty())
-            m_buffer->data.reserveInitialCapacity(length);
-        appendToDataBuffer(data, length);
-        return;
-    }
-
-    char* segment;
-    if (!positionInSegment) {
-        segment = allocateSegment();
-        m_segments.append(segment);
-    } else
-        segment = m_segments.last() + positionInSegment;
-
-    unsigned segmentFreeSpace = segmentSize - positionInSegment;
-    unsigned bytesToCopy = std::min(length, segmentFreeSpace);
-
-    for (;;) {
-        memcpy(segment, data, bytesToCopy);
-        if (static_cast<unsigned>(length) == bytesToCopy)
-            break;
-
-        length -= bytesToCopy;
-        data += bytesToCopy;
-        segment = allocateSegment();
-        m_segments.append(segment);
-        bytesToCopy = std::min(length, segmentSize);
-    }
-#else
     m_size += length;
-    if (m_buffer->data.isEmpty())
-        m_buffer->data.reserveInitialCapacity(length);
-    appendToDataBuffer(data, length);
-#endif
+    Vector<char> vector;
+    vector.append(data, length);
+    m_segments.append(DataSegment::create(WTFMove(vector)));
 }
 
 void SharedBuffer::append(Vector<char>&& data)
 {
-    // This takes its argument as a rvalue reference because we intend to have a future
-    // version take ownership of the vector rather than copying.
-    append(data.data(), data.size());
+    m_size += data.size();
+    m_segments.append(DataSegment::create(WTFMove(data)));
 }
 
 void SharedBuffer::clear()
 {
-    m_fileData = { };
-
-    clearPlatformData();
-    
-#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    for (char* segment : m_segments)
-        freeSegment(segment);
-    m_segments.clear();
-#else
-    m_dataArray.clear();
-#endif
-
     m_size = 0;
-    clearDataBuffer();
+    m_segments.clear();
 }
 
 Ref<SharedBuffer> SharedBuffer::copy() const
 {
-    Ref<SharedBuffer> clone { adoptRef(*new SharedBuffer) };
-
-    if (hasPlatformData() || m_fileData) {
-        clone->append(data(), size());
-        return clone;
-    }
-
+    Ref<SharedBuffer> clone = adoptRef(*new SharedBuffer);
     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)
-    if (!m_segments.isEmpty()) {
-        unsigned lastIndex = m_segments.size() - 1;
-        for (unsigned i = 0; i < lastIndex; ++i)
-            clone->m_buffer->data.append(m_segments[i], segmentSize);
-
-        unsigned sizeOfLastSegment = m_size - m_buffer->data.size() - lastIndex * segmentSize;
-        clone->m_buffer->data.append(m_segments.last(), sizeOfLastSegment);
-    }
-#else
-    for (auto& data : m_dataArray)
-        clone->m_dataArray.append(data.get());
-#endif
-    ASSERT(clone->size() == size());
-
+    clone->m_segments.reserveInitialCapacity(m_segments.size());
+    for (const auto& segment : m_segments)
+        clone->m_segments.uncheckedAppend(segment.copyRef());
     return clone;
 }
 
-void SharedBuffer::duplicateDataBufferIfNecessary() const
-{
-    size_t currentCapacity = m_buffer->data.capacity();
-    if (m_buffer->hasOneRef() || m_size <= currentCapacity)
-        return;
-
-    size_t newCapacity = std::max(static_cast<size_t>(m_size), currentCapacity * 2);
-    auto newBuffer = adoptRef(*new DataBuffer);
-    newBuffer->data.reserveInitialCapacity(newCapacity);
-    newBuffer->data = m_buffer->data;
-    m_buffer = WTFMove(newBuffer);
-}
-
-void SharedBuffer::appendToDataBuffer(const char *data, unsigned length) const
+const char* SharedBuffer::DataSegment::data() const
 {
-    duplicateDataBufferIfNecessary();
-    m_buffer->data.append(data, length);
-}
-
-void SharedBuffer::clearDataBuffer()
-{
-    if (!m_buffer->hasOneRef())
-        m_buffer = adoptRef(*new DataBuffer);
-    else
-        m_buffer->data.clear();
+    auto visitor = WTF::makeVisitor(
+        [](const Vector<char>& data) { return data.data(); },
+#if USE(CF)
+        [](const RetainPtr<CFDataRef>& data) { return reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())); },
+#endif
+#if USE(SOUP)
+        [](const GUniquePtr<SoupBuffer>& data) { return data->data; },
+#endif
+        [](const MappedFileData& data) { return reinterpret_cast<const char*>(data.data()); }
+    );
+    return WTF::visit(visitor, m_immutableData);
 }
 
 #if !USE(CF)
@@ -314,111 +174,21 @@ void SharedBuffer::hintMemoryNotNeededSoon()
 }
 #endif
 
-#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-
-void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
+size_t SharedBuffer::DataSegment::size() const
 {
-    for (char* segment : m_segments) {
-        unsigned effectiveBytesToCopy = std::min(bytesToCopy, segmentSize);
-        memcpy(destination, segment, effectiveBytesToCopy);
-        destination += effectiveBytesToCopy;
-        bytesToCopy -= effectiveBytesToCopy;
-        freeSegment(segment);
-    }
-    m_segments.clear();
-}
-
+    auto visitor = WTF::makeVisitor(
+        [](const Vector<char>& data) { return data.size(); },
+#if USE(CF)
+        [](const RetainPtr<CFDataRef>& data) { return CFDataGetLength(data.get()); },
 #endif
-
-const Vector<char>& SharedBuffer::buffer() const
-{
-    unsigned bufferSize = m_buffer->data.size();
-    if (m_size > bufferSize) {
-        duplicateDataBufferIfNecessary();
-        m_buffer->data.resize(m_size);
-        copyBufferAndClear(m_buffer->data.data() + bufferSize, m_size - bufferSize);
-    }
-    return m_buffer->data;
-}
-
-unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
-{
-    unsigned totalSize = size();
-    if (position >= totalSize) {
-        someData = 0;
-        return 0;
-    }
-
-    if (hasPlatformData() || m_fileData) {
-        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);
+#if USE(SOUP)
+        [](const GUniquePtr<SoupBuffer>& data) { return static_cast<size_t>(data->length); },
 #endif
+        [](const MappedFileData& data) { return data.size(); }
+    );
+    return WTF::visit(visitor, m_immutableData);
 }
 
-void SharedBuffer::maybeTransferMappedFileData()
-{
-    if (m_fileData) {
-        auto fileData = WTFMove(m_fileData);
-        append(static_cast<const char*>(fileData.data()), fileData.size());
-    }
-}
-
-#if !USE(CF) && !USE(SOUP)
-
-inline void SharedBuffer::clearPlatformData()
-{
-}
-
-inline void SharedBuffer::maybeTransferPlatformData()
-{
-}
-
-inline bool SharedBuffer::hasPlatformData() const
-{
-    return false;
-}
-
-inline const char* SharedBuffer::platformData() const
-{
-    ASSERT_NOT_REACHED();
-
-    return nullptr;
-}
-
-inline bool SharedBuffer::maybeAppendPlatformData(SharedBuffer&)
-{
-    return false;
-}
-
-#endif
-
 RefPtr<SharedBuffer> utf8Buffer(const String& string)
 {
     // Allocate a buffer big enough to hold all the characters.
index 88580c6..ab6feed 100644 (file)
@@ -31,6 +31,7 @@
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 #include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Variant.h>
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
@@ -49,27 +50,24 @@ OBJC_CLASS NSData;
 
 namespace WebCore {
     
-class SharedBuffer : public RefCounted<SharedBuffer> {
+class WEBCORE_EXPORT SharedBuffer : public RefCounted<SharedBuffer> {
 public:
     static Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
-    static Ref<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(*new SharedBuffer(c, i)); }
-    static Ref<SharedBuffer> create(const unsigned char* data, unsigned size) { return adoptRef(*new SharedBuffer(data, size)); }
+    static Ref<SharedBuffer> create(const char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
+    static Ref<SharedBuffer> create(const unsigned char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
+    static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
 
-    WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
-
-    WEBCORE_EXPORT static Ref<SharedBuffer> create(Vector<char>&&);
-    
-    WEBCORE_EXPORT ~SharedBuffer();
+    static Ref<SharedBuffer> create(Vector<char>&&);
     
 #if USE(FOUNDATION)
-    WEBCORE_EXPORT RetainPtr<NSData> createNSData();
-    WEBCORE_EXPORT RetainPtr<NSArray> createNSDataArray() const;
-    WEBCORE_EXPORT static Ref<SharedBuffer> wrapNSData(NSData *);
+    RetainPtr<NSData> createNSData();
+    RetainPtr<NSArray> createNSDataArray() const;
+    static Ref<SharedBuffer> create(NSData *);
 #endif
 #if USE(CF)
-    WEBCORE_EXPORT RetainPtr<CFDataRef> createCFData();
-    WEBCORE_EXPORT static Ref<SharedBuffer> wrapCFData(CFDataRef);
-    WEBCORE_EXPORT void append(CFDataRef);
+    RetainPtr<CFDataRef> createCFData();
+    static Ref<SharedBuffer> create(CFDataRef);
+    void append(CFDataRef);
 #endif
 
 #if USE(SOUP)
@@ -77,101 +75,94 @@ public:
     static Ref<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
 #endif
 
-    // Calling this function will force internal segmented buffers
-    // to be merged into a flat buffer. Use getSomeData() whenever possible
-    // for better performance.
-    WEBCORE_EXPORT const char* data() const;
+    // Calling data() causes all the data segments to be copied into one segment if they are not already.
+    // Iterate the segments using begin() and end() instead.
+    // FIXME: Audit the call sites of this function and replace them with iteration if possible.
+    const char* data() const;
+
     // Creates an ArrayBuffer and copies this SharedBuffer's contents to that
     // ArrayBuffer without merging segmented buffers into a flat buffer.
-    WEBCORE_EXPORT RefPtr<ArrayBuffer> createArrayBuffer() const;
+    RefPtr<ArrayBuffer> tryCreateArrayBuffer() const;
 
-    WEBCORE_EXPORT unsigned size() const;
+    // FIXME: This should return a size_t.
+    unsigned size() const { return m_size; }
 
     bool isEmpty() const { return !size(); }
 
-    WEBCORE_EXPORT void append(SharedBuffer&);
-    WEBCORE_EXPORT void append(const char*, unsigned);
-    WEBCORE_EXPORT void append(Vector<char>&&);
-
-    WEBCORE_EXPORT void clear();
-
-    WEBCORE_EXPORT Ref<SharedBuffer> copy() const;
-    
-    // Return the number of consecutive bytes after "position". "data"
-    // points to the first byte.
-    // Return 0 when no more data left.
-    // When extracting all data with getSomeData(), the caller should
-    // repeat calling it until it returns 0.
-    // Usage:
-    //      const char* segment;
-    //      unsigned pos = 0;
-    //      while (unsigned length = sharedBuffer->getSomeData(segment, pos)) {
-    //          // Use the data. for example: decoder->decode(segment, length);
-    //          pos += length;
-    //      }
-    WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
-
-    bool tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
-    WEBCORE_EXPORT bool hasPlatformData() const;
-
-    struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
-        Vector<char> data;
-    };
-
-    void hintMemoryNotNeededSoon();
-
-private:
-    WEBCORE_EXPORT SharedBuffer();
-    WEBCORE_EXPORT SharedBuffer(const char*, unsigned);
-    WEBCORE_EXPORT SharedBuffer(const unsigned char*, unsigned);
-    explicit SharedBuffer(MappedFileData&&);
-
-    static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
+    void append(const SharedBuffer&);
+    void append(const char*, size_t);
+    void append(Vector<char>&&);
 
-    // Calling this function will force internal segmented buffers
-    // to be merged into a flat buffer. Use getSomeData() whenever possible
-    // for better performance.
-    const Vector<char>& buffer() const;
+    void clear();
 
-    void clearPlatformData();
-    void maybeTransferPlatformData();
-    bool maybeAppendPlatformData(SharedBuffer&);
+    Ref<SharedBuffer> copy() const;
 
-    void maybeTransferMappedFileData();
+    // Data wrapped by a DataSegment should be immutable because it can be referenced by other objects.
+    // To modify or combine the data, allocate a new DataSegment.
+    class DataSegment : public ThreadSafeRefCounted<DataSegment> {
+    public:
+        const char* data() const;
+        size_t size() const;
 
-    void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
-
-    void appendToDataBuffer(const char *, unsigned) const;
-    void duplicateDataBufferIfNecessary() const;
-    void clearDataBuffer();
+        static Ref<DataSegment> create(Vector<char>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
+#if USE(CF)
+        static Ref<DataSegment> create(RetainPtr<CFDataRef>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
+#endif
+#if USE(SOUP)
+        static Ref<DataSegment> create(GUniquePtr<SoupBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
+#endif
+        static Ref<DataSegment> create(MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
 
-    unsigned m_size { 0 };
-    mutable Ref<DataBuffer> m_buffer;
+    private:
+        DataSegment(Vector<char>&& data)
+            : m_immutableData(WTFMove(data)) { }
+#if USE(CF)
+        DataSegment(RetainPtr<CFDataRef>&& data)
+            : m_immutableData(WTFMove(data)) { }
+#endif
+#if USE(SOUP)
+        DataSegment(GUniquePtr<SoupBuffer>&& data)
+            : m_immutableData(WTFMove(data)) { }
+#endif
+        DataSegment(MappedFileData&& data)
+            : m_immutableData(WTFMove(data)) { }
 
-#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
-    unsigned copySomeDataFromDataArray(const char*& someData, unsigned position) const;
-    const char *singleDataArrayBuffer() const;
-    bool maybeAppendDataArray(SharedBuffer&);
-#else
-    mutable Vector<char*> m_segments;
+        Variant<Vector<char>,
+#if USE(CF)
+            RetainPtr<CFDataRef>,
+#endif
+#if USE(SOUP)
+            GUniquePtr<SoupBuffer>,
 #endif
+            MappedFileData> m_immutableData;
+        friend class SharedBuffer;
+    };
 
-    unsigned platformDataSize() const;
-    const char* platformData() const;
+    using DataSegmentVector = Vector<Ref<DataSegment>, 1>;
+    DataSegmentVector::const_iterator begin() const { return m_segments.begin(); }
+    DataSegmentVector::const_iterator end() const { return m_segments.end(); }
 
+    void hintMemoryNotNeededSoon();
+
+private:
+    explicit SharedBuffer() = default;
+    explicit SharedBuffer(const char*, size_t);
+    explicit SharedBuffer(const unsigned char*, size_t);
+    explicit SharedBuffer(Vector<char>&&);
+    explicit SharedBuffer(MappedFileData&&);
 #if USE(CF)
     explicit SharedBuffer(CFDataRef);
-    RetainPtr<CFDataRef> m_cfData;
-    CFDataRef existingCFData();
 #endif
-
 #if USE(SOUP)
     explicit SharedBuffer(SoupBuffer*);
-    GUniquePtr<SoupBuffer> m_soupBuffer;
 #endif
 
-    MappedFileData m_fileData;
+    void combineIntoOneSegment() const;
+    
+    static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
+
+    size_t m_size { 0 };
+    mutable DataSegmentVector m_segments;
 };
 
 RefPtr<SharedBuffer> utf8Buffer(const String&);
index 6a13fe6..a203fee 100644 (file)
 #include "config.h"
 #include "SharedBufferChunkReader.h"
 
+#if ENABLE(MHTML)
+
+// FIXME: This class is overkill. Remove this class and just iterate the segments of a SharedBuffer
+// using the cool new SharedBuffer::begin() and SharedBuffer::end() instead of using this class.
+
 #include "SharedBuffer.h"
 
 namespace WebCore {
@@ -100,7 +105,10 @@ bool SharedBufferChunkReader::nextChunk(Vector<char>& chunk, bool includeSeparat
         // Read the next segment.
         m_segmentIndex = 0;
         m_bufferPosition += m_segmentLength;
-        m_segmentLength = m_buffer->getSomeData(m_segment, m_bufferPosition);
+        // Let's pretend all the data is in one block.
+        // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer.
+        m_segment = m_buffer->data() + m_bufferPosition;
+        m_segmentLength = m_buffer->size() - m_bufferPosition;
         if (!m_segmentLength) {
             m_reachedEndOfFile = true;
             if (m_separatorIndex > 0)
@@ -134,12 +142,14 @@ size_t SharedBufferChunkReader::peek(Vector<char>& data, size_t requestedSize)
 
     size_t bufferPosition = m_bufferPosition + m_segmentLength;
     const char* segment = 0;
-    while (size_t segmentLength = m_buffer->getSomeData(segment, bufferPosition)) {
-        if (requestedSize <= readBytesCount + segmentLength) {
-            data.append(segment, requestedSize - readBytesCount);
-            readBytesCount += (requestedSize - readBytesCount);
-            break;
-        }
+
+    // Let's pretend all the data is in one block.
+    // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer.
+    if (bufferPosition != m_buffer->size()) {
+        segment = m_buffer->data() + bufferPosition;
+        size_t segmentLength = m_buffer->size() - bufferPosition;
+        if (segmentLength > requestedSize)
+            segmentLength = requestedSize;
         data.append(segment, segmentLength);
         readBytesCount += segmentLength;
         bufferPosition += segmentLength;
@@ -148,3 +158,5 @@ size_t SharedBufferChunkReader::peek(Vector<char>& data, size_t requestedSize)
 }
 
 }
+
+#endif
index 568ec3c..756eee2 100644 (file)
@@ -28,8 +28,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef SharedBufferChunkReader_h
-#define SharedBufferChunkReader_h
+#pragma once
+
+#if ENABLE(MHTML)
 
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
index 619a2c0..d0f0c9e 100644 (file)
@@ -145,7 +145,7 @@ RefPtr<SharedBuffer> KeyedEncoderCF::finishEncoding()
     auto data = adoptCF(CFPropertyListCreateData(kCFAllocatorDefault, m_rootDictionary.get(), kCFPropertyListBinaryFormat_v1_0, 0, nullptr));
     if (!data)
         return nullptr;
-    return SharedBuffer::wrapCFData(data.get());
+    return SharedBuffer::create(data.get());
 }
 
 } // namespace WebCore
index f4024b4..4995904 100644 (file)
 
 namespace WebCore {
 
-SharedBuffer::SharedBuffer(CFDataRef cfData)
-    : m_buffer(adoptRef(*new DataBuffer))
-    , m_cfData(cfData)
+SharedBuffer::SharedBuffer(CFDataRef data)
 {
+    append(data);
 }
 
 // Using Foundation allows for an even more efficient implementation of this function,
@@ -44,144 +43,34 @@ SharedBuffer::SharedBuffer(CFDataRef cfData)
 #if !USE(FOUNDATION)
 RetainPtr<CFDataRef> SharedBuffer::createCFData()
 {
-    if (m_cfData)
-        return m_cfData;
-
-    // Internal data in SharedBuffer can be segmented. We need to get the contiguous buffer.
-    const Vector<char>& contiguousBuffer = buffer();
-    return adoptCF(CFDataCreate(0, reinterpret_cast<const UInt8*>(contiguousBuffer.data()), contiguousBuffer.size()));
+    if (m_segments.size() == 1) {
+        if (auto data = WTF::get_if<RetainPtr<CFDataRef>>(m_segments[0]->m_immutableData))
+            return *data;
+    }
+    return adoptCF(CFDataCreate(nullptr, reinterpret_cast<const UInt8*>(data()), size()));
 }
 #endif
 
-Ref<SharedBuffer> SharedBuffer::wrapCFData(CFDataRef data)
+Ref<SharedBuffer> SharedBuffer::create(CFDataRef data)
 {
     return adoptRef(*new SharedBuffer(data));
 }
 
-bool SharedBuffer::hasPlatformData() const
-{
-    return m_cfData;
-}
-
-const char* SharedBuffer::platformData() const
-{
-    return reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get()));
-}
-
-unsigned SharedBuffer::platformDataSize() const
-{
-    return CFDataGetLength(m_cfData.get());
-}
-
 void SharedBuffer::hintMemoryNotNeededSoon()
 {
-    if (!hasPlatformData())
-        return;
-    OSAllocator::hintMemoryNotNeededSoon(const_cast<char*>(platformData()), platformDataSize());
-}
-
-void SharedBuffer::maybeTransferPlatformData()
-{
-    if (!m_cfData)
-        return;
-    
-    ASSERT(!m_size);
-    
-    // Hang on to the m_cfData pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
-    // and we need to make sure to early return when it does.
-    RetainPtr<CFDataRef> cfData = adoptCF(m_cfData.leakRef());
-
-    append(reinterpret_cast<const char*>(CFDataGetBytePtr(cfData.get())), CFDataGetLength(cfData.get()));
-}
-
-void SharedBuffer::clearPlatformData()
-{
-    m_cfData = 0;
-}
-
-bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
-{
-    if (!newContents.m_cfData)
-        return false;
-
-    clear();
-    m_cfData = newContents.m_cfData;
-    return true;
-}
-
-bool SharedBuffer::maybeAppendPlatformData(SharedBuffer& newContents)
-{
-    if (size() || !newContents.m_cfData)
-        return false;
-    m_cfData = newContents.m_cfData;
-    return true;
+    for (const auto& segment : m_segments) {
+        if (segment->hasOneRef()) {
+            if (auto data = WTF::get_if<RetainPtr<CFDataRef>>(segment->m_immutableData))
+                OSAllocator::hintMemoryNotNeededSoon(const_cast<UInt8*>(CFDataGetBytePtr(data->get())), CFDataGetLength(data->get()));
+        }
+    }
 }
 
-#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
 void SharedBuffer::append(CFDataRef data)
 {
     ASSERT(data);
-    m_dataArray.append(data);
     m_size += CFDataGetLength(data);
+    m_segments.append(DataSegment::create(data));
 }
 
-void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
-{
-    if (m_dataArray.isEmpty())
-        return;
-
-    CFIndex bytesLeft = bytesToCopy;
-    for (auto& cfData : m_dataArray) {
-        CFIndex dataLen = CFDataGetLength(cfData.get());
-        ASSERT(bytesLeft >= dataLen);
-        memcpy(destination, CFDataGetBytePtr(cfData.get()), dataLen);
-        destination += dataLen;
-        bytesLeft -= dataLen;
-    }
-    m_dataArray.clear();
-}
-
-unsigned SharedBuffer::copySomeDataFromDataArray(const char*& someData, unsigned position) const
-{
-    unsigned totalOffset = 0;
-    for (auto& cfData : m_dataArray) {
-        unsigned dataLen = static_cast<unsigned>(CFDataGetLength(cfData.get()));
-        ASSERT(totalOffset <= position);
-        unsigned localOffset = position - totalOffset;
-        if (localOffset < dataLen) {
-            someData = reinterpret_cast<const char *>(CFDataGetBytePtr(cfData.get())) + localOffset;
-            return dataLen - localOffset;
-        }
-        totalOffset += dataLen;
-    }
-    return 0;
-}
-
-const char *SharedBuffer::singleDataArrayBuffer() const
-{
-    // If we had previously copied data into m_buffer in copyDataArrayAndClear() or some other
-    // function, then we can't return a pointer to the CFDataRef buffer.
-    if (m_buffer->data.size())
-        return 0;
-
-    if (m_dataArray.size() != 1)
-        return 0;
-
-    return reinterpret_cast<const char*>(CFDataGetBytePtr(m_dataArray.at(0).get()));
-}
-
-bool SharedBuffer::maybeAppendDataArray(SharedBuffer& data)
-{
-    if (m_buffer->data.size() || m_cfData || !data.m_dataArray.size())
-        return false;
-#if !ASSERT_DISABLED
-    unsigned originalSize = size();
-#endif
-    for (auto& cfData : data.m_dataArray)
-        append(cfData.get());
-    ASSERT(size() == originalSize + data.size());
-    return true;
-}
-#endif
-
 }
index aac8787..ceeb62e 100644 (file)
@@ -197,7 +197,7 @@ void NetworkExtensionContentFilter::finishedAddingData()
 Ref<SharedBuffer> NetworkExtensionContentFilter::replacementData() const
 {
     ASSERT(didBlockData());
-    return SharedBuffer::wrapNSData(m_replacementData.get());
+    return SharedBuffer::create(m_replacementData.get());
 }
 
 #if ENABLE(CONTENT_FILTERING)
index e7c1ee2..95e911f 100644 (file)
@@ -93,7 +93,7 @@ void ParentalControlsContentFilter::finishedAddingData()
 Ref<SharedBuffer> ParentalControlsContentFilter::replacementData() const
 {
     ASSERT(didBlockData());
-    return SharedBuffer::wrapNSData(m_replacementData.get());
+    return SharedBuffer::create(m_replacementData.get());
 }
 
 #if ENABLE(CONTENT_FILTERING)
index 70be9e3..b4801de 100644 (file)
@@ -35,10 +35,10 @@ using namespace WebCore;
 
 @interface WebCoreSharedBufferData : NSData
 {
-    RefPtr<SharedBuffer::DataBuffer> sharedBufferDataBuffer;
+    RefPtr<const SharedBuffer::DataSegment> sharedBufferDataSegment;
 }
 
-- (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer;
+- (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment;
 @end
 
 @implementation WebCoreSharedBufferData
@@ -59,31 +59,31 @@ using namespace WebCore;
     [super dealloc];
 }
 
-- (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer
+- (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment
 {
     self = [super init];
     
     if (self)
-        sharedBufferDataBuffer = dataBuffer;
+        sharedBufferDataSegment = &dataSegment;
 
     return self;
 }
 
 - (NSUInteger)length
 {
-    return sharedBufferDataBuffer->data.size();
+    return sharedBufferDataSegment->size();
 }
 
 - (const void *)bytes
 {
-    return sharedBufferDataBuffer->data.data();
+    return sharedBufferDataSegment->data();
 }
 
 @end
 
 namespace WebCore {
 
-Ref<SharedBuffer> SharedBuffer::wrapNSData(NSData *nsData)
+Ref<SharedBuffer> SharedBuffer::create(NSData *nsData)
 {
     return adoptRef(*new SharedBuffer((CFDataRef)nsData));
 }
@@ -93,57 +93,28 @@ RetainPtr<NSData> SharedBuffer::createNSData()
     return adoptNS((NSData *)createCFData().leakRef());
 }
 
-CFDataRef SharedBuffer::existingCFData()
-{
-    if (m_cfData)
-        return m_cfData.get();
-
-#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    if (m_dataArray.size() == 1)
-        return m_dataArray.at(0).get();
-#endif
-
-    return nullptr;
-}
-
 RetainPtr<CFDataRef> SharedBuffer::createCFData()
 {
-    if (CFDataRef cfData = existingCFData())
-        return cfData;
-
-    data(); // Force data into m_buffer from segments or data array.
-    return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.ptr()]).leakRef());
+    combineIntoOneSegment();
+    if (!m_segments.size())
+        return adoptCF(CFDataCreate(nullptr, nullptr, 0));
+    ASSERT(m_segments.size() == 1);
+    return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:m_segments[0]]).leakRef());
 }
 
 RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
 {
     NSData *resourceData = [NSData dataWithContentsOfFile:filePath];
     if (resourceData) 
-        return SharedBuffer::wrapNSData(resourceData);
+        return SharedBuffer::create(resourceData);
     return nullptr;
 }
 
 RetainPtr<NSArray> SharedBuffer::createNSDataArray() const
 {
-    if (auto platformData = (NSData *)m_cfData.get())
-        return @[ platformData ];
-
-    if (m_fileData)
-        return @[ [NSData dataWithBytes:m_fileData.data() length:m_fileData.size()] ];
-
-    auto dataArray = adoptNS([[NSMutableArray alloc] init]);
-    if (m_buffer->data.size())
-        [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.ptr()]).get()];
-
-#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    for (auto& data : m_dataArray)
-        [dataArray addObject:(NSData *)data.get()];
-#else
-    // Cocoa platforms all currently USE(NETWORK_CFDATA_ARRAY_CALLBACK), so implementing a code path for copying segments would be dead code.
-    // If this ever changes, the following static_assert will detect it.
-    static_assert(false, "FIXME: Copy the segments into an array of NSData objects.");
-#endif
-
+    auto dataArray = adoptNS([[NSMutableArray alloc] initWithCapacity:m_segments.size()]);
+    for (const auto& segment : m_segments)
+        [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:segment]).get()];
     return WTFMove(dataArray);
 }
 
index 08de639..76030d2 100644 (file)
@@ -173,27 +173,37 @@ void WebCoreAVFResourceLoader::fulfillRequestWithResource(CachedResource& resour
         responseOffset = static_cast<NSUInteger>(contentRange.firstBytePosition());
 
     // Check for possible unsigned overflow.
-    ASSERT([dataRequest currentOffset] >= [dataRequest requestedOffset]);
-    ASSERT([dataRequest requestedLength] >= ([dataRequest currentOffset] - [dataRequest requestedOffset]));
-
-    NSUInteger remainingLength = [dataRequest requestedLength] - static_cast<NSUInteger>([dataRequest currentOffset] - [dataRequest requestedOffset]);
-    do {
-        // Check to see if there is any data available in the buffer to fulfill the data request.
-        if (data->size() <= [dataRequest currentOffset] - responseOffset)
-            return;
-
-        const char* someData;
-        NSUInteger receivedLength = data->getSomeData(someData, static_cast<unsigned>([dataRequest currentOffset] - responseOffset));
-
-        // Create an NSData with only as much of the received data as necessary to fulfill the request.
-        NSUInteger length = MIN(receivedLength, remainingLength);
-        RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytes:someData length:length]);
-
-        [dataRequest respondWithData:nsData.get()];
-        remainingLength -= length;
-    } while (remainingLength);
+    ASSERT(dataRequest.currentOffset >= dataRequest.requestedOffset);
+    ASSERT(dataRequest.requestedLength >= (dataRequest.currentOffset - dataRequest.requestedOffset));
+
+    NSUInteger remainingLength = dataRequest.requestedLength - static_cast<NSUInteger>(dataRequest.currentOffset - dataRequest.requestedOffset);
+
+    auto bytesToSkip = dataRequest.currentOffset - responseOffset;
+    RetainPtr<NSArray> array = data->createNSDataArray();
+    for (NSData *segment in array.get()) {
+        if (bytesToSkip) {
+            if (bytesToSkip > segment.length) {
+                bytesToSkip -= segment.length;
+                continue;
+            }
+            auto bytesToUse = segment.length - bytesToSkip;
+            [dataRequest respondWithData:[segment subdataWithRange:NSMakeRange(static_cast<NSUInteger>(bytesToSkip), static_cast<NSUInteger>(segment.length - bytesToSkip))]];
+            bytesToSkip = 0;
+            remainingLength -= bytesToUse;
+            continue;
+        }
+        if (segment.length <= remainingLength) {
+            [dataRequest respondWithData:segment];
+            remainingLength -= segment.length;
+            continue;
+        }
+        [dataRequest respondWithData:[segment subdataWithRange:NSMakeRange(0, remainingLength)]];
+        remainingLength = 0;
+        if (!remainingLength)
+            break;
+    }
 
-    if ([dataRequest currentOffset] + [dataRequest requestedLength] >= [dataRequest requestedOffset]) {
+    if (dataRequest.currentOffset + dataRequest.requestedLength >= dataRequest.requestedOffset) {
         [m_avRequest.get() finishLoading];
         stopLoading();
     }
index 1cfd3eb..bd8567c 100644 (file)
@@ -201,7 +201,7 @@ RetainPtr<CFTypeRef> FontPlatformData::objectForEqualityCheck() const
 RefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
 {
     if (RetainPtr<CFDataRef> data = adoptCF(CTFontCopyTable(font(), table, kCTFontTableOptionNoOptions)))
-        return SharedBuffer::wrapCFData(data.get());
+        return SharedBuffer::create(data.get());
     
     return nullptr;
 }
index 4eeac73..fb8fa05 100644 (file)
@@ -1163,13 +1163,8 @@ void ResourceHandleStreamingClient::didReceiveData(ResourceHandle*, const char*
 
 void ResourceHandleStreamingClient::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int /* encodedLength */)
 {
-    // This pattern is suggested by SharedBuffer.h.
-    const char* segment;
-    unsigned position = 0;
-    while (unsigned length = buffer->getSomeData(segment, position)) {
-        handleDataReceived(segment, length);
-        position += length;
-    }
+    for (const auto& segment : buffer.get())
+        handleDataReceived(segment->data(), segment->size());
 }
 
 void ResourceHandleStreamingClient::didFinishLoading(ResourceHandle*)
index 2dba80a..f5fa697 100644 (file)
@@ -63,7 +63,7 @@ PassRefPtr<Image> Image::loadPlatformResource(const char *name)
     NSData *namedImageData = [NSData dataWithContentsOfFile:imagePath];
     if (namedImageData) {
         auto image = BitmapImage::create();
-        image->setData(SharedBuffer::wrapNSData(namedImageData), true);
+        image->setData(SharedBuffer::create(namedImageData), true);
         return WTFMove(image);
     }
 
index baf9e46..663f6d8 100644 (file)
@@ -42,17 +42,19 @@ namespace WebCore {
 
 namespace {
 
-unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer, unsigned offset)
+static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer)
 {
     unsigned bytesExtracted = 0;
-    const char* moreData;
-    while (unsigned moreDataLength = sharedBuffer.getSomeData(moreData, offset)) {
-        unsigned bytesToCopy = min(bufferLength - bytesExtracted, moreDataLength);
-        memcpy(buffer + bytesExtracted, moreData, bytesToCopy);
-        bytesExtracted += bytesToCopy;
-        if (bytesExtracted == bufferLength)
+    for (const auto& segment : sharedBuffer) {
+        if (bytesExtracted + segment->size() <= bufferLength) {
+            memcpy(buffer + bytesExtracted, segment->data(), segment->size());
+            bytesExtracted += segment->size();
+        } else {
+            ASSERT(bufferLength - bytesExtracted < segment->size());
+            memcpy(buffer + bytesExtracted, segment->data(), bufferLength - bytesExtracted);
+            bytesExtracted = bufferLength;
             break;
-        offset += bytesToCopy;
+        }
     }
     return bytesExtracted;
 }
@@ -100,7 +102,7 @@ RefPtr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption
 {
     static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP"
     char contents[lengthOfLongestSignature];
-    unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data, 0);
+    unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data);
     if (length < lengthOfLongestSignature)
         return nullptr;
 
index 9604a50..3a9561c 100644 (file)
@@ -157,11 +157,16 @@ public:
         if (setjmp(JMPBUF(m_png)))
             return decoder->setFailed();
 
-        const char* segment;
-        while (unsigned segmentLength = data.getSomeData(segment, m_readOffset)) {
-            m_readOffset += segmentLength;
+        auto bytesToSkip = m_readOffset;
+        for (const auto& segment : data) {
+            if (bytesToSkip > segment->size()) {
+                bytesToSkip -= segment->size();
+                continue;
+            }
+            m_readOffset += segment->size();
             m_currentBufferSize = m_readOffset;
-            png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment)), segmentLength);
+            png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment->data() + bytesToSkip)), segment->size() - bytesToSkip);
+            bytesToSkip = 0;
             // We explicitly specify the superclass encodedDataStatus() because we
             // merely want to check if we've managed to set the size, not
             // (recursively) trigger additional decoding if we haven't.
index 58adc96..ab1be83 100644 (file)
@@ -329,7 +329,7 @@ RefPtr<SharedBuffer> PlatformPasteboard::readBuffer(int index, const String& typ
 
     if (![pasteboardItem count])
         return nullptr;
-    return SharedBuffer::wrapNSData([pasteboardItem.get() objectAtIndex:0]);
+    return SharedBuffer::create([pasteboardItem.get() objectAtIndex:0]);
 }
 
 String PlatformPasteboard::readString(int index, const String& type)
index a90ec3d..8ad4758 100644 (file)
@@ -261,7 +261,7 @@ static void writeFileWrapperAsRTFDAttachment(NSFileWrapper *wrapper, const Strin
     if (!RTFDData)
         return;
 
-    newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(RTFDData).ptr(), NSRTFDPboardType, pasteboardName);
+    newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::create(RTFDData).ptr(), NSRTFDPboardType, pasteboardName);
 }
 
 void Pasteboard::write(const PasteboardImage& pasteboardImage)
@@ -278,7 +278,7 @@ void Pasteboard::write(const PasteboardImage& pasteboardImage)
         types.append(WebArchivePboardType);
 
     m_changeCount = writeURLForTypes(types, m_pasteboardName, pasteboardImage.url);
-    m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapCFData(imageData).ptr(), NSTIFFPboardType, m_pasteboardName);
+    m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::create(imageData).ptr(), NSTIFFPboardType, m_pasteboardName);
     if (pasteboardImage.dataInWebArchiveFormat)
         m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(pasteboardImage.dataInWebArchiveFormat.get(), WebArchivePboardType, m_pasteboardName);
     writeFileWrapperAsRTFDAttachment(fileWrapper(pasteboardImage), m_pasteboardName, m_changeCount);
index daff4fc..16a248c 100644 (file)
@@ -50,7 +50,7 @@ RefPtr<SharedBuffer> PlatformPasteboard::bufferForType(const String& pasteboardT
     NSData *data = [m_pasteboard.get() dataForType:pasteboardType];
     if (!data)
         return nullptr;
-    return SharedBuffer::wrapNSData([[data copy] autorelease]);
+    return SharedBuffer::create([[data copy] autorelease]);
 }
 
 int PlatformPasteboard::numberOfFiles()
index 8e574c1..9cff893 100644 (file)
@@ -604,7 +604,7 @@ void BlobResourceHandle::notifyResponseOnError()
 void BlobResourceHandle::notifyReceiveData(const char* data, int bytesRead)
 {
     if (client())
-        client()->didReceiveBuffer(this, SharedBuffer::create(data, bytesRead), bytesRead);
+        client()->didReceiveBuffer(this, SharedBuffer::create(reinterpret_cast<const uint8_t*>(data), bytesRead), bytesRead);
 }
 
 void BlobResourceHandle::notifyFail(Error errorCode)
index 267b597..251693e 100644 (file)
@@ -31,6 +31,8 @@
 #include "config.h"
 #include "MIMEHeader.h"
 
+#if ENABLE(MHTML)
+
 #include "ParsedContentType.h"
 #include "SharedBufferChunkReader.h"
 #include <wtf/HashMap.h>
@@ -133,3 +135,5 @@ MIMEHeader::MIMEHeader()
 }
 
 }
+
+#endif
index 4df3e28..008aec2 100644 (file)
@@ -28,8 +28,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef MIMEHeader_h
-#define MIMEHeader_h
+#pragma once
+
+#if ENABLE(MHTML)
 
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
index de29de2..1d39f68 100644 (file)
@@ -177,7 +177,7 @@ void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(CFD
         if (protectedThis->hasHandle() && m_handle->client()) {
             LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data());
 
-            m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapCFData(data), originalLength);
+            m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength);
         }
 
         CFRelease(data);
index d1cd8e5..bfc557a 100644 (file)
@@ -184,7 +184,7 @@ void SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData(CFDataRef
     LOG(Network, "CFNet - SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData(handle=%p, bytes=%ld) (%s)", m_handle, CFDataGetLength(data), m_handle->firstRequest().url().string().utf8().data());
 
     if (ResourceHandleClient* client = m_handle->client())
-        client->didReceiveBuffer(m_handle, SharedBuffer::wrapCFData(data), originalLength);
+        client->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength);
 }
 
 void SynchronousResourceHandleCFURLConnectionDelegate::didFinishLoading()
index c825a29..f025cfb 100644 (file)
@@ -174,7 +174,7 @@ using namespace WebCore;
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
     // -1 means we do not provide any data about transfer size to inspector so it would use
     // Content-Length headers or content size to show transfer size.
-    m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
+    m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), -1);
 }
 
 - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
index 631f4be..d7a34f0 100644 (file)
@@ -223,7 +223,7 @@ using namespace WebCore;
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
         // -1 means we do not provide any data about transfer size to inspector so it would use
         // Content-Length headers or content size to show transfer size.
-        m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
+        m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), -1);
     });
 }
 
index 3b4b61a..9c0bf79 100644 (file)
 namespace WebCore {
 
 SharedBuffer::SharedBuffer(SoupBuffer* soupBuffer)
-    : m_buffer(*new DataBuffer)
-    , m_soupBuffer(soupBuffer)
 {
     ASSERT(soupBuffer);
+    m_size = soupBuffer->length;
+    m_segments.append(DataSegment::create(GUniquePtr<SoupBuffer>(soupBuffer)));
 }
 
 Ref<SharedBuffer> SharedBuffer::wrapSoupBuffer(SoupBuffer* soupBuffer)
@@ -40,11 +40,6 @@ Ref<SharedBuffer> SharedBuffer::wrapSoupBuffer(SoupBuffer* soupBuffer)
 
 GUniquePtr<SoupBuffer> SharedBuffer::createSoupBuffer(unsigned offset, unsigned size)
 {
-    if (m_soupBuffer && !offset && !size) {
-        GUniquePtr<SoupBuffer> buffer(soup_buffer_copy(m_soupBuffer.get()));
-        return buffer;
-    }
-
     ref();
     GUniquePtr<SoupBuffer> buffer(soup_buffer_new_with_owner(data() + offset, size ? size : this->size(), this, [](void* data) {
         static_cast<SharedBuffer*>(data)->deref();
@@ -52,57 +47,6 @@ GUniquePtr<SoupBuffer> SharedBuffer::createSoupBuffer(unsigned offset, unsigned
     return buffer;
 }
 
-void SharedBuffer::clearPlatformData()
-{
-    m_soupBuffer.reset();
-}
-
-void SharedBuffer::maybeTransferPlatformData()
-{
-    if (!m_soupBuffer)
-        return;
-
-    ASSERT(!m_size);
-
-    // Hang on to the m_soupBuffer pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
-    // and we need to make sure to early return when it does.
-    GUniquePtr<SoupBuffer> soupBuffer;
-    soupBuffer.swap(m_soupBuffer);
-
-    append(soupBuffer->data, soupBuffer->length);
-}
-
-bool SharedBuffer::hasPlatformData() const
-{
-    return m_soupBuffer.get();
-}
-
-const char* SharedBuffer::platformData() const
-{
-    return m_soupBuffer->data;
-}
-
-unsigned SharedBuffer::platformDataSize() const
-{
-    return m_soupBuffer->length;
-}
-
-bool SharedBuffer::maybeAppendPlatformData(SharedBuffer&)
-{
-    return false;
-}
-
-bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
-{
-    if (!newContents.hasPlatformData())
-        return false;
-
-    clear();
-    // FIXME: Use GRefPtr instead of GUniquePtr for the SoupBuffer.
-    m_soupBuffer.swap(newContents.m_soupBuffer);
-    return true;
-}
-
 } // namespace WebCore
 
 #endif
index 1306108..cbb305b 100644 (file)
@@ -229,7 +229,7 @@ RefPtr<ArrayBuffer> XMLHttpRequest::createResponseArrayBuffer()
     ASSERT(m_responseType == ResponseType::Arraybuffer);
     ASSERT(doneWithoutErrors());
 
-    auto result = m_binaryResponseBuilder ? m_binaryResponseBuilder->createArrayBuffer() : ArrayBuffer::create(nullptr, 0);
+    auto result = m_binaryResponseBuilder ? m_binaryResponseBuilder->tryCreateArrayBuffer() : ArrayBuffer::create(nullptr, 0);
     m_binaryResponseBuilder = nullptr;
     return result;
 }
index d5533c0..0fa459b 100644 (file)
@@ -1,3 +1,18 @@
+2017-04-24  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce copies and allocations in SharedBuffer::append
+        https://bugs.webkit.org/show_bug.cgi?id=170956
+
+        Reviewed by Andreas Kling.
+
+        * WebView/WebArchive.mm:
+        (-[WebArchive initWithData:]):
+        * WebView/WebFrame.mm:
+        (-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
+        * WebView/WebResource.mm:
+        (-[WebResource initWithCoder:]):
+        (-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]):
+
 2017-04-24  Dan Bernstein  <mitz@apple.com>
 
         [Cocoa] Some ivars are needlessly @protected
index ff7546d..d1044e1 100644 (file)
@@ -200,7 +200,7 @@ static BOOL isArrayOfClass(id object, Class elementClass)
 #endif
 
     _private = [[WebArchivePrivate alloc] init];
-    auto coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData(data));
+    auto coreArchive = LegacyWebArchive::create(SharedBuffer::create(data));
     if (!coreArchive) {
         [self release];
         return nil;
index b2c27b5..6da930a 100644 (file)
@@ -2493,7 +2493,7 @@ static NSURL *createUniqueWebDataURL()
     ResourceRequest request(baseURL);
 
     ResourceResponse response(responseURL, MIMEType, [data length], encodingName);
-    SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
+    SubstituteData substituteData(WebCore::SharedBuffer::create(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
 
     _private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
 }
index b3bb75b..3977b44 100644 (file)
@@ -149,7 +149,7 @@ static NSString * const WebResourceResponseKey =          @"WebResourceResponse"
         return nil;
     }
 
-    auto coreResource = ArchiveResource::create(SharedBuffer::wrapNSData(data), url, mimeType, textEncoding, frameName, response);
+    auto coreResource = ArchiveResource::create(SharedBuffer::create(data), url, mimeType, textEncoding, frameName, response);
     if (!coreResource) {
         [self release];
         return nil;
@@ -301,7 +301,7 @@ static NSString * const WebResourceResponseKey =          @"WebResourceResponse"
         return nil;
     }
 
-    auto coreResource = ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response);
+    auto coreResource = ArchiveResource::create(SharedBuffer::create(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response);
     if (!coreResource) {
         [self release];
         return nil;
index 9c498b4..a705396 100644 (file)
@@ -1,3 +1,31 @@
+2017-04-24  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce copies and allocations in SharedBuffer::append
+        https://bugs.webkit.org/show_bug.cgi?id=170956
+
+        Reviewed by Andreas Kling.
+
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
+        * Platform/IPC/DataReference.cpp:
+        (IPC::SharedBufferDataReference::encode):
+        * Shared/ShareableResource.cpp:
+        (WebKit::ShareableResource::wrapInSharedBuffer):
+        * UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm:
+        (-[WKURLSchemeHandlerTaskImpl didReceiveData:]):
+        * WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
+        (-[WKWebProcessPlugInBrowserContextController _setEditingDelegate:]):
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::addArchiveResource):
+        (WebKit::PDFPlugin::liveResourceData):
+        (WebKit::PDFPlugin::writeItemsToPasteboard):
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::redeliverManualStream):
+        * WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
+        (WebKit::WebDragClient::declareAndWriteDragImage):
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::cachedResponseDataForURL):
+
 2017-04-24  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Switch to use ENABLE_REMOTE_INSPECTOR instead of ENABLE_INSPECTOR_SERVER for the remote inspector
index f0c5c3c..d135afe 100644 (file)
@@ -386,7 +386,7 @@ static WebCore::NetworkLoadPriority toNetworkLoadPriority(float priority)
 
     auto storedCredentials = _withCredentials ? WebCore::StoredCredentials::AllowStoredCredentials : WebCore::StoredCredentials::DoNotAllowStoredCredentials;
     if (auto* networkDataTask = _session->dataTaskForIdentifier(dataTask.taskIdentifier, storedCredentials))
-        networkDataTask->didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
+        networkDataTask->didReceiveData(WebCore::SharedBuffer::create(data));
 }
 
 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
index 9bdec4f..7da38d6 100644 (file)
@@ -47,13 +47,8 @@ void SharedBufferDataReference::encode(Encoder& encoder) const
     encoder.reserve(bufferSize + sizeof(uint64_t));
     encoder << bufferSize;
 
-    const char* partialData;
-    unsigned position = 0;
-    while (position < bufferSize) {
-        unsigned bytesToWrite = m_buffer->getSomeData(partialData, position);
-        encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(partialData), bytesToWrite, 1);
-        position += bytesToWrite;
-    }
+    for (const auto& segment : *m_buffer)
+        encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(segment->data()), segment->size(), 1);
 }
 
 } // namespace IPC
index 9e2eb00..d147d80 100644 (file)
@@ -87,7 +87,7 @@ RefPtr<SharedBuffer> ShareableResource::wrapInSharedBuffer()
 #if USE(CF)
     RetainPtr<CFAllocatorRef> deallocator = adoptCF(createShareableResourceDeallocator(this));
     RetainPtr<CFDataRef> cfData = adoptCF(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data()), static_cast<CFIndex>(size()), deallocator.get()));
-    return SharedBuffer::wrapCFData(cfData.get());
+    return SharedBuffer::create(cfData.get());
 #elif USE(SOUP)
     return SharedBuffer::wrapSoupBuffer(soup_buffer_new_with_owner(data(), size(), this, [](void* data) { static_cast<ShareableResource*>(data)->deref(); }));
 #else
index d0e868b..952f131 100644 (file)
@@ -70,7 +70,7 @@ static void raiseExceptionIfNecessary(WebKit::WebURLSchemeHandlerTask::Exception
 
 - (void)didReceiveData:(NSData *)data
 {
-    auto result = _urlSchemeHandlerTask->task().didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
+    auto result = _urlSchemeHandlerTask->task().didReceiveData(WebCore::SharedBuffer::create(data));
     raiseExceptionIfNecessary(result);
 }
 
index 72bae5c..486fcfd 100644 (file)
@@ -646,7 +646,7 @@ static inline WKEditorInsertAction toWK(EditorInsertAction action)
             auto dataByType = [m_controller->_editingDelegate.get() _webProcessPlugInBrowserContextController:m_controller pasteboardDataForRange:wrapper(*InjectedBundleRangeHandle::getOrCreate(range).get())];
             for (NSString *type in dataByType) {
                 pasteboardTypes.append(type);
-                pasteboardData.append(SharedBuffer::wrapNSData(dataByType[type]));
+                pasteboardData.append(SharedBuffer::create(dataByType[type]));
             };
         }
 
index 130bf05..02d84a1 100644 (file)
@@ -916,7 +916,7 @@ void PDFPlugin::addArchiveResource()
     RetainPtr<NSURLResponse> response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:m_sourceURL statusCode:200 HTTPVersion:(NSString*)kCFHTTPVersion1_1 headerFields:headers]);
     ResourceResponse synthesizedResponse(response.get());
 
-    RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::wrapCFData(m_data.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse);
+    RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::create(m_data.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse);
     pluginView()->frame()->document()->loader()->addArchiveResource(resource.releaseNonNull());
 }
 
@@ -1756,7 +1756,7 @@ RefPtr<SharedBuffer> PDFPlugin::liveResourceData() const
     if (!pdfData)
         return nullptr;
 
-    return SharedBuffer::wrapNSData(pdfData);
+    return SharedBuffer::create(pdfData);
 }
 
 bool PDFPlugin::pluginHandlesContentOffsetForAccessibilityHitTest() const
@@ -1827,7 +1827,7 @@ void PDFPlugin::writeItemsToPasteboard(NSString *pasteboardName, NSArray *items,
             RetainPtr<NSString> plainTextString = adoptNS([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
             webProcess.parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardStringForType(pasteboardName, type, plainTextString.get()), Messages::WebPasteboardProxy::SetPasteboardStringForType::Reply(newChangeCount), 0);
         } else {
-            RefPtr<SharedBuffer> buffer = SharedBuffer::wrapNSData(data);
+            RefPtr<SharedBuffer> buffer = SharedBuffer::create(data);
 
             if (!buffer)
                 continue;
index f383281..8c04351 100644 (file)
@@ -1311,14 +1311,8 @@ void PluginView::redeliverManualStream()
 
     // Deliver the data.
     if (m_manualStreamData) {
-        const char* data;
-        unsigned position = 0;
-
-        while (unsigned length = m_manualStreamData->getSomeData(data, position)) {
-            manualLoadDidReceiveData(data, length);
-            position += length;
-        }
-
+        for (const auto& segment : *m_manualStreamData)
+            manualLoadDidReceiveData(segment->data(), segment->size());
         m_manualStreamData = nullptr;
     }
 
index 57144af..5f45654 100644 (file)
@@ -165,7 +165,7 @@ void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Eleme
     SharedMemory::Handle archiveHandle;
     size_t archiveSize = 0;
     if (data) {
-        RefPtr<SharedBuffer> archiveBuffer = SharedBuffer::wrapNSData((NSData *)data.get());
+        RefPtr<SharedBuffer> archiveBuffer = SharedBuffer::create((NSData *)data.get());
         RefPtr<SharedMemory> archiveSharedMemoryBuffer = SharedMemory::allocate(archiveBuffer->size());
         if (!archiveSharedMemoryBuffer)
             return;
index 4519d23..f8fb041 100644 (file)
@@ -709,7 +709,7 @@ String WebPage::cachedResponseMIMETypeForURL(const URL& url)
 
 RefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const URL& url)
 {
-    return SharedBuffer::wrapNSData([cachedResponseForURL(this, url) data]);
+    return SharedBuffer::create([cachedResponseForURL(this, url) data]);
 }
 
 bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request)
index 041fdfa..937a219 100644 (file)
@@ -1,3 +1,13 @@
+2017-04-24  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce copies and allocations in SharedBuffer::append
+        https://bugs.webkit.org/show_bug.cgi?id=170956
+
+        Reviewed by Andreas Kling.
+
+        * TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm:
+        (TestWebKitAPI::TEST_F):
+
 2017-04-24  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Switch to use ENABLE_REMOTE_INSPECTOR instead of ENABLE_INSPECTOR_SERVER for the remote inspector
index 32a737c..0a7dd38 100644 (file)
@@ -87,7 +87,7 @@ TEST_F(SharedBufferTest, appendBufferCreatedWithContentsOfExistingFile)
     EXPECT_EQ('a', buffer->data()[strlen(SharedBufferTest::testData())]);
 }
 
-TEST_F(SharedBufferTest, createArrayBuffer)
+TEST_F(SharedBufferTest, tryCreateArrayBuffer)
 {
     char testData0[] = "Hello";
     char testData1[] = "World";
@@ -95,13 +95,13 @@ TEST_F(SharedBufferTest, createArrayBuffer)
     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(testData0, strlen(testData0));
     sharedBuffer->append(testData1, strlen(testData1));
     sharedBuffer->append(testData2, strlen(testData2));
-    RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->createArrayBuffer();
+    RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->tryCreateArrayBuffer();
     char expectedConcatenation[] = "HelloWorldGoodbye";
     ASSERT_EQ(strlen(expectedConcatenation), arrayBuffer->byteLength());
     EXPECT_EQ(0, memcmp(expectedConcatenation, arrayBuffer->data(), strlen(expectedConcatenation)));
 }
 
-TEST_F(SharedBufferTest, createArrayBufferLargeSegments)
+TEST_F(SharedBufferTest, tryCreateArrayBufferLargeSegments)
 {
     Vector<char> vector0(0x4000, 'a');
     Vector<char> vector1(0x4000, 'b');
@@ -110,7 +110,7 @@ TEST_F(SharedBufferTest, createArrayBufferLargeSegments)
     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(WTFMove(vector0));
     sharedBuffer->append(WTFMove(vector1));
     sharedBuffer->append(WTFMove(vector2));
-    RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->createArrayBuffer();
+    RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->tryCreateArrayBuffer();
     ASSERT_EQ(0x4000U + 0x4000U + 0x4000U, arrayBuffer->byteLength());
     int position = 0;
     for (int i = 0; i < 0x4000; ++i) {
index 2646766..399b95c 100644 (file)
@@ -59,8 +59,8 @@ TEST_F(SharedBufferTest, createNSDataArray)
         buffer->append((CFDataRef)worldData);
         expectDataArraysEqual(@[ helloData, worldData ], buffer->createNSDataArray().get());
 
-        expectDataArraysEqual(@[ helloData ], SharedBuffer::wrapNSData(helloData)->createNSDataArray().get());
-        expectDataArraysEqual(@[ worldData ], SharedBuffer::wrapCFData((CFDataRef)worldData)->createNSDataArray().get());
+        expectDataArraysEqual(@[ helloData ], SharedBuffer::create(helloData)->createNSDataArray().get());
+        expectDataArraysEqual(@[ worldData ], SharedBuffer::create((CFDataRef)worldData)->createNSDataArray().get());
 
         expectDataArraysEqual(@[ [NSData dataWithContentsOfFile:tempFilePath()] ], SharedBuffer::createWithContentsOfFile(tempFilePath())->createNSDataArray().get());
     }