Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Unified Diff: Source/bindings/v8/SerializedScriptValue.cpp

Issue 223123002: Add blob serialization support [currently unused] to SerializedScriptValue. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebaseline crypto tests Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/v8/SerializedScriptValue.h ('k') | Source/core/fileapi/File.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/v8/SerializedScriptValue.cpp
diff --git a/Source/bindings/v8/SerializedScriptValue.cpp b/Source/bindings/v8/SerializedScriptValue.cpp
index 7de88cbe5d9bb862f7bb978d6dbc55729868a72b..7ba4d063bdfb5e93dbe21c6c30027b27f57fe2d4 100644
--- a/Source/bindings/v8/SerializedScriptValue.cpp
+++ b/Source/bindings/v8/SerializedScriptValue.cpp
@@ -65,6 +65,7 @@
#include "heap/Handle.h"
#include "platform/SharedBuffer.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebBlobInfo.h"
#include "public/platform/WebCrypto.h"
#include "public/platform/WebCryptoKey.h"
#include "public/platform/WebCryptoKeyAlgorithm.h"
@@ -199,10 +200,13 @@ enum SerializationTag {
DateTag = 'D', // value:double -> Date (ref)
MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with transferred MessagePort.
NumberTag = 'N', // value:double -> Number
- BlobTag = 'b', // url:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref)
+ BlobTag = 'b', // uuid:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref)
+ BlobIndexTag = 'i', // index:int32_t -> Blob (ref)
FileTag = 'f', // file:RawFile -> File (ref)
- DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, url:WebCoreString -> FileSystem (ref)
+ FileIndexTag = 'e', // index:int32_t -> File (ref)
+ DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, uuid:WebCoreString -> FileSystem (ref)
FileListTag = 'l', // length:uint32_t, files:RawFile[length] -> FileList (ref)
+ FileListIndexTag = 'L', // length:uint32_t, files:int32_t[length] -> FileList (ref)
ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint32_t, data:byte[pixelDataLength] -> ImageData (ref)
ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the open stack;
// fills it with the last numProperties name,value pairs pushed onto the deserialization stack
@@ -458,6 +462,13 @@ public:
doWriteUint64(size);
}
+ void writeBlobIndex(int blobIndex)
+ {
+ ASSERT(blobIndex >= 0);
+ append(BlobIndexTag);
+ doWriteUint32(blobIndex);
+ }
+
void writeDOMFileSystem(int type, const String& name, const String& url)
{
append(DOMFileSystemTag);
@@ -472,6 +483,12 @@ public:
doWriteFile(file);
}
+ void writeFileIndex(int blobIndex)
+ {
+ append(FileIndexTag);
+ doWriteUint32(blobIndex);
+ }
+
void writeFileList(const FileList& fileList)
{
append(FileListTag);
@@ -481,6 +498,15 @@ public:
doWriteFile(*fileList.item(i));
}
+ void writeFileListIndex(const Vector<int>& blobIndices)
+ {
+ append(FileListIndexTag);
+ uint32_t length = blobIndices.size();
+ doWriteUint32(length);
+ for (unsigned i = 0; i < length; ++i)
+ doWriteUint32(blobIndices[i]);
+ }
+
bool writeCryptoKey(const blink::WebCryptoKey& key)
{
append(static_cast<uint8_t>(CryptoKeyTag));
@@ -910,12 +936,13 @@ public:
JSException
};
- Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::Isolate* isolate)
+ Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::Isolate* isolate)
: m_writer(writer)
, m_tryCatch(tryCatch)
, m_depth(0)
, m_status(Success)
, m_nextObjectReference(0)
+ , m_blobInfo(blobInfo)
, m_blobDataHandles(blobDataHandles)
, m_isolate(isolate)
{
@@ -1259,8 +1286,12 @@ private:
return 0;
if (blob->hasBeenClosed())
return handleError(DataCloneError, "A Blob object has been closed, and could therefore not be cloned.", next);
- m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
+ int blobIndex = -1;
m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle());
+ if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex))
+ m_writer.writeBlobIndex(blobIndex);
+ else
+ m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
return 0;
}
@@ -1282,20 +1313,41 @@ private:
return 0;
if (file->hasBeenClosed())
return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next);
- m_writer.writeFile(*file);
+ int blobIndex = -1;
m_blobDataHandles.add(file->uuid(), file->blobDataHandle());
+ if (appendFileInfo(file->uuid(), file->path(), file->name(), file->type(), &blobIndex)) {
+ ASSERT(blobIndex >= 0);
+ m_writer.writeFileIndex(blobIndex);
+ } else {
+ m_writer.writeFile(*file);
+ }
return 0;
}
- void writeFileList(v8::Handle<v8::Value> value)
+ StateBase* writeFileList(v8::Handle<v8::Value> value, StateBase* next)
{
FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
if (!fileList)
- return;
- m_writer.writeFileList(*fileList);
+ return 0;
unsigned length = fileList->length();
- for (unsigned i = 0; i < length; ++i)
- m_blobDataHandles.add(fileList->item(i)->uuid(), fileList->item(i)->blobDataHandle());
+ Vector<int> blobIndices;
+ for (unsigned i = 0; i < length; ++i) {
+ int blobIndex = -1;
+ const File* file = fileList->item(i);
+ if (file->hasBeenClosed())
+ return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next);
+ m_blobDataHandles.add(file->uuid(), file->blobDataHandle());
+ if (appendFileInfo(file->uuid(), file->path(), file->name(), file->type(), &blobIndex)) {
+ ASSERT(!i || blobIndex > 0);
+ ASSERT(blobIndex >= 0);
+ blobIndices.append(blobIndex);
+ }
+ }
+ if (!blobIndices.isEmpty())
+ m_writer.writeFileListIndex(blobIndices);
+ else
+ m_writer.writeFileList(*fileList);
+ return 0;
}
bool writeCryptoKey(v8::Handle<v8::Value> value)
@@ -1414,6 +1466,24 @@ private:
m_objectPool.set(object, objectReference);
}
+ bool appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index)
+ {
+ if (!m_blobInfo)
+ return false;
+ *index = m_blobInfo->size();
+ m_blobInfo->append(blink::WebBlobInfo(uuid, type, size));
+ return true;
+ }
+
+ bool appendFileInfo(const String& uuid, const String& filePath, const String& fileName, const String& type, int* index)
+ {
+ if (!m_blobInfo)
+ return false;
+ *index = m_blobInfo->size();
+ m_blobInfo->append(blink::WebBlobInfo(uuid, filePath, fileName, type));
+ return true;
+ }
+
Writer& m_writer;
v8::TryCatch& m_tryCatch;
int m_depth;
@@ -1424,6 +1494,7 @@ private:
ObjectPool m_transferredMessagePorts;
ObjectPool m_transferredArrayBuffers;
uint32_t m_nextObjectReference;
+ WebBlobInfoArray* m_blobInfo;
BlobDataHandleMap& m_blobDataHandles;
v8::Isolate* m_isolate;
};
@@ -1500,7 +1571,7 @@ Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat
else if (V8DOMFileSystem::hasInstance(value, m_isolate))
return writeDOMFileSystem(value, next);
else if (V8FileList::hasInstance(value, m_isolate))
- writeFileList(value);
+ return writeFileList(value, next);
else if (V8Key::hasInstance(value, m_isolate)) {
if (!writeCryptoKey(value))
return handleError(DataCloneError, "Couldn't serialize key data", next);
@@ -1543,12 +1614,13 @@ public:
// restoring information about saved objects of composite types.
class Reader {
public:
- Reader(const uint8_t* buffer, int length, v8::Isolate* isolate, const BlobDataHandleMap& blobDataHandles)
+ Reader(const uint8_t* buffer, int length, v8::Isolate* isolate, const WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles)
: m_buffer(buffer)
, m_length(length)
, m_position(0)
, m_version(0)
, m_isolate(isolate)
+ , m_blobInfo(blobInfo)
, m_blobDataHandles(blobDataHandles)
{
ASSERT(!(reinterpret_cast<size_t>(buffer) & 1));
@@ -1638,12 +1710,14 @@ public:
creator.pushObjectReference(*value);
break;
case BlobTag:
- if (!readBlob(value))
+ case BlobIndexTag:
+ if (!readBlob(value, tag == BlobIndexTag))
return false;
creator.pushObjectReference(*value);
break;
case FileTag:
- if (!readFile(value))
+ case FileIndexTag:
+ if (!readFile(value, tag == FileIndexTag))
return false;
creator.pushObjectReference(*value);
break;
@@ -1653,7 +1727,8 @@ public:
creator.pushObjectReference(*value);
break;
case FileListTag:
- if (!readFileList(value))
+ case FileListIndexTag:
+ if (!readFileList(value, tag == FileListIndexTag))
return false;
creator.pushObjectReference(*value);
break;
@@ -2064,20 +2139,34 @@ private:
return true;
}
- bool readBlob(v8::Handle<v8::Value>* value)
+ bool readBlob(v8::Handle<v8::Value>* value, bool isIndexed)
{
if (m_version < 3)
return false;
- String uuid;
- String type;
- uint64_t size;
- if (!readWebCoreString(&uuid))
- return false;
- if (!readWebCoreString(&type))
- return false;
- if (!doReadUint64(&size))
- return false;
- RefPtrWillBeRawPtr<Blob> blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
+ RefPtrWillBeRawPtr<Blob> blob;
+ if (isIndexed) {
+ if (m_version < 6)
+ return false;
+ ASSERT(m_blobInfo);
+ uint32_t index;
+ if (!doReadUint32(&index) || index >= m_blobInfo->size())
+ return false;
+ const blink::WebBlobInfo& info = (*m_blobInfo)[index];
+ blob = Blob::create(getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
+ } else {
+ ASSERT(!m_blobInfo);
+ String uuid;
+ String type;
+ uint64_t size;
+ ASSERT(!m_blobInfo);
+ if (!readWebCoreString(&uuid))
+ return false;
+ if (!readWebCoreString(&type))
+ return false;
+ if (!doReadUint64(&size))
+ return false;
+ blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
+ }
*value = toV8(blob.release(), v8::Handle<v8::Object>(), m_isolate);
return true;
}
@@ -2098,16 +2187,23 @@ private:
return true;
}
- bool readFile(v8::Handle<v8::Value>* value)
+ bool readFile(v8::Handle<v8::Value>* value, bool isIndexed)
{
- RefPtrWillBeRawPtr<File> file = doReadFileHelper();
+ RefPtrWillBeRawPtr<File> file;
+ if (isIndexed) {
+ if (m_version < 6)
+ return false;
+ file = readFileIndexHelper();
+ } else {
+ file = readFileHelper();
+ }
if (!file)
return false;
*value = toV8(file.release(), v8::Handle<v8::Object>(), m_isolate);
return true;
}
- bool readFileList(v8::Handle<v8::Value>* value)
+ bool readFileList(v8::Handle<v8::Value>* value, bool isIndexed)
{
if (m_version < 3)
return false;
@@ -2116,7 +2212,14 @@ private:
return false;
RefPtrWillBeRawPtr<FileList> fileList = FileList::create();
for (unsigned i = 0; i < length; ++i) {
- RefPtrWillBeRawPtr<File> file = doReadFileHelper();
+ RefPtrWillBeRawPtr<File> file;
+ if (isIndexed) {
+ if (m_version < 6)
+ return false;
+ file = readFileIndexHelper();
+ } else {
+ file = readFileHelper();
+ }
if (!file)
return false;
fileList->append(file.release());
@@ -2181,10 +2284,11 @@ private:
return true;
}
- PassRefPtrWillBeRawPtr<File> doReadFileHelper()
+ PassRefPtrWillBeRawPtr<File> readFileHelper()
{
if (m_version < 3)
return nullptr;
+ ASSERT(!m_blobInfo);
String path;
String name;
String relativePath;
@@ -2214,6 +2318,18 @@ private:
return File::create(path, name, relativePath, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type));
}
+ PassRefPtrWillBeRawPtr<File> readFileIndexHelper()
+ {
+ if (m_version < 3)
+ return nullptr;
+ ASSERT(m_blobInfo);
+ uint32_t index;
+ if (!doReadUint32(&index) || index >= m_blobInfo->size())
+ return nullptr;
+ const blink::WebBlobInfo& info = (*m_blobInfo)[index];
+ return File::create(info.filePath(), info.fileName(), info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
+ }
+
template<class T>
bool doReadUintHelper(T* value)
{
@@ -2261,7 +2377,7 @@ private:
// the collection of BDH's for blobs to work, which would encourage lifetimes to be considered
// when passing ssv's around cross process. At present, we get 'lucky' in some cases because
// the blob in the src process happens to still exist at the time the dest process is deserializing.
- // For example in sharedWorker.postMesssage(...).
+ // For example in sharedWorker.postMessage(...).
BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid);
if (it != m_blobDataHandles.end()) {
// make assertions about type and size?
@@ -2432,6 +2548,7 @@ private:
unsigned m_position;
uint32_t m_version;
v8::Isolate* m_isolate;
+ const WebBlobInfoArray* m_blobInfo;
const BlobDataHandleMap& m_blobDataHandles;
};
@@ -2674,19 +2791,19 @@ private:
PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
{
- return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, exceptionState, isolate));
+ return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, 0, exceptionState, isolate));
}
PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExceptions(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
TrackExceptionState exceptionState;
- return adoptRef(new SerializedScriptValue(value, 0, 0, exceptionState, isolate));
+ return adoptRef(new SerializedScriptValue(value, 0, 0, 0, exceptionState, isolate));
}
-PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, ExceptionState& exceptionState, ScriptState* state)
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, ScriptState* state)
{
ScriptScope scope(state);
- return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, exceptionState, state->isolate()));
+ return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, blobInfo, exceptionState, state->isolate()));
}
PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& data)
@@ -2810,7 +2927,7 @@ PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
return contents.release();
}
-SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
+SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate)
: m_externallyAllocatedMemory(0)
{
Writer writer;
@@ -2818,7 +2935,7 @@ SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag
String errorMessage;
{
v8::TryCatch tryCatch;
- Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHandles, tryCatch, isolate);
+ Serializer serializer(writer, messagePorts, arrayBuffers, blobInfo, m_blobDataHandles, tryCatch, isolate);
status = serializer.serialize(value);
if (status == Serializer::JSException) {
// If there was a JS exception thrown, re-throw it.
@@ -2853,10 +2970,10 @@ SerializedScriptValue::SerializedScriptValue(const String& wireData)
v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messagePorts)
{
- return deserialize(v8::Isolate::GetCurrent(), messagePorts);
+ return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
}
-v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts)
+v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts, const WebBlobInfoArray* blobInfo)
{
if (!m_data.impl())
return v8::Null(isolate);
@@ -2866,7 +2983,7 @@ v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M
// storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
// information stored in m_data isn't even encoded in UTF-16. Instead,
// unicode characters are encoded as UTF-8 with two code units per UChar.
- Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate, m_blobDataHandles);
+ Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate, blobInfo, m_blobDataHandles);
Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.get());
// deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed.
« no previous file with comments | « Source/bindings/v8/SerializedScriptValue.h ('k') | Source/core/fileapi/File.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698