<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[199524] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/199524">199524</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2016-04-13 17:54:10 -0700 (Wed, 13 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modern IDB (Blob support): Support retrieving Blobs from IDB.
https://bugs.webkit.org/show_bug.cgi?id=156367

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (No testable change in behavior yet, current tests pass).

This patch does the following:
- Pulls BlobURLs and stored filenames out of IDB whenever an IDB record is fetched.
- Adds those URLs and filenames to IDBValue.
- Uses IDBValue in more places instead of SharedBuffer/ThreadSafeBuffer.
- Teaches SerializedScriptValue, Blob, and File how to read the URLs and filenames when they exist.
- Teaches the Blob registry to register a new type of Blob that is not a &quot;File&quot; but is backed by one.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::setGetResult):

* Modules/indexeddb/IDBGetResult.h:
(WebCore::IDBGetResult::IDBGetResult):

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::setResultToStructuredClone):
* Modules/indexeddb/IDBRequest.h:

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::didGetRecordOnServer):

* Modules/indexeddb/IDBValue.cpp:
(WebCore::IDBValue::IDBValue):
* Modules/indexeddb/IDBValue.h:

* Modules/indexeddb/server/MemoryIndexCursor.cpp:
(WebCore::IDBServer::MemoryIndexCursor::currentData):

* Modules/indexeddb/server/MemoryObjectStoreCursor.cpp:
(WebCore::IDBServer::MemoryObjectStoreCursor::currentData):

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

* Modules/indexeddb/server/SQLiteIDBCursor.cpp:
(WebCore::IDBServer::SQLiteIDBCursor::currentData):
(WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
* Modules/indexeddb/server/SQLiteIDBCursor.h:
(WebCore::IDBServer::SQLiteIDBCursor::currentValue):
(WebCore::IDBServer::SQLiteIDBCursor::currentValueBuffer): Deleted.

* Modules/indexeddb/server/SQLiteIDBTransaction.h:
(WebCore::IDBServer::SQLiteIDBTransaction::backingStore):

* Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::WorkerThreadableWebSocketChannel::Bridge::send):

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::deserializeIDBValueDataToJSValue):
(WebCore::deserializeIDBValueData):
(WebCore::deserializeIDBValue):
* bindings/js/IDBBindingUtilities.h:

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readFile):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::CloneDeserializer::blobFilePathForBlobURL):
(WebCore::SerializedScriptValue::deserialize):
* bindings/js/SerializedScriptValue.h:

* fileapi/Blob.cpp:
(WebCore::Blob::Blob):
* fileapi/Blob.h:
(WebCore::Blob::deserialize):

* fileapi/File.cpp:
(WebCore::File::File):

* fileapi/ThreadableBlobRegistry.cpp:
(WebCore::threadableQueue):
(WebCore::ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked):
* fileapi/ThreadableBlobRegistry.h:

* platform/CrossThreadTask.h:
(WebCore::createCrossThreadTask):

* platform/network/BlobRegistry.h:

* platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::registerBlobURL):
(WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
* platform/network/BlobRegistryImpl.h:

Source/WebKit2:

* NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
(WebKit::NetworkBlobRegistry::registerBlobURLOptionallyFileBacked):
* NetworkProcess/FileAPI/NetworkBlobRegistry.h:

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::registerBlobURLOptionallyFileBacked):
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/NetworkConnectionToWebProcess.messages.in:

* WebProcess/FileAPI/BlobRegistryProxy.cpp:
(WebKit::BlobRegistryProxy::registerBlobURLOptionallyFileBacked):
* WebProcess/FileAPI/BlobRegistryProxy.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBCursorcpp">trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBGetResulth">trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBRequestcpp">trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBRequesth">trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBValuecpp">trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBValueh">trunk/Source/WebCore/Modules/indexeddb/IDBValue.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIndexCursorcpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryObjectStoreCursorcpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorh">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBTransactionh">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebsocketsWorkerThreadableWebSocketChannelcpp">trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiesh">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsSerializedScriptValuecpp">trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsSerializedScriptValueh">trunk/Source/WebCore/bindings/js/SerializedScriptValue.h</a></li>
<li><a href="#trunkSourceWebCorefileapiBlobcpp">trunk/Source/WebCore/fileapi/Blob.cpp</a></li>
<li><a href="#trunkSourceWebCorefileapiBlobh">trunk/Source/WebCore/fileapi/Blob.h</a></li>
<li><a href="#trunkSourceWebCorefileapiFilecpp">trunk/Source/WebCore/fileapi/File.cpp</a></li>
<li><a href="#trunkSourceWebCorefileapiThreadableBlobRegistrycpp">trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp</a></li>
<li><a href="#trunkSourceWebCorefileapiThreadableBlobRegistryh">trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h</a></li>
<li><a href="#trunkSourceWebCoreplatformCrossThreadTaskh">trunk/Source/WebCore/platform/CrossThreadTask.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkBlobRegistryh">trunk/Source/WebCore/platform/network/BlobRegistry.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkBlobRegistryImplcpp">trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkBlobRegistryImplh">trunk/Source/WebCore/platform/network/BlobRegistryImpl.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessFileAPINetworkBlobRegistrycpp">trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessFileAPINetworkBlobRegistryh">trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkConnectionToWebProcesscpp">trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkConnectionToWebProcessh">trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkConnectionToWebProcessmessagesin">trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessFileAPIBlobRegistryProxycpp">trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessFileAPIBlobRegistryProxyh">trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/ChangeLog        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -1,3 +1,100 @@
</span><ins>+2016-04-13  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB (Blob support): Support retrieving Blobs from IDB.
+        https://bugs.webkit.org/show_bug.cgi?id=156367
+
+        Reviewed by Alex Christensen.
+
+        No new tests (No testable change in behavior yet, current tests pass).
+
+        This patch does the following:
+        - Pulls BlobURLs and stored filenames out of IDB whenever an IDB record is fetched.
+        - Adds those URLs and filenames to IDBValue.
+        - Uses IDBValue in more places instead of SharedBuffer/ThreadSafeBuffer.
+        - Teaches SerializedScriptValue, Blob, and File how to read the URLs and filenames when they exist.
+        - Teaches the Blob registry to register a new type of Blob that is not a &quot;File&quot; but is backed by one.
+
+        * Modules/indexeddb/IDBCursor.cpp:
+        (WebCore::IDBCursor::setGetResult):
+        
+        * Modules/indexeddb/IDBGetResult.h:
+        (WebCore::IDBGetResult::IDBGetResult):
+        
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::setResultToStructuredClone):
+        * Modules/indexeddb/IDBRequest.h:
+        
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::didGetRecordOnServer):
+        
+        * Modules/indexeddb/IDBValue.cpp:
+        (WebCore::IDBValue::IDBValue):
+        * Modules/indexeddb/IDBValue.h:
+        
+        * Modules/indexeddb/server/MemoryIndexCursor.cpp:
+        (WebCore::IDBServer::MemoryIndexCursor::currentData):
+        
+        * Modules/indexeddb/server/MemoryObjectStoreCursor.cpp:
+        (WebCore::IDBServer::MemoryObjectStoreCursor::currentData):
+        
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord):
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+        
+        * Modules/indexeddb/server/SQLiteIDBCursor.cpp:
+        (WebCore::IDBServer::SQLiteIDBCursor::currentData):
+        (WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
+        * Modules/indexeddb/server/SQLiteIDBCursor.h:
+        (WebCore::IDBServer::SQLiteIDBCursor::currentValue):
+        (WebCore::IDBServer::SQLiteIDBCursor::currentValueBuffer): Deleted.
+        
+        * Modules/indexeddb/server/SQLiteIDBTransaction.h:
+        (WebCore::IDBServer::SQLiteIDBTransaction::backingStore):
+        
+        * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+        (WebCore::WorkerThreadableWebSocketChannel::Bridge::send):
+        
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::deserializeIDBValueDataToJSValue):
+        (WebCore::deserializeIDBValueData):
+        (WebCore::deserializeIDBValue):
+        * bindings/js/IDBBindingUtilities.h:
+        
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneDeserializer::deserialize):
+        (WebCore::CloneDeserializer::CloneDeserializer):
+        (WebCore::CloneDeserializer::readFile):
+        (WebCore::CloneDeserializer::readTerminal):
+        (WebCore::CloneDeserializer::blobFilePathForBlobURL):
+        (WebCore::SerializedScriptValue::deserialize):
+        * bindings/js/SerializedScriptValue.h:
+
+        * fileapi/Blob.cpp:
+        (WebCore::Blob::Blob):
+        * fileapi/Blob.h:
+        (WebCore::Blob::deserialize):
+
+        * fileapi/File.cpp:
+        (WebCore::File::File):
+
+        * fileapi/ThreadableBlobRegistry.cpp:
+        (WebCore::threadableQueue):
+        (WebCore::ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked):
+        * fileapi/ThreadableBlobRegistry.h:
+
+        * platform/CrossThreadTask.h:
+        (WebCore::createCrossThreadTask):
+
+        * platform/network/BlobRegistry.h:
+
+        * platform/network/BlobRegistryImpl.cpp:
+        (WebCore::BlobRegistryImpl::registerBlobURL):
+        (WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
+        * platform/network/BlobRegistryImpl.h:
+
</ins><span class="cx"> 2016-04-13  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Text on compositing layer with negative letter-spacing is truncated.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBCursorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -418,7 +418,7 @@
</span><span class="cx">     if (isKeyCursor())
</span><span class="cx">         m_deprecatedCurrentValue = { };
</span><span class="cx">     else
</span><del>-        m_deprecatedCurrentValue = deserializeIDBValueData(*context, getResult.value().data());
</del><ins>+        m_deprecatedCurrentValue = deserializeIDBValue(*context, getResult.value());
</ins><span class="cx"> 
</span><span class="cx">     m_gotValue = true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBGetResulth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -43,10 +43,10 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    IDBGetResult(Ref&lt;SharedBuffer&gt;&amp;&amp; buffer, const IDBKeyData&amp; currentPrimaryKey)
-        : m_primaryKeyData(currentPrimaryKey)
</del><ins>+    IDBGetResult(const IDBValue&amp; value, const IDBKeyData&amp; currentPrimaryKey)
+        : m_value(value)
+        , m_primaryKeyData(currentPrimaryKey)
</ins><span class="cx">     {
</span><del>-        dataFromBuffer(buffer.get());
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     IDBGetResult(const ThreadSafeDataBuffer&amp; buffer)
</span><span class="lines">@@ -54,6 +54,11 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    IDBGetResult(IDBValue&amp;&amp; buffer)
+        : m_value(WTFMove(buffer))
+    {
+    }
+
</ins><span class="cx">     IDBGetResult(PassRefPtr&lt;IDBKey&gt; key)
</span><span class="cx">         : m_keyData(key.get())
</span><span class="cx">     {
</span><span class="lines">@@ -78,13 +83,20 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    IDBGetResult(const IDBKeyData&amp; keyData, const IDBKeyData&amp; primaryKeyData, const ThreadSafeDataBuffer&amp; valueBuffer)
-        : m_value(valueBuffer)
</del><ins>+    IDBGetResult(const IDBKeyData&amp; keyData, const IDBKeyData&amp; primaryKeyData, IDBValue&amp;&amp; value)
+        : m_value(WTFMove(value))
</ins><span class="cx">         , m_keyData(keyData)
</span><span class="cx">         , m_primaryKeyData(primaryKeyData)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    IDBGetResult(const IDBKeyData&amp; keyData, const IDBKeyData&amp; primaryKeyData, const IDBValue&amp; value)
+        : m_value(value)
+        , m_keyData(keyData)
+        , m_primaryKeyData(primaryKeyData)
+    {
+    }
+
</ins><span class="cx">     IDBGetResult isolatedCopy() const;
</span><span class="cx"> 
</span><span class="cx">     const IDBValue&amp; value() const { return m_value; }
</span><span class="lines">@@ -97,7 +109,7 @@
</span><span class="cx">     template&lt;class Decoder&gt; static bool decode(Decoder&amp;, IDBGetResult&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    WEBCORE_EXPORT void dataFromBuffer(SharedBuffer&amp;);
</del><ins>+    void dataFromBuffer(SharedBuffer&amp;);
</ins><span class="cx"> 
</span><span class="cx">     IDBValue m_value;
</span><span class="cx">     IDBKeyData m_keyData;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -341,7 +341,7 @@
</span><span class="cx">     m_result = IDBAny::create(Deprecated::ScriptValue(scriptExecutionContext()-&gt;vm(), JSC::JSValue(number)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void IDBRequest::setResultToStructuredClone(const ThreadSafeDataBuffer&amp; valueData)
</del><ins>+void IDBRequest::setResultToStructuredClone(const IDBValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBRequest::setResultToStructuredClone&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -349,8 +349,8 @@
</span><span class="cx">     if (!context)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    Deprecated::ScriptValue value = deserializeIDBValueData(*context, valueData);
-    m_result = IDBAny::create(WTFMove(value));
</del><ins>+    Deprecated::ScriptValue scriptValue = deserializeIDBValue(*context, value);
+    m_result = IDBAny::create(WTFMove(scriptValue));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void IDBRequest::setResultToUndefined()
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBRequesth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> class IDBKeyData;
</span><span class="cx"> class IDBObjectStore;
</span><span class="cx"> class IDBResultData;
</span><ins>+class IDBValue;
</ins><span class="cx"> class ThreadSafeDataBuffer;
</span><span class="cx"> 
</span><span class="cx"> namespace IDBClient {
</span><span class="lines">@@ -98,7 +99,7 @@
</span><span class="cx"> 
</span><span class="cx">     void setResult(const IDBKeyData*);
</span><span class="cx">     void setResult(uint64_t);
</span><del>-    void setResultToStructuredClone(const ThreadSafeDataBuffer&amp;);
</del><ins>+    void setResultToStructuredClone(const IDBValue&amp;);
</ins><span class="cx">     void setResultToUndefined();
</span><span class="cx"> 
</span><span class="cx">     IDBAny* modernResult() { return m_result.get(); }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -738,7 +738,7 @@
</span><span class="cx">             request.setResultToUndefined();
</span><span class="cx">     } else {
</span><span class="cx">         if (resultData.getResult().value().data().data())
</span><del>-            request.setResultToStructuredClone(resultData.getResult().value().data());
</del><ins>+            request.setResultToStructuredClone(resultData.getResult().value());
</ins><span class="cx">         else
</span><span class="cx">             request.setResultToUndefined();
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -54,6 +54,13 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBValue::IDBValue(const ThreadSafeDataBuffer&amp; value, Vector&lt;String&gt;&amp;&amp; blobURLs, Vector&lt;String&gt;&amp;&amp; blobFilePaths)
+    : m_data(value)
+    , m_blobURLs(WTFMove(blobURLs))
+    , m_blobFilePaths(WTFMove(blobFilePaths))
+{
+}
+
</ins><span class="cx"> IDBValue::IDBValue(const ThreadSafeDataBuffer&amp; value, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths)
</span><span class="cx">     : m_data(value)
</span><span class="cx">     , m_blobURLs(blobURLs)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBValue.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBValue.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBValue.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx">     IDBValue(const SerializedScriptValue&amp;);
</span><span class="cx">     IDBValue(const ThreadSafeDataBuffer&amp;);
</span><span class="cx">     IDBValue(const SerializedScriptValue&amp;, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths);
</span><ins>+    IDBValue(const ThreadSafeDataBuffer&amp;, Vector&lt;String&gt;&amp;&amp; blobURLs, Vector&lt;String&gt;&amp;&amp; blobFilePaths);
</ins><span class="cx">     IDBValue(const ThreadSafeDataBuffer&amp;, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths);
</span><span class="cx"> 
</span><span class="cx">     IDBValue isolatedCopy() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIndexCursorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -74,8 +74,10 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_info.cursorType() == IndexedDB::CursorType::KeyOnly)
</span><span class="cx">         getResult = { m_currentKey, m_currentPrimaryKey };
</span><del>-    else
-        getResult = { m_currentKey, m_currentPrimaryKey, m_index.objectStore().valueForKey(m_currentPrimaryKey) };
</del><ins>+    else {
+        IDBValue value = { m_index.objectStore().valueForKey(m_currentPrimaryKey), { }, { } };
+        getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value) };
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MemoryIndexCursor::iterate(const IDBKeyData&amp; key, uint32_t count, IDBGetResult&amp; getResult)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryObjectStoreCursorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -189,7 +189,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_currentPositionKey = **m_iterator;
</span><del>-    data = { m_currentPositionKey, m_currentPositionKey, m_objectStore.valueForKeyRange(m_currentPositionKey) };
</del><ins>+    IDBValue value = { m_objectStore.valueForKeyRange(m_currentPositionKey), { }, { } };
+    data = { m_currentPositionKey, m_currentPositionKey, WTFMove(value) };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MemoryObjectStoreCursor::incrementForwardIterator(std::set&lt;IDBKeyData&gt;&amp; set, const IDBKeyData&amp; key, uint32_t count)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -1049,7 +1049,8 @@
</span><span class="cx"> 
</span><span class="cx">     while (!cursor-&gt;currentKey().isNull()) {
</span><span class="cx">         auto&amp; key = cursor-&gt;currentKey();
</span><del>-        auto valueBuffer = ThreadSafeDataBuffer::copyVector(cursor-&gt;currentValueBuffer());
</del><ins>+        auto* value = cursor-&gt;currentValue();
+        ThreadSafeDataBuffer valueBuffer = value ? value-&gt;data() : ThreadSafeDataBuffer();
</ins><span class="cx"> 
</span><span class="cx">         IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
</span><span class="cx">         if (!error.isNull()) {
</span><span class="lines">@@ -1627,6 +1628,60 @@
</span><span class="cx">     return error;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBError SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector&lt;String&gt;&amp; blobURLs, Vector&lt;String&gt;&amp; blobFilePaths)
+{
+    ASSERT(objectStoreRecord);
+
+    HashSet&lt;String&gt; blobURLSet;
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT blobURL FROM BlobRecords WHERE objectStoreRow = ?&quot;));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindInt64(1, objectStoreRecord) != SQLITE_OK) {
+            LOG_ERROR(&quot;Could not prepare statement to fetch blob URLs for object store record (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Failed to look up blobURL records in object store by key range&quot;) };
+        }
+
+        int sqlResult = sql.step();
+        if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
+            // There are no blobURLs in the database for this object store record.
+            return { };
+        }
+
+        while (sqlResult == SQLITE_ROW) {
+            blobURLSet.add(sql.getColumnText(0));
+            sqlResult = sql.step();
+        }
+
+        if (sqlResult != SQLITE_DONE) {
+            LOG_ERROR(&quot;Could not fetch blob URLs for object store record (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Failed to look up blobURL records in object store by key range&quot;) };
+        }
+    }
+
+    ASSERT(!blobURLSet.isEmpty());
+    String databaseDirectory = fullDatabaseDirectory();
+    for (auto&amp; blobURL : blobURLSet) {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT fileName FROM BlobFiles WHERE blobURL = ?&quot;));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindText(1, blobURL) != SQLITE_OK) {
+            LOG_ERROR(&quot;Could not prepare statement to fetch blob filename for object store record (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Failed to look up blobURL records in object store by key range&quot;) };
+        }
+
+        if (sql.step() != SQLITE_ROW) {
+            LOG_ERROR(&quot;Entry for blob filename for blob url %s does not exist (%i) - %s&quot;, blobURL.utf8().data(), m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Failed to look up blobURL records in object store by key range&quot;) };
+        }
+
+        blobURLs.append(blobURL);
+
+        String fileName = sql.getColumnText(0);
+        blobFilePaths.append(pathByAppendingComponent(databaseDirectory, fileName));
+    }
+
+    return { };
+}
+
</ins><span class="cx"> IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData&amp; keyRange, IDBGetResult&amp; resultValue)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;SQLiteIDBBackingStore::getRecord - key range %s, object store %&quot; PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
</span><span class="lines">@@ -1658,11 +1713,13 @@
</span><span class="cx">         return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to serialize upper IDBKey in lookup range&quot;) };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    int64_t recordID = 0;
+    ThreadSafeDataBuffer resultBuffer;
</ins><span class="cx">     {
</span><del>-        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerOpenUpperOpen(&quot;SELECT value FROM Records WHERE objectStoreID = ? AND key &gt; CAST(? AS TEXT) AND key &lt; CAST(? AS TEXT) ORDER BY key;&quot;);
-        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerOpenUpperClosed(&quot;SELECT value FROM Records WHERE objectStoreID = ? AND key &gt; CAST(? AS TEXT) AND key &lt;= CAST(? AS TEXT) ORDER BY key;&quot;);
-        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerClosedUpperOpen(&quot;SELECT value FROM Records WHERE objectStoreID = ? AND key &gt;= CAST(? AS TEXT) AND key &lt; CAST(? AS TEXT) ORDER BY key;&quot;);
-        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerClosedUpperClosed(&quot;SELECT value FROM Records WHERE objectStoreID = ? AND key &gt;= CAST(? AS TEXT) AND key &lt;= CAST(? AS TEXT) ORDER BY key;&quot;);
</del><ins>+        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerOpenUpperOpen(&quot;SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key &gt; CAST(? AS TEXT) AND key &lt; CAST(? AS TEXT) ORDER BY key;&quot;);
+        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerOpenUpperClosed(&quot;SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key &gt; CAST(? AS TEXT) AND key &lt;= CAST(? AS TEXT) ORDER BY key;&quot;);
+        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerClosedUpperOpen(&quot;SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key &gt;= CAST(? AS TEXT) AND key &lt; CAST(? AS TEXT) ORDER BY key;&quot;);
+        static NeverDestroyed&lt;const ASCIILiteral&gt; lowerClosedUpperClosed(&quot;SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key &gt;= CAST(? AS TEXT) AND key &lt;= CAST(? AS TEXT) ORDER BY key;&quot;);
</ins><span class="cx"> 
</span><span class="cx">         const ASCIILiteral* query = nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -1703,9 +1760,20 @@
</span><span class="cx"> 
</span><span class="cx">         Vector&lt;uint8_t&gt; buffer;
</span><span class="cx">         sql.getColumnBlobAsVector(0, buffer);
</span><del>-        resultValue = ThreadSafeDataBuffer::adoptVector(buffer);
</del><ins>+        resultBuffer = ThreadSafeDataBuffer::adoptVector(buffer);
+
+        recordID = sql.getColumnInt64(1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ASSERT(recordID);
+    Vector&lt;String&gt; blobURLs, blobFilePaths;
+    auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
+    ASSERT(blobURLs.size() == blobFilePaths.size());
+
+    if (!error.isNull())
+        return error;
+
+    resultValue = { { resultBuffer, WTFMove(blobURLs), WTFMove(blobFilePaths) } };
</ins><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1739,7 +1807,7 @@
</span><span class="cx">         if (type == IndexedDB::IndexRecordType::Key)
</span><span class="cx">             getResult = { cursor-&gt;currentPrimaryKey() };
</span><span class="cx">         else
</span><del>-            getResult = { SharedBuffer::create(cursor-&gt;currentValueBuffer().data(), cursor-&gt;currentValueBuffer().size()), cursor-&gt;currentPrimaryKey() };
</del><ins>+            getResult = { cursor-&gt;currentValue() ? *cursor-&gt;currentValue() : IDBValue(), cursor-&gt;currentPrimaryKey() };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return { };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -85,6 +85,8 @@
</span><span class="cx"> 
</span><span class="cx">     IDBBackingStoreTemporaryFileHandler&amp; temporaryFileHandler() const { return m_temporaryFileHandler; }
</span><span class="cx"> 
</span><ins>+    IDBError getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector&lt;String&gt;&amp; blobURLs, Vector&lt;String&gt;&amp; blobFilePaths);
+
</ins><span class="cx"> private:
</span><span class="cx">     String filenameForDatabaseName() const;
</span><span class="cx">     String fullDatabasePath() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;IDBGetResult.h&quot;
</span><span class="cx"> #include &quot;IDBSerialization.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><ins>+#include &quot;SQLiteIDBBackingStore.h&quot;
</ins><span class="cx"> #include &quot;SQLiteIDBTransaction.h&quot;
</span><span class="cx"> #include &quot;SQLiteStatement.h&quot;
</span><span class="cx"> #include &quot;SQLiteTransaction.h&quot;
</span><span class="lines">@@ -102,7 +103,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    result = { m_currentKey, m_currentPrimaryKey, ThreadSafeDataBuffer::copyVector(m_currentValueBuffer) };
</del><ins>+    result = { m_currentKey, m_currentPrimaryKey, m_currentValue ? *m_currentValue : IDBValue() };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static String buildIndexStatement(const IDBKeyRangeData&amp; keyRange, IndexedDB::CursorDirection cursorDirection)
</span><span class="lines">@@ -337,6 +338,8 @@
</span><span class="cx">     ASSERT(m_statement);
</span><span class="cx">     ASSERT(!m_completed);
</span><span class="cx"> 
</span><ins>+    m_currentValue = nullptr;
+
</ins><span class="cx">     int result = m_statement-&gt;step();
</span><span class="cx">     if (result == SQLITE_DONE) {
</span><span class="cx">         m_completed = true;
</span><span class="lines">@@ -344,7 +347,7 @@
</span><span class="cx">         // When a cursor reaches its end, that is indicated by having undefined keys/values
</span><span class="cx">         m_currentKey = IDBKeyData();
</span><span class="cx">         m_currentPrimaryKey = IDBKeyData();
</span><del>-        m_currentValueBuffer.clear();
</del><ins>+        m_currentValue = nullptr;
</ins><span class="cx"> 
</span><span class="cx">         return AdvanceResult::Success;
</span><span class="cx">     }
</span><span class="lines">@@ -367,12 +370,25 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_statement-&gt;getColumnBlobAsVector(2, keyData);
</span><del>-    m_currentValueBuffer = keyData;
</del><span class="cx"> 
</span><ins>+    int64_t recordID = m_statement-&gt;getColumnInt64(0);
+    ASSERT(recordID);
+
</ins><span class="cx">     // The primaryKey of an ObjectStore cursor is the same as its key.
</span><del>-    if (m_indexID == IDBIndexInfo::InvalidId)
</del><ins>+    if (m_indexID == IDBIndexInfo::InvalidId) {
</ins><span class="cx">         m_currentPrimaryKey = m_currentKey;
</span><del>-    else {
</del><ins>+
+        Vector&lt;String&gt; blobURLs, blobFilePaths;
+        auto error = m_transaction-&gt;backingStore().getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
+        if (!error.isNull()) {
+            LOG_ERROR(&quot;Unable to fetch blob records from database while advancing cursor&quot;);
+            m_completed = true;
+            m_errored = true;
+            return AdvanceResult::Failure;
+        }
+
+        m_currentValue = std::make_unique&lt;IDBValue&gt;(ThreadSafeDataBuffer::adoptVector(keyData), blobURLs, blobFilePaths);
+    } else {
</ins><span class="cx">         if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentPrimaryKey)) {
</span><span class="cx">             LOG_ERROR(&quot;Unable to deserialize value data from database while advancing index cursor&quot;);
</span><span class="cx">             m_completed = true;
</span><span class="lines">@@ -383,7 +399,7 @@
</span><span class="cx">         SQLiteStatement objectStoreStatement(m_statement-&gt;database(), &quot;SELECT value FROM Records WHERE key = CAST(? AS TEXT) and objectStoreID = ?;&quot;);
</span><span class="cx"> 
</span><span class="cx">         if (objectStoreStatement.prepare() != SQLITE_OK
</span><del>-            || objectStoreStatement.bindBlob(1, m_currentValueBuffer.data(), m_currentValueBuffer.size()) != SQLITE_OK
</del><ins>+            || objectStoreStatement.bindBlob(1, keyData.data(), keyData.size()) != SQLITE_OK
</ins><span class="cx">             || objectStoreStatement.bindInt64(2, m_objectStoreID) != SQLITE_OK) {
</span><span class="cx">             LOG_ERROR(&quot;Could not create index cursor statement into object store records (%i) '%s'&quot;, m_statement-&gt;database().lastError(), m_statement-&gt;database().lastErrorMsg());
</span><span class="cx">             m_completed = true;
</span><span class="lines">@@ -393,9 +409,10 @@
</span><span class="cx"> 
</span><span class="cx">         int result = objectStoreStatement.step();
</span><span class="cx"> 
</span><del>-        if (result == SQLITE_ROW)
-            objectStoreStatement.getColumnBlobAsVector(0, m_currentValueBuffer);
-        else if (result == SQLITE_DONE) {
</del><ins>+        if (result == SQLITE_ROW) {
+            objectStoreStatement.getColumnBlobAsVector(0, keyData);
+            m_currentValue = std::make_unique&lt;IDBValue&gt;(ThreadSafeDataBuffer::adoptVector(keyData));
+        } else if (result == SQLITE_DONE) {
</ins><span class="cx">             // This indicates that the record we're trying to retrieve has been removed from the object store.
</span><span class="cx">             // Skip over it.
</span><span class="cx">             return AdvanceResult::ShouldAdvanceAgain;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;IDBKeyData.h&quot;
</span><span class="cx"> #include &quot;IDBKeyRangeData.h&quot;
</span><span class="cx"> #include &quot;IDBResourceIdentifier.h&quot;
</span><ins>+#include &quot;IDBValue.h&quot;
</ins><span class="cx"> #include &quot;SQLiteStatement.h&quot;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -61,7 +62,7 @@
</span><span class="cx"> 
</span><span class="cx">     const IDBKeyData&amp; currentKey() const { return m_currentKey; }
</span><span class="cx">     const IDBKeyData&amp; currentPrimaryKey() const { return m_currentPrimaryKey; }
</span><del>-    const Vector&lt;uint8_t&gt;&amp; currentValueBuffer() const { return m_currentValueBuffer; }
</del><ins>+    IDBValue* currentValue() const { return m_currentValue.get(); }
</ins><span class="cx"> 
</span><span class="cx">     bool advance(uint64_t count);
</span><span class="cx">     bool iterate(const IDBKeyData&amp; targetKey);
</span><span class="lines">@@ -102,7 +103,7 @@
</span><span class="cx"> 
</span><span class="cx">     IDBKeyData m_currentKey;
</span><span class="cx">     IDBKeyData m_currentPrimaryKey;
</span><del>-    Vector&lt;uint8_t&gt; m_currentValueBuffer;
</del><ins>+    std::unique_ptr&lt;IDBValue&gt; m_currentValue;
</ins><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;SQLiteStatement&gt; m_statement;
</span><span class="cx">     bool m_statementNeedsReset { false };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBTransactionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx">     bool inProgress() const;
</span><span class="cx"> 
</span><span class="cx">     SQLiteTransaction* sqliteTransaction() const { return m_sqliteTransaction.get(); }
</span><ins>+    SQLiteIDBBackingStore&amp; backingStore() { return m_backingStore; }
</ins><span class="cx"> 
</span><span class="cx">     void addBlobFile(const String&amp; temporaryPath, const String&amp; storedFilename);
</span><span class="cx">     void addRemovedBlobFile(const String&amp; removedFilename);
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebsocketsWorkerThreadableWebSocketChannelcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -500,7 +500,7 @@
</span><span class="cx">         ASSERT_UNUSED(context, context.isDocument());
</span><span class="cx">         ASSERT(peer);
</span><span class="cx"> 
</span><del>-        peer-&gt;send(Blob::deserialize(capturedURL.url(), capturedType.string(), size));
</del><ins>+        peer-&gt;send(Blob::deserialize(capturedURL.url(), capturedType.string(), size, { }));
</ins><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;Bridge&gt; protect(*this);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;IDBKey.h&quot;
</span><span class="cx"> #include &quot;IDBKeyData.h&quot;
</span><span class="cx"> #include &quot;IDBKeyPath.h&quot;
</span><ins>+#include &quot;IDBValue.h&quot;
</ins><span class="cx"> #include &quot;IndexKey.h&quot;
</span><span class="cx"> #include &quot;JSDOMBinding.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="lines">@@ -428,19 +429,8 @@
</span><span class="cx">     return Deprecated::ScriptValue(exec-&gt;vm(), result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&amp; context, const ThreadSafeDataBuffer&amp; valueData)
</del><ins>+static JSC::JSValue deserializeIDBValueDataToJSValue(JSC::ExecState&amp; exec, const ThreadSafeDataBuffer&amp; valueData, const Vector&lt;String&gt; blobURLs, const Vector&lt;String&gt; blobFilePaths)
</ins><span class="cx"> {
</span><del>-    DOMRequestState state(&amp;context);
-    auto* execState = state.exec();
-
-    if (!execState)
-        return Deprecated::ScriptValue();
-
-    return Deprecated::ScriptValue(execState-&gt;vm(), deserializeIDBValueDataToJSValue(*execState, valueData));
-}
-
-JSC::JSValue deserializeIDBValueDataToJSValue(JSC::ExecState&amp; exec, const ThreadSafeDataBuffer&amp; valueData)
-{
</del><span class="cx">     if (!valueData.data())
</span><span class="cx">         return jsUndefined();
</span><span class="cx"> 
</span><span class="lines">@@ -450,7 +440,7 @@
</span><span class="cx">         RefPtr&lt;SerializedScriptValue&gt; serializedValue = SerializedScriptValue::createFromWireBytes(Vector&lt;uint8_t&gt;(data));
</span><span class="cx"> 
</span><span class="cx">         exec.vm().apiLock().lock();
</span><del>-        result = serializedValue-&gt;deserialize(&amp;exec, exec.lexicalGlobalObject(), 0, NonThrowing);
</del><ins>+        result = serializedValue-&gt;deserialize(&amp;exec, exec.lexicalGlobalObject(), 0, NonThrowing, blobURLs, blobFilePaths);
</ins><span class="cx">         exec.vm().apiLock().unlock();
</span><span class="cx">     } else
</span><span class="cx">         result = jsNull();
</span><span class="lines">@@ -458,6 +448,34 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&amp; context, const ThreadSafeDataBuffer&amp; valueData)
+{
+    DOMRequestState state(&amp;context);
+    auto* execState = state.exec();
+
+    if (!execState)
+        return { };
+
+    return { execState-&gt;vm(), deserializeIDBValueDataToJSValue(*execState, valueData) };
+}
+
+Deprecated::ScriptValue deserializeIDBValue(ScriptExecutionContext&amp; context, const IDBValue&amp; value)
+{
+    DOMRequestState state(&amp;context);
+    auto* execState = state.exec();
+
+    if (!execState)
+        return { };
+
+    return { execState-&gt;vm(), deserializeIDBValueDataToJSValue(*execState, value.data(), value.blobURLs(), value.blobFilePaths()) };
+}
+
+JSC::JSValue deserializeIDBValueDataToJSValue(JSC::ExecState&amp; exec, const ThreadSafeDataBuffer&amp; valueData)
+{
+    Vector&lt;String&gt; dummyURLs, dummyFilePaths;
+    return deserializeIDBValueDataToJSValue(exec, valueData, dummyURLs, dummyFilePaths);
+}
+
</ins><span class="cx"> Deprecated::ScriptValue deserializeIDBValueBuffer(DOMRequestState* requestState, PassRefPtr&lt;SharedBuffer&gt; prpBuffer, bool keyIsDefined)
</span><span class="cx"> {
</span><span class="cx">     if (prpBuffer) {
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> class IDBKey;
</span><span class="cx"> class IDBKeyData;
</span><span class="cx"> class IDBKeyPath;
</span><ins>+class IDBValue;
</ins><span class="cx"> class IndexKey;
</span><span class="cx"> class SharedBuffer;
</span><span class="cx"> class ThreadSafeDataBuffer;
</span><span class="lines">@@ -57,6 +58,7 @@
</span><span class="cx"> 
</span><span class="cx"> Deprecated::ScriptValue deserializeIDBValue(DOMRequestState*, PassRefPtr&lt;SerializedScriptValue&gt;);
</span><span class="cx"> Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&amp;, const ThreadSafeDataBuffer&amp; valueData);
</span><ins>+Deprecated::ScriptValue deserializeIDBValue(ScriptExecutionContext&amp;, const IDBValue&amp;);
</ins><span class="cx"> Deprecated::ScriptValue deserializeIDBValueBuffer(DOMRequestState*, PassRefPtr&lt;SharedBuffer&gt;, bool keyIsDefined);
</span><span class="cx"> WEBCORE_EXPORT Deprecated::ScriptValue deserializeIDBValueBuffer(JSC::ExecState*, Vector&lt;uint8_t&gt;&amp;&amp;, bool keyIsDefined);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsSerializedScriptValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -1482,13 +1482,11 @@
</span><span class="cx">         return str;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject,
-                                             MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray,
-                                             const Vector&lt;uint8_t&gt;&amp; buffer)
</del><ins>+    static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray, const Vector&lt;uint8_t&gt;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt; blobFilePaths)
</ins><span class="cx">     {
</span><span class="cx">         if (!buffer.size())
</span><span class="cx">             return std::make_pair(jsNull(), UnspecifiedError);
</span><del>-        CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer);
</del><ins>+        CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer, blobURLs, blobFilePaths);
</ins><span class="cx">         if (!deserializer.isValid())
</span><span class="cx">             return std::make_pair(JSValue(), ValidationError);
</span><span class="cx">         return deserializer.deserialize();
</span><span class="lines">@@ -1533,9 +1531,7 @@
</span><span class="cx">         size_t m_index;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, 
-                      MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents,
-                      const Vector&lt;uint8_t&gt;&amp; buffer)
</del><ins>+    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector&lt;uint8_t&gt;&amp; buffer)
</ins><span class="cx">         : CloneBase(exec)
</span><span class="cx">         , m_globalObject(globalObject)
</span><span class="cx">         , m_isDOMGlobalObject(globalObject-&gt;inherits(JSDOMGlobalObject::info()))
</span><span class="lines">@@ -1550,6 +1546,23 @@
</span><span class="cx">             m_version = 0xFFFFFFFF;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector&lt;uint8_t&gt;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt; blobFilePaths)
+        : CloneBase(exec)
+        , m_globalObject(globalObject)
+        , m_isDOMGlobalObject(globalObject-&gt;inherits(JSDOMGlobalObject::info()))
+        , m_ptr(buffer.data())
+        , m_end(buffer.data() + buffer.size())
+        , m_version(0xFFFFFFFF)
+        , m_messagePorts(messagePorts)
+        , m_arrayBufferContents(arrayBufferContents)
+        , m_arrayBuffers(arrayBufferContents ? arrayBufferContents-&gt;size() : 0)
+        , m_blobURLs(blobURLs)
+        , m_blobFilePaths(blobFilePaths)
+    {
+        if (!read(m_version))
+            m_version = 0xFFFFFFFF;
+    }
+
</ins><span class="cx">     DeserializationResult deserialize();
</span><span class="cx"> 
</span><span class="cx">     void throwValidationError()
</span><span class="lines">@@ -1773,8 +1786,14 @@
</span><span class="cx">         CachedStringRef name;
</span><span class="cx">         if (!readStringData(name))
</span><span class="cx">             return 0;
</span><ins>+
+        // If the blob URL for this file has an associated blob file path, prefer that one over the &quot;built-in&quot; path.
+        String filePath = blobFilePathForBlobURL(url-&gt;string());
+        if (filePath.isEmpty())
+            filePath = path-&gt;string();
+
</ins><span class="cx">         if (m_isDOMGlobalObject)
</span><del>-            file = File::deserialize(path-&gt;string(), URL(URL(), url-&gt;string()), type-&gt;string(), name-&gt;string());
</del><ins>+            file = File::deserialize(filePath, URL(URL(), url-&gt;string()), type-&gt;string(), name-&gt;string());
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -2273,7 +2292,7 @@
</span><span class="cx">                 return JSValue();
</span><span class="cx">             if (!m_isDOMGlobalObject)
</span><span class="cx">                 return jsNull();
</span><del>-            return getJSValue(Blob::deserialize(URL(URL(), url-&gt;string()), type-&gt;string(), size).get());
</del><ins>+            return getJSValue(Blob::deserialize(URL(URL(), url-&gt;string()), type-&gt;string(), size, blobFilePathForBlobURL(url-&gt;string())).get());
</ins><span class="cx">         }
</span><span class="cx">         case StringTag: {
</span><span class="cx">             CachedStringRef cachedString;
</span><span class="lines">@@ -2405,6 +2424,19 @@
</span><span class="cx">     MessagePortArray* m_messagePorts;
</span><span class="cx">     ArrayBufferContentsArray* m_arrayBufferContents;
</span><span class="cx">     ArrayBufferArray m_arrayBuffers;
</span><ins>+    Vector&lt;String&gt; m_blobURLs;
+    Vector&lt;String&gt; m_blobFilePaths;
+
+    String blobFilePathForBlobURL(const String&amp; blobURL)
+    {
+        size_t i = 0;
+        for (; i &lt; m_blobURLs.size(); ++i) {
+            if (m_blobURLs[i] == blobURL)
+                break;
+        }
+
+        return i &lt; m_blobURLs.size() ? m_blobFilePaths[i] : String();
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> DeserializationResult CloneDeserializer::deserialize()
</span><span class="lines">@@ -2683,11 +2715,15 @@
</span><span class="cx">     return CloneDeserializer::deserializeString(m_data);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject,
-                                           MessagePortArray* messagePorts, SerializationErrorMode throwExceptions)
</del><ins>+JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, SerializationErrorMode throwExceptions)
</ins><span class="cx"> {
</span><del>-    DeserializationResult result = CloneDeserializer::deserialize(exec, globalObject, messagePorts,
-                                                                  m_arrayBufferContentsArray.get(), m_data);
</del><ins>+    Vector&lt;String&gt; dummyBlobs, dummyPaths;
+    return deserialize(exec, globalObject, messagePorts, throwExceptions, dummyBlobs, dummyPaths);
+}
+
+JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, SerializationErrorMode throwExceptions, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths)
+{
+    DeserializationResult result = CloneDeserializer::deserialize(exec, globalObject, messagePorts, m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths);
</ins><span class="cx">     if (throwExceptions == Throwing)
</span><span class="cx">         maybeThrowExceptionIfSerializationFailed(exec, result.second);
</span><span class="cx">     return result.first ? result.first : jsNull();
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsSerializedScriptValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     static Ref&lt;SerializedScriptValue&gt; nullValue();
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, MessagePortArray*, SerializationErrorMode = Throwing);
</span><ins>+    JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, MessagePortArray*, SerializationErrorMode, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths);
</ins><span class="cx"> 
</span><span class="cx">     static uint32_t wireFormatVersion();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorefileapiBlobcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/fileapi/Blob.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/fileapi/Blob.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/fileapi/Blob.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -95,12 +95,15 @@
</span><span class="cx">     ThreadableBlobRegistry::registerBlobURL(m_internalURL, WTFMove(blobParts), contentType);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Blob::Blob(DeserializationContructor, const URL&amp; srcURL, const String&amp; type, long long size)
</del><ins>+Blob::Blob(DeserializationContructor, const URL&amp; srcURL, const String&amp; type, long long size, const String&amp; fileBackedPath)
</ins><span class="cx">     : m_type(normalizedContentType(type))
</span><span class="cx">     , m_size(size)
</span><span class="cx"> {
</span><span class="cx">     m_internalURL = BlobURL::createInternalURL();
</span><del>-    ThreadableBlobRegistry::registerBlobURL(nullptr, m_internalURL, srcURL);
</del><ins>+    if (fileBackedPath.isEmpty())
+        ThreadableBlobRegistry::registerBlobURL(nullptr, m_internalURL, srcURL);
+    else
+        ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(m_internalURL, srcURL, fileBackedPath);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Blob::Blob(const URL&amp; srcURL, long long start, long long end, const String&amp; type)
</span></span></pre></div>
<a id="trunkSourceWebCorefileapiBlobh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/fileapi/Blob.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/fileapi/Blob.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/fileapi/Blob.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -58,10 +58,10 @@
</span><span class="cx">         return adoptRef(*new Blob(WTFMove(blobParts), contentType));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static Ref&lt;Blob&gt; deserialize(const URL&amp; srcURL, const String&amp; type, long long size)
</del><ins>+    static Ref&lt;Blob&gt; deserialize(const URL&amp; srcURL, const String&amp; type, long long size, const String&amp; fileBackedPath)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(Blob::isNormalizedContentType(type));
</span><del>-        return adoptRef(*new Blob(deserializationContructor, srcURL, type, size));
</del><ins>+        return adoptRef(*new Blob(deserializationContructor, srcURL, type, size, fileBackedPath));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     virtual ~Blob();
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">     Blob(UninitializedContructor);
</span><span class="cx"> 
</span><span class="cx">     enum DeserializationContructor { deserializationContructor };
</span><del>-    Blob(DeserializationContructor, const URL&amp; srcURL, const String&amp; type, long long size);
</del><ins>+    Blob(DeserializationContructor, const URL&amp; srcURL, const String&amp; type, long long size, const String&amp; fileBackedPath);
</ins><span class="cx"> 
</span><span class="cx">     // For slicing.
</span><span class="cx">     Blob(const URL&amp; srcURL, long long start, long long end, const String&amp; contentType);
</span></span></pre></div>
<a id="trunkSourceWebCorefileapiFilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/fileapi/File.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/fileapi/File.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/fileapi/File.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> File::File(DeserializationContructor, const String&amp; path, const URL&amp; url, const String&amp; type, const String&amp; name)
</span><del>-    : Blob(deserializationContructor, url, type, -1)
</del><ins>+    : Blob(deserializationContructor, url, type, -1, path)
</ins><span class="cx">     , m_path(path)
</span><span class="cx">     , m_name(name)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorefileapiThreadableBlobRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -35,10 +35,12 @@
</span><span class="cx"> #include &quot;BlobPart.h&quot;
</span><span class="cx"> #include &quot;BlobRegistry.h&quot;
</span><span class="cx"> #include &quot;BlobURL.h&quot;
</span><ins>+#include &quot;CrossThreadTask.h&quot;
</ins><span class="cx"> #include &quot;SecurityOrigin.h&quot;
</span><span class="cx"> #include &lt;mutex&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><ins>+#include &lt;wtf/MessageQueue.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSpecific.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringHash.h&gt;
</span><span class="lines">@@ -98,6 +100,17 @@
</span><span class="cx">     return *map;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static MessageQueue&lt;CrossThreadTask&gt;&amp; threadableQueue()
+{
+    static std::once_flag onceFlag;
+    static MessageQueue&lt;CrossThreadTask&gt;* queue;
+    std::call_once(onceFlag, [] {
+        queue = new MessageQueue&lt;CrossThreadTask&gt;;
+    });
+
+    return *queue;
+}
+
</ins><span class="cx"> void ThreadableBlobRegistry::registerFileBlobURL(const URL&amp; url, const String&amp; path, const String&amp; contentType)
</span><span class="cx"> {
</span><span class="cx">     if (isMainThread())
</span><span class="lines">@@ -144,6 +157,21 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(const URL&amp; url, const URL&amp; srcURL, const String&amp; fileBackedPath)
+{
+    if (isMainThread())
+        blobRegistry().registerBlobURLOptionallyFileBacked(url, srcURL, fileBackedPath);
+    else {
+        threadableQueue().append(createCrossThreadTask(ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked, url, srcURL, fileBackedPath));
+
+        callOnMainThread([] {
+            auto task = threadableQueue().tryGetMessage();
+            ASSERT(task);
+            task-&gt;performTask();
+        });
+    }
+}
+
</ins><span class="cx"> void ThreadableBlobRegistry::registerBlobURLForSlice(const URL&amp; newURL, const URL&amp; srcURL, long long start, long long end)
</span><span class="cx"> {
</span><span class="cx">     if (isMainThread())
</span></span></pre></div>
<a id="trunkSourceWebCorefileapiThreadableBlobRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx">     static void registerFileBlobURL(const URL&amp;, const String&amp; path, const String&amp; contentType);
</span><span class="cx">     static void registerBlobURL(const URL&amp;, Vector&lt;BlobPart&gt; blobParts, const String&amp; contentType);
</span><span class="cx">     static void registerBlobURL(SecurityOrigin*, const URL&amp;, const URL&amp; srcURL);
</span><ins>+    static void registerBlobURLOptionallyFileBacked(const URL&amp;, const URL&amp; srcURL, const String&amp; fileBackedPath);
</ins><span class="cx">     static void registerBlobURLForSlice(const URL&amp; newURL, const URL&amp; srcURL, long long start, long long end);
</span><span class="cx">     static void unregisterBlobURL(const URL&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformCrossThreadTaskh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/CrossThreadTask.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/CrossThreadTask.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/platform/CrossThreadTask.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -62,6 +62,17 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template &lt;typename... Arguments&gt;
+class CrossThreadTaskStaticImpl final : public CrossThreadTask {
+public:
+    CrossThreadTaskStaticImpl(void (*method)(Arguments...), Arguments&amp;&amp;... arguments)
+    {
+        m_taskFunction = [method, arguments...] {
+            method(arguments...);
+        };
+    }
+};
+
</ins><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> std::unique_ptr&lt;CrossThreadTask&gt; createCrossThreadTask(
</span><span class="cx">     T&amp; callee,
</span><span class="lines">@@ -113,6 +124,20 @@
</span><span class="cx">         WebCore::CrossThreadCopier&lt;P3&gt;::copy(parameter3));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3&gt;
+std::unique_ptr&lt;CrossThreadTask&gt; createCrossThreadTask(
+    void (*method)(MP1, MP2, MP3),
+    const P1&amp; parameter1,
+    const P2&amp; parameter2,
+    const P3&amp; parameter3)
+{
+    return std::make_unique&lt;CrossThreadTaskStaticImpl&lt;MP1, MP2, MP3&gt;&gt;(
+        method,
+        WebCore::CrossThreadCopier&lt;P1&gt;::copy(parameter1),
+        WebCore::CrossThreadCopier&lt;P2&gt;::copy(parameter2),
+        WebCore::CrossThreadCopier&lt;P3&gt;::copy(parameter3));
+}
+
</ins><span class="cx"> template&lt;typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4&gt;
</span><span class="cx"> std::unique_ptr&lt;CrossThreadTask&gt; createCrossThreadTask(
</span><span class="cx">     T&amp; callee,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkBlobRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/BlobRegistry.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/BlobRegistry.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/platform/network/BlobRegistry.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -57,6 +57,9 @@
</span><span class="cx">     // Registers a new blob URL referring to the blob data identified by the specified srcURL.
</span><span class="cx">     virtual void registerBlobURL(const URL&amp;, const URL&amp; srcURL) = 0;
</span><span class="cx"> 
</span><ins>+    // Registers a new blob URL referring to the blob data identified by the specified srcURL or, if none found, referring to the file found at the given path.
+    virtual void registerBlobURLOptionallyFileBacked(const URL&amp;, const URL&amp; srcURL, const String&amp; fileBackedPath) = 0;
+
</ins><span class="cx">     // Negative start and end values select from the end.
</span><span class="cx">     virtual void registerBlobURLForSlice(const URL&amp;, const URL&amp; srcURL, long long start, long long end) = 0;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkBlobRegistryImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -160,13 +160,26 @@
</span><span class="cx"> 
</span><span class="cx"> void BlobRegistryImpl::registerBlobURL(const URL&amp; url, const URL&amp; srcURL)
</span><span class="cx"> {
</span><ins>+    registerBlobURLOptionallyFileBacked(url, srcURL, { });
+}
+
+void BlobRegistryImpl::registerBlobURLOptionallyFileBacked(const URL&amp; url, const URL&amp; srcURL, const String&amp; fileBackedPath)
+{
</ins><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><span class="cx">     BlobData* src = getBlobDataFromURL(srcURL);
</span><del>-    if (!src)
</del><ins>+    if (src) {
+        m_blobs.set(url.string(), src);
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><del>-    m_blobs.set(url.string(), src);
</del><ins>+    if (fileBackedPath.isEmpty())
+        return;
+
+    RefPtr&lt;BlobData&gt; backingFile = BlobData::create({ });
+    backingFile-&gt;appendFile(BlobDataFileReference::create(fileBackedPath));
+
+    m_blobs.set(url.string(), backingFile.release());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BlobRegistryImpl::registerBlobURLForSlice(const URL&amp; url, const URL&amp; srcURL, long long start, long long end)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkBlobRegistryImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx">     void registerFileBlobURL(const URL&amp;, RefPtr&lt;BlobDataFileReference&gt;&amp;&amp;, const String&amp; contentType) override;
</span><span class="cx">     void registerBlobURL(const URL&amp;, Vector&lt;BlobPart&gt;, const String&amp; contentType) override;
</span><span class="cx">     void registerBlobURL(const URL&amp;, const URL&amp; srcURL) override;
</span><ins>+    void registerBlobURLOptionallyFileBacked(const URL&amp;, const URL&amp; srcURL, const String&amp; fileBackedPath) override;
</ins><span class="cx">     void registerBlobURLForSlice(const URL&amp;, const URL&amp; srcURL, long long start, long long end) override;
</span><span class="cx">     void unregisterBlobURL(const URL&amp;) override;
</span><span class="cx">     bool isBlobRegistryImpl() const override { return true; }
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/ChangeLog        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-04-13  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB (Blob support): Support retrieving Blobs from IDB.
+        https://bugs.webkit.org/show_bug.cgi?id=156367
+
+        Reviewed by Alex Christensen.
+
+        * NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
+        (WebKit::NetworkBlobRegistry::registerBlobURLOptionallyFileBacked):
+        * NetworkProcess/FileAPI/NetworkBlobRegistry.h:
+        
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::registerBlobURLOptionallyFileBacked):
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
+        
+        * WebProcess/FileAPI/BlobRegistryProxy.cpp:
+        (WebKit::BlobRegistryProxy::registerBlobURLOptionallyFileBacked):
+        * WebProcess/FileAPI/BlobRegistryProxy.h:
+
</ins><span class="cx"> 2016-04-13  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         We should not speculatively revalidate cached redirects
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessFileAPINetworkBlobRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -83,6 +83,17 @@
</span><span class="cx">     mapIterator-&gt;value.add(url);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetworkBlobRegistry::registerBlobURLOptionallyFileBacked(NetworkConnectionToWebProcess* connection, const URL&amp; url, const URL&amp; srcURL, const String&amp; fileBackedPath)
+{
+    blobRegistry().registerBlobURLOptionallyFileBacked(url, srcURL, fileBackedPath);
+
+    ASSERT(!m_blobsForConnection.get(connection).contains(url));
+    BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
+    if (mapIterator == m_blobsForConnection.end())
+        mapIterator = m_blobsForConnection.add(connection, HashSet&lt;URL&gt;()).iterator;
+    mapIterator-&gt;value.add(url);
+}
+
</ins><span class="cx"> void NetworkBlobRegistry::registerBlobURLForSlice(NetworkConnectionToWebProcess* connection, const WebCore::URL&amp; url, const WebCore::URL&amp; srcURL, int64_t start, int64_t end)
</span><span class="cx"> {
</span><span class="cx">     // The connection may not be registered if NetworkProcess prevously crashed for any reason.
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessFileAPINetworkBlobRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">     void registerFileBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&amp;, const String&amp; path, RefPtr&lt;SandboxExtension&gt;&amp;&amp;, const String&amp; contentType);
</span><span class="cx">     void registerBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&amp;, Vector&lt;WebCore::BlobPart&gt;, const String&amp; contentType);
</span><span class="cx">     void registerBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&amp;, const WebCore::URL&amp; srcURL);
</span><ins>+    void registerBlobURLOptionallyFileBacked(NetworkConnectionToWebProcess*, const WebCore::URL&amp;, const WebCore::URL&amp; srcURL, const String&amp; fileBackedPath);
</ins><span class="cx">     void registerBlobURLForSlice(NetworkConnectionToWebProcess*, const WebCore::URL&amp;, const WebCore::URL&amp; srcURL, int64_t start, int64_t end);
</span><span class="cx">     void unregisterBlobURL(NetworkConnectionToWebProcess*, const WebCore::URL&amp;);
</span><span class="cx">     uint64_t blobSize(NetworkConnectionToWebProcess*, const WebCore::URL&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkConnectionToWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -271,6 +271,11 @@
</span><span class="cx">     NetworkBlobRegistry::singleton().registerBlobURL(this, url, srcURL);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetworkConnectionToWebProcess::registerBlobURLOptionallyFileBacked(const URL&amp; url, const URL&amp; srcURL, const String&amp; fileBackedPath)
+{
+    NetworkBlobRegistry::singleton().registerBlobURLOptionallyFileBacked(this, url, srcURL, fileBackedPath);
+}
+
</ins><span class="cx"> void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL&amp; url, const URL&amp; srcURL, int64_t start, int64_t end)
</span><span class="cx"> {
</span><span class="cx">     NetworkBlobRegistry::singleton().registerBlobURLForSlice(this, url, srcURL, start, end);
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkConnectionToWebProcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -91,6 +91,7 @@
</span><span class="cx">     void registerFileBlobURL(const WebCore::URL&amp;, const String&amp; path, const SandboxExtension::Handle&amp;, const String&amp; contentType);
</span><span class="cx">     void registerBlobURL(const WebCore::URL&amp;, Vector&lt;WebCore::BlobPart&gt;, const String&amp; contentType);
</span><span class="cx">     void registerBlobURLFromURL(const WebCore::URL&amp;, const WebCore::URL&amp; srcURL);
</span><ins>+    void registerBlobURLOptionallyFileBacked(const WebCore::URL&amp;, const WebCore::URL&amp; srcURL, const String&amp; fileBackedPath);
</ins><span class="cx">     void registerBlobURLForSlice(const WebCore::URL&amp;, const WebCore::URL&amp; srcURL, int64_t start, int64_t end);
</span><span class="cx">     void blobSize(const WebCore::URL&amp;, uint64_t&amp; resultSize);
</span><span class="cx">     void unregisterBlobURL(const WebCore::URL&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkConnectionToWebProcessmessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     RegisterFileBlobURL(WebCore::URL url, String path, WebKit::SandboxExtension::Handle extensionHandle, String contentType)
</span><span class="cx">     RegisterBlobURL(WebCore::URL url, Vector&lt;WebCore::BlobPart&gt; blobParts, String contentType)
</span><span class="cx">     RegisterBlobURLFromURL(WebCore::URL url, WebCore::URL srcURL)
</span><ins>+    RegisterBlobURLOptionallyFileBacked(WebCore::URL url, WebCore::URL srcURL, String fileBackedPath)
</ins><span class="cx">     RegisterBlobURLForSlice(WebCore::URL url, WebCore::URL srcURL, int64_t start, int64_t end)
</span><span class="cx">     UnregisterBlobURL(WebCore::URL url)
</span><span class="cx">     BlobSize(WebCore::URL url) -&gt; (uint64_t resultSize)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessFileAPIBlobRegistryProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.cpp        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -57,6 +57,11 @@
</span><span class="cx">     WebProcess::singleton().networkConnection()-&gt;connection()-&gt;send(Messages::NetworkConnectionToWebProcess::RegisterBlobURLFromURL(url, srcURL), 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BlobRegistryProxy::registerBlobURLOptionallyFileBacked(const URL&amp; url, const URL&amp; srcURL, const String&amp; fileBackedPath)
+{
+    WebProcess::singleton().networkConnection()-&gt;connection()-&gt;send(Messages::NetworkConnectionToWebProcess::RegisterBlobURLOptionallyFileBacked(url, srcURL, fileBackedPath), 0);
+}
+
</ins><span class="cx"> void BlobRegistryProxy::unregisterBlobURL(const URL&amp; url)
</span><span class="cx"> {
</span><span class="cx">     WebProcess::singleton().networkConnection()-&gt;connection()-&gt;send(Messages::NetworkConnectionToWebProcess::UnregisterBlobURL(url), 0);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessFileAPIBlobRegistryProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h (199523 => 199524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h        2016-04-14 00:47:40 UTC (rev 199523)
+++ trunk/Source/WebKit2/WebProcess/FileAPI/BlobRegistryProxy.h        2016-04-14 00:54:10 UTC (rev 199524)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx">     void registerFileBlobURL(const WebCore::URL&amp;, RefPtr&lt;WebCore::BlobDataFileReference&gt;&amp;&amp;, const String&amp; contentType) override;
</span><span class="cx">     void registerBlobURL(const WebCore::URL&amp;, Vector&lt;WebCore::BlobPart&gt;, const String&amp; contentType) override;
</span><span class="cx">     void registerBlobURL(const WebCore::URL&amp;, const WebCore::URL&amp; srcURL) override;
</span><ins>+    void registerBlobURLOptionallyFileBacked(const WebCore::URL&amp;, const WebCore::URL&amp; srcURL, const String&amp; fileBackedPath) override;
</ins><span class="cx">     void unregisterBlobURL(const WebCore::URL&amp;) override;
</span><span class="cx">     void registerBlobURLForSlice(const WebCore::URL&amp;, const WebCore::URL&amp; srcURL, long long start, long long end) override;
</span><span class="cx">     unsigned long long blobSize(const WebCore::URL&amp;) override;
</span></span></pre>
</div>
</div>

</body>
</html>