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