1d0825bca7fe65beaee391d30da42e937db621564Steve Block/* 2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2010 Google Inc. All rights reserved. 3d0825bca7fe65beaee391d30da42e937db621564Steve Block * 4d0825bca7fe65beaee391d30da42e937db621564Steve Block * Redistribution and use in source and binary forms, with or without 5d0825bca7fe65beaee391d30da42e937db621564Steve Block * modification, are permitted provided that the following conditions are 6d0825bca7fe65beaee391d30da42e937db621564Steve Block * met: 7d0825bca7fe65beaee391d30da42e937db621564Steve Block * 8d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Redistributions of source code must retain the above copyright 9d0825bca7fe65beaee391d30da42e937db621564Steve Block * notice, this list of conditions and the following disclaimer. 10d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Redistributions in binary form must reproduce the above 11d0825bca7fe65beaee391d30da42e937db621564Steve Block * copyright notice, this list of conditions and the following disclaimer 12d0825bca7fe65beaee391d30da42e937db621564Steve Block * in the documentation and/or other materials provided with the 13d0825bca7fe65beaee391d30da42e937db621564Steve Block * distribution. 14d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Neither the name of Google Inc. nor the names of its 15d0825bca7fe65beaee391d30da42e937db621564Steve Block * contributors may be used to endorse or promote products derived from 16d0825bca7fe65beaee391d30da42e937db621564Steve Block * this software without specific prior written permission. 17d0825bca7fe65beaee391d30da42e937db621564Steve Block * 18d0825bca7fe65beaee391d30da42e937db621564Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19d0825bca7fe65beaee391d30da42e937db621564Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21d0825bca7fe65beaee391d30da42e937db621564Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22d0825bca7fe65beaee391d30da42e937db621564Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23d0825bca7fe65beaee391d30da42e937db621564Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25d0825bca7fe65beaee391d30da42e937db621564Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26d0825bca7fe65beaee391d30da42e937db621564Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27d0825bca7fe65beaee391d30da42e937db621564Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28d0825bca7fe65beaee391d30da42e937db621564Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29d0825bca7fe65beaee391d30da42e937db621564Steve Block */ 30d0825bca7fe65beaee391d30da42e937db621564Steve Block 31d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "config.h" 32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "SerializedScriptValue.h" 33d0825bca7fe65beaee391d30da42e937db621564Steve Block 34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Blob.h" 35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ByteArray.h" 36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "CanvasPixelArray.h" 37ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "ExceptionCode.h" 38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "File.h" 39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "FileList.h" 40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ImageData.h" 41d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "SharedBuffer.h" 42545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "V8Binding.h" 43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8Blob.h" 44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8File.h" 45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8FileList.h" 46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8ImageData.h" 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8Proxy.h" 480617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#include "V8Utilities.h" 49d0825bca7fe65beaee391d30da42e937db621564Steve Block 50d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/Assertions.h> 51d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/RefCounted.h> 52d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/Vector.h> 53d0825bca7fe65beaee391d30da42e937db621564Steve Block 5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch// FIXME: consider crashing in debug mode on deserialization errors 55d0825bca7fe65beaee391d30da42e937db621564Steve Block 56d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace WebCore { 57d0825bca7fe65beaee391d30da42e937db621564Steve Block 58d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace { 59d0825bca7fe65beaee391d30da42e937db621564Steve Block 60d0825bca7fe65beaee391d30da42e937db621564Steve Blocktypedef UChar BufferValueType; 61d0825bca7fe65beaee391d30da42e937db621564Steve Block 62d0825bca7fe65beaee391d30da42e937db621564Steve Block// Serialization format is a sequence of (tag, optional data) 63d0825bca7fe65beaee391d30da42e937db621564Steve Block// pairs. Tag always takes exactly one byte. 64d0825bca7fe65beaee391d30da42e937db621564Steve Blockenum SerializationTag { 65d0825bca7fe65beaee391d30da42e937db621564Steve Block InvalidTag = '!', 66d0825bca7fe65beaee391d30da42e937db621564Steve Block PaddingTag = '\0', 67d0825bca7fe65beaee391d30da42e937db621564Steve Block UndefinedTag = '_', 68d0825bca7fe65beaee391d30da42e937db621564Steve Block NullTag = '0', 69d0825bca7fe65beaee391d30da42e937db621564Steve Block TrueTag = 'T', 70d0825bca7fe65beaee391d30da42e937db621564Steve Block FalseTag = 'F', 71d0825bca7fe65beaee391d30da42e937db621564Steve Block StringTag = 'S', 72d0825bca7fe65beaee391d30da42e937db621564Steve Block Int32Tag = 'I', 73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Uint32Tag = 'U', 74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DateTag = 'D', 75d0825bca7fe65beaee391d30da42e937db621564Steve Block NumberTag = 'N', 76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block BlobTag = 'b', 77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block FileTag = 'f', 78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block FileListTag = 'l', 79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ImageDataTag = '#', 80d0825bca7fe65beaee391d30da42e937db621564Steve Block ArrayTag = '[', 81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ObjectTag = '{', 82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SparseArrayTag = '@', 83e14391e94c850b8bd03680c23b38978db68687a8John Reck RegExpTag = 'R', 84d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 85d0825bca7fe65beaee391d30da42e937db621564Steve Block 86d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic bool shouldCheckForCycles(int depth) 87d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 88d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(depth >= 0); 89d0825bca7fe65beaee391d30da42e937db621564Steve Block // Since we are not required to spot the cycle as soon as it 90d0825bca7fe65beaee391d30da42e937db621564Steve Block // happens we can check for cycles only when the current depth 91d0825bca7fe65beaee391d30da42e937db621564Steve Block // is a power of two. 92d0825bca7fe65beaee391d30da42e937db621564Steve Block return !(depth & (depth - 1)); 93d0825bca7fe65beaee391d30da42e937db621564Steve Block} 94d0825bca7fe65beaee391d30da42e937db621564Steve Block 95d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const int maxDepth = 20000; 96d0825bca7fe65beaee391d30da42e937db621564Steve Block 97d0825bca7fe65beaee391d30da42e937db621564Steve Block// VarInt encoding constants. 98d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const int varIntShift = 7; 99d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const int varIntMask = (1 << varIntShift) - 1; 100d0825bca7fe65beaee391d30da42e937db621564Steve Block 101d0825bca7fe65beaee391d30da42e937db621564Steve Block// ZigZag encoding helps VarInt encoding stay small for negative 102d0825bca7fe65beaee391d30da42e937db621564Steve Block// numbers with small absolute values. 103d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass ZigZag { 104d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic: 105d0825bca7fe65beaee391d30da42e937db621564Steve Block static uint32_t encode(uint32_t value) 106d0825bca7fe65beaee391d30da42e937db621564Steve Block { 107d0825bca7fe65beaee391d30da42e937db621564Steve Block if (value & (1U << 31)) 108d0825bca7fe65beaee391d30da42e937db621564Steve Block value = ((~value) << 1) + 1; 109d0825bca7fe65beaee391d30da42e937db621564Steve Block else 110d0825bca7fe65beaee391d30da42e937db621564Steve Block value <<= 1; 111d0825bca7fe65beaee391d30da42e937db621564Steve Block return value; 112d0825bca7fe65beaee391d30da42e937db621564Steve Block } 113d0825bca7fe65beaee391d30da42e937db621564Steve Block 114d0825bca7fe65beaee391d30da42e937db621564Steve Block static uint32_t decode(uint32_t value) 115d0825bca7fe65beaee391d30da42e937db621564Steve Block { 116d0825bca7fe65beaee391d30da42e937db621564Steve Block if (value & 1) 117d0825bca7fe65beaee391d30da42e937db621564Steve Block value = ~(value >> 1); 118d0825bca7fe65beaee391d30da42e937db621564Steve Block else 119d0825bca7fe65beaee391d30da42e937db621564Steve Block value >>= 1; 120d0825bca7fe65beaee391d30da42e937db621564Steve Block return value; 121d0825bca7fe65beaee391d30da42e937db621564Steve Block } 122d0825bca7fe65beaee391d30da42e937db621564Steve Block 123d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate: 124d0825bca7fe65beaee391d30da42e937db621564Steve Block ZigZag(); 125d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 126d0825bca7fe65beaee391d30da42e937db621564Steve Block 127d0825bca7fe65beaee391d30da42e937db621564Steve Block// Writer is responsible for serializing primitive types and storing 128d0825bca7fe65beaee391d30da42e937db621564Steve Block// information used to reconstruct composite types. 129ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass Writer { 130ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WTF_MAKE_NONCOPYABLE(Writer); 131d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic: 132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Writer() 133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : m_position(0) 134d0825bca7fe65beaee391d30da42e937db621564Steve Block { 135d0825bca7fe65beaee391d30da42e937db621564Steve Block } 136d0825bca7fe65beaee391d30da42e937db621564Steve Block 137d0825bca7fe65beaee391d30da42e937db621564Steve Block // Write functions for primitive types. 138d0825bca7fe65beaee391d30da42e937db621564Steve Block 139d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeUndefined() { append(UndefinedTag); } 140d0825bca7fe65beaee391d30da42e937db621564Steve Block 141d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeNull() { append(NullTag); } 142d0825bca7fe65beaee391d30da42e937db621564Steve Block 143d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeTrue() { append(TrueTag); } 144d0825bca7fe65beaee391d30da42e937db621564Steve Block 145d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeFalse() { append(FalseTag); } 146d0825bca7fe65beaee391d30da42e937db621564Steve Block 147d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeString(const char* data, int length) 148d0825bca7fe65beaee391d30da42e937db621564Steve Block { 149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(length >= 0); 150d0825bca7fe65beaee391d30da42e937db621564Steve Block append(StringTag); 151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteString(data, length); 152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeWebCoreString(const String& string) 155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Uses UTF8 encoding so we can read it back as either V8 or 157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // WebCore string. 158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(StringTag); 159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteWebCoreString(string); 160d0825bca7fe65beaee391d30da42e937db621564Steve Block } 161d0825bca7fe65beaee391d30da42e937db621564Steve Block 162d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeInt32(int32_t value) 163d0825bca7fe65beaee391d30da42e937db621564Steve Block { 164d0825bca7fe65beaee391d30da42e937db621564Steve Block append(Int32Tag); 165d0825bca7fe65beaee391d30da42e937db621564Steve Block doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value))); 166d0825bca7fe65beaee391d30da42e937db621564Steve Block } 167d0825bca7fe65beaee391d30da42e937db621564Steve Block 168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeUint32(uint32_t value) 169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(Uint32Tag); 171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(value); 172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeDate(double numberValue) 175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(DateTag); 177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteNumber(numberValue); 178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 180d0825bca7fe65beaee391d30da42e937db621564Steve Block void writeNumber(double number) 181d0825bca7fe65beaee391d30da42e937db621564Steve Block { 182d0825bca7fe65beaee391d30da42e937db621564Steve Block append(NumberTag); 183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteNumber(number); 184d0825bca7fe65beaee391d30da42e937db621564Steve Block } 185d0825bca7fe65beaee391d30da42e937db621564Steve Block 186f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick void writeBlob(const String& url, const String& type, unsigned long long size) 187d0825bca7fe65beaee391d30da42e937db621564Steve Block { 188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(BlobTag); 189f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteWebCoreString(url); 190f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteWebCoreString(type); 191f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteUint64(size); 192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 194f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick void writeFile(const String& path, const String& url, const String& type) 195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(FileTag); 197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteWebCoreString(path); 198f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteWebCoreString(url); 199f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteWebCoreString(type); 200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 201dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 202dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeFileList(const FileList& fileList) 203dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 204dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(FileListTag); 205dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t length = fileList.length(); 206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(length); 207f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (unsigned i = 0; i < length; ++i) { 208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteWebCoreString(fileList.item(i)->path()); 209f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteWebCoreString(fileList.item(i)->url().string()); 210f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteWebCoreString(fileList.item(i)->type()); 211f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 213dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 214dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength) 215dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 216dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(ImageDataTag); 217dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(width); 218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(height); 219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(pixelDataLength); 220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(pixelData, pixelDataLength); 221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 22281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 223e14391e94c850b8bd03680c23b38978db68687a8John Reck void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags) 224e14391e94c850b8bd03680c23b38978db68687a8John Reck { 225e14391e94c850b8bd03680c23b38978db68687a8John Reck append(RegExpTag); 226e14391e94c850b8bd03680c23b38978db68687a8John Reck v8::String::Utf8Value patternUtf8Value(pattern); 227e14391e94c850b8bd03680c23b38978db68687a8John Reck doWriteString(*patternUtf8Value, patternUtf8Value.length()); 228e14391e94c850b8bd03680c23b38978db68687a8John Reck doWriteUint32(static_cast<uint32_t>(flags)); 22981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 230dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeArray(uint32_t length) 232dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 233dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(ArrayTag); 234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(length); 235dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 236dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeObject(uint32_t numProperties) 238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(ObjectTag); 240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(numProperties); 241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeSparseArray(uint32_t numProperties, uint32_t length) 244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 245dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(SparseArrayTag); 246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(numProperties); 247dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(length); 248d0825bca7fe65beaee391d30da42e937db621564Steve Block } 249d0825bca7fe65beaee391d30da42e937db621564Steve Block 250d0825bca7fe65beaee391d30da42e937db621564Steve Block Vector<BufferValueType>& data() 251d0825bca7fe65beaee391d30da42e937db621564Steve Block { 252d0825bca7fe65beaee391d30da42e937db621564Steve Block fillHole(); 253d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_buffer; 254d0825bca7fe65beaee391d30da42e937db621564Steve Block } 255d0825bca7fe65beaee391d30da42e937db621564Steve Block 256d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate: 257dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void doWriteString(const char* data, int length) 258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteUint32(static_cast<uint32_t>(length)); 260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(reinterpret_cast<const uint8_t*>(data), length); 261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void doWriteWebCoreString(const String& string) 264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RefPtr<SharedBuffer> buffer = utf8Buffer(string); 266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block doWriteString(buffer->data(), buffer->size()); 267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 269f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick template<class T> 270f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick void doWriteUintHelper(T value) 271d0825bca7fe65beaee391d30da42e937db621564Steve Block { 272d0825bca7fe65beaee391d30da42e937db621564Steve Block while (true) { 273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint8_t b = (value & varIntMask); 274d0825bca7fe65beaee391d30da42e937db621564Steve Block value >>= varIntShift; 275d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!value) { 276d0825bca7fe65beaee391d30da42e937db621564Steve Block append(b); 277d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 278d0825bca7fe65beaee391d30da42e937db621564Steve Block } 279d0825bca7fe65beaee391d30da42e937db621564Steve Block append(b | (1 << varIntShift)); 280d0825bca7fe65beaee391d30da42e937db621564Steve Block } 281d0825bca7fe65beaee391d30da42e937db621564Steve Block } 282d0825bca7fe65beaee391d30da42e937db621564Steve Block 283f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick void doWriteUint32(uint32_t value) 284f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick { 285f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteUintHelper(value); 286f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 287f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 288f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick void doWriteUint64(uint64_t value) 289f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick { 290f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick doWriteUintHelper(value); 291f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 292f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void doWriteNumber(double number) 294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); 296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 298d0825bca7fe65beaee391d30da42e937db621564Steve Block void append(SerializationTag tag) 299d0825bca7fe65beaee391d30da42e937db621564Steve Block { 300dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block append(static_cast<uint8_t>(tag)); 301d0825bca7fe65beaee391d30da42e937db621564Steve Block } 302d0825bca7fe65beaee391d30da42e937db621564Steve Block 303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void append(uint8_t b) 304d0825bca7fe65beaee391d30da42e937db621564Steve Block { 305d0825bca7fe65beaee391d30da42e937db621564Steve Block ensureSpace(1); 306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *byteAt(m_position++) = b; 307d0825bca7fe65beaee391d30da42e937db621564Steve Block } 308d0825bca7fe65beaee391d30da42e937db621564Steve Block 309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void append(const uint8_t* data, int length) 310d0825bca7fe65beaee391d30da42e937db621564Steve Block { 311d0825bca7fe65beaee391d30da42e937db621564Steve Block ensureSpace(length); 312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block memcpy(byteAt(m_position), data, length); 313d0825bca7fe65beaee391d30da42e937db621564Steve Block m_position += length; 314d0825bca7fe65beaee391d30da42e937db621564Steve Block } 315d0825bca7fe65beaee391d30da42e937db621564Steve Block 316d0825bca7fe65beaee391d30da42e937db621564Steve Block void ensureSpace(int extra) 317d0825bca7fe65beaee391d30da42e937db621564Steve Block { 318d0825bca7fe65beaee391d30da42e937db621564Steve Block COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 319d0825bca7fe65beaee391d30da42e937db621564Steve Block m_buffer.grow((m_position + extra + 1) / 2); // "+ 1" to round up. 320d0825bca7fe65beaee391d30da42e937db621564Steve Block } 321d0825bca7fe65beaee391d30da42e937db621564Steve Block 322d0825bca7fe65beaee391d30da42e937db621564Steve Block void fillHole() 323d0825bca7fe65beaee391d30da42e937db621564Steve Block { 324d0825bca7fe65beaee391d30da42e937db621564Steve Block COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 325d0825bca7fe65beaee391d30da42e937db621564Steve Block // If the writer is at odd position in the buffer, then one of 326d0825bca7fe65beaee391d30da42e937db621564Steve Block // the bytes in the last UChar is not initialized. 327d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_position % 2) 328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); 329d0825bca7fe65beaee391d30da42e937db621564Steve Block } 330d0825bca7fe65beaee391d30da42e937db621564Steve Block 331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; } 332d0825bca7fe65beaee391d30da42e937db621564Steve Block 333d0825bca7fe65beaee391d30da42e937db621564Steve Block Vector<BufferValueType> m_buffer; 334d0825bca7fe65beaee391d30da42e937db621564Steve Block unsigned m_position; 335d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 336d0825bca7fe65beaee391d30da42e937db621564Steve Block 337d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass Serializer { 338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class StateBase; 339d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic: 34081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch enum Status { 34181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Success, 34281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch InputError, 34381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSException, 34481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSFailure 34581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch }; 34681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 34781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Serializer(Writer& writer, v8::TryCatch& tryCatch) 348d0825bca7fe65beaee391d30da42e937db621564Steve Block : m_writer(writer) 34981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_tryCatch(tryCatch) 350d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_depth(0) 35181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_status(Success) 352d0825bca7fe65beaee391d30da42e937db621564Steve Block { 35381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(!tryCatch.HasCaught()); 354d0825bca7fe65beaee391d30da42e937db621564Steve Block } 355d0825bca7fe65beaee391d30da42e937db621564Steve Block 35681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Status serialize(v8::Handle<v8::Value> value) 357d0825bca7fe65beaee391d30da42e937db621564Steve Block { 358d0825bca7fe65beaee391d30da42e937db621564Steve Block v8::HandleScope scope; 359dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* state = doSerialize(value, 0); 360dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block while (state) 361dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block state = state->advance(*this); 36281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return m_status; 363dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 364dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Functions used by serialization states. 366dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 367dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next); 368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 36981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch StateBase* checkException(StateBase* state) 37081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 37181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return m_tryCatch.HasCaught() ? handleError(JSException, state) : 0; 37281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 37381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 37481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch StateBase* reportFailure(StateBase* state) 37581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 37681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return handleError(JSFailure, state); 37781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 37881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 379dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* writeArray(uint32_t length, StateBase* state) 380dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeArray(length); 382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return pop(state); 383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* writeObject(uint32_t numProperties, StateBase* state) 386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeObject(numProperties); 388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return pop(state); 389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state) 392dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 393dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeSparseArray(numProperties, length); 394dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return pop(state); 395d0825bca7fe65beaee391d30da42e937db621564Steve Block } 396d0825bca7fe65beaee391d30da42e937db621564Steve Block 397d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate: 398ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch class StateBase { 399ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WTF_MAKE_NONCOPYABLE(StateBase); 400d0825bca7fe65beaee391d30da42e937db621564Steve Block public: 401d0825bca7fe65beaee391d30da42e937db621564Steve Block virtual ~StateBase() { } 402d0825bca7fe65beaee391d30da42e937db621564Steve Block 403d0825bca7fe65beaee391d30da42e937db621564Steve Block // Link to the next state to form a stack. 404d0825bca7fe65beaee391d30da42e937db621564Steve Block StateBase* nextState() { return m_next; } 405d0825bca7fe65beaee391d30da42e937db621564Steve Block 406d0825bca7fe65beaee391d30da42e937db621564Steve Block // Composite object we're processing in this state. 407d0825bca7fe65beaee391d30da42e937db621564Steve Block v8::Handle<v8::Value> composite() { return m_composite; } 408d0825bca7fe65beaee391d30da42e937db621564Steve Block 409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Serializes (a part of) the current composite and returns 410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // the next state to process or null when this is the final 411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // state. 412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* advance(Serializer&) = 0; 413d0825bca7fe65beaee391d30da42e937db621564Steve Block 414d0825bca7fe65beaee391d30da42e937db621564Steve Block protected: 415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase(v8::Handle<v8::Value> composite, StateBase* next) 416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : m_composite(composite) 417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_next(next) 418d0825bca7fe65beaee391d30da42e937db621564Steve Block { 419d0825bca7fe65beaee391d30da42e937db621564Steve Block } 420d0825bca7fe65beaee391d30da42e937db621564Steve Block 421d0825bca7fe65beaee391d30da42e937db621564Steve Block private: 422d0825bca7fe65beaee391d30da42e937db621564Steve Block v8::Handle<v8::Value> m_composite; 423dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* m_next; 424d0825bca7fe65beaee391d30da42e937db621564Steve Block }; 425d0825bca7fe65beaee391d30da42e937db621564Steve Block 426dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Dummy state that is used to signal serialization errors. 427dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class ErrorState : public StateBase { 428d0825bca7fe65beaee391d30da42e937db621564Steve Block public: 429dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ErrorState() 430dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : StateBase(v8::Handle<v8::Value>(), 0) 431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 432dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 433d0825bca7fe65beaee391d30da42e937db621564Steve Block 434dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* advance(Serializer&) 435dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 436dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block delete this; 437dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return 0; 438dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 439dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block }; 440dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 441dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block template <typename T> 442dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class State : public StateBase { 443dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block public: 444dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); } 445d0825bca7fe65beaee391d30da42e937db621564Steve Block 446d0825bca7fe65beaee391d30da42e937db621564Steve Block protected: 447dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block State(v8::Handle<T> composite, StateBase* next) 448dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : StateBase(composite, next) 449d0825bca7fe65beaee391d30da42e937db621564Steve Block { 450d0825bca7fe65beaee391d30da42e937db621564Steve Block } 451d0825bca7fe65beaee391d30da42e937db621564Steve Block }; 452d0825bca7fe65beaee391d30da42e937db621564Steve Block 453dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if 0 454dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Currently unused, see comment in newArrayState. 455dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class ArrayState : public State<v8::Array> { 456d0825bca7fe65beaee391d30da42e937db621564Steve Block public: 457dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ArrayState(v8::Handle<v8::Array> array, StateBase* next) 458dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : State<v8::Array>(array, next) 459dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_index(-1) 460d0825bca7fe65beaee391d30da42e937db621564Steve Block { 461d0825bca7fe65beaee391d30da42e937db621564Steve Block } 462d0825bca7fe65beaee391d30da42e937db621564Steve Block 463dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* advance(Serializer& serializer) 464d0825bca7fe65beaee391d30da42e937db621564Steve Block { 465dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ++m_index; 466dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (; m_index < composite()->Length(); ++m_index) { 46781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch v8::Handle<v8::Value> value = composite()->Get(m_index); 46881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.checkException(this)) 46981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return newState; 47081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.doSerialize(value, this)) 471dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return newState; 472d0825bca7fe65beaee391d30da42e937db621564Steve Block } 473dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return serializer.writeArray(composite()->Length(), this); 474d0825bca7fe65beaee391d30da42e937db621564Steve Block } 475d0825bca7fe65beaee391d30da42e937db621564Steve Block 476d0825bca7fe65beaee391d30da42e937db621564Steve Block private: 477dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block unsigned m_index; 478d0825bca7fe65beaee391d30da42e937db621564Steve Block }; 479dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 480d0825bca7fe65beaee391d30da42e937db621564Steve Block 481dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class AbstractObjectState : public State<v8::Object> { 482d0825bca7fe65beaee391d30da42e937db621564Steve Block public: 483dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next) 484dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : State<v8::Object>(object, next) 48581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_index(0) 486dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_numSerializedProperties(0) 487dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_nameDone(false) 488d0825bca7fe65beaee391d30da42e937db621564Steve Block { 489d0825bca7fe65beaee391d30da42e937db621564Steve Block } 490d0825bca7fe65beaee391d30da42e937db621564Steve Block 491dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* advance(Serializer& serializer) 492d0825bca7fe65beaee391d30da42e937db621564Steve Block { 49381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_index) { 49481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_propertyNames = composite()->GetPropertyNames(); 49581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.checkException(this)) 49681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return newState; 49781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_propertyNames.IsEmpty()) 49881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return serializer.reportFailure(this); 49981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 50081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch while (m_index < m_propertyNames->Length()) { 50181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_nameDone) { 502dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); 50381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.checkException(this)) 50481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return newState; 50581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (propertyName.IsEmpty()) 50681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return serializer.reportFailure(this); 50781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch bool hasStringProperty = propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>()); 50881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.checkException(this)) 50981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return newState; 51081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch bool hasIndexedProperty = !hasStringProperty && propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()); 51181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.checkException(this)) 51281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return newState; 51381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (hasStringProperty || hasIndexedProperty) 514dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_propertyName = propertyName; 51581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch else { 51681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ++m_index; 517dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block continue; 51881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 519dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 520dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!m_propertyName.IsEmpty()); 521dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!m_nameDone) { 522dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_nameDone = true; 523dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (StateBase* newState = serializer.doSerialize(m_propertyName, this)) 524dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return newState; 525dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 526dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Value> value = composite()->Get(m_propertyName); 52781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (StateBase* newState = serializer.checkException(this)) 52881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return newState; 529dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_nameDone = false; 530dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_propertyName.Clear(); 53181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ++m_index; 532dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ++m_numSerializedProperties; 533dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (StateBase* newState = serializer.doSerialize(value, this)) 534dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return newState; 535dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 536dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return objectDone(m_numSerializedProperties, serializer); 537d0825bca7fe65beaee391d30da42e937db621564Steve Block } 538d0825bca7fe65beaee391d30da42e937db621564Steve Block 539dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block protected: 540dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; 541d0825bca7fe65beaee391d30da42e937db621564Steve Block 542d0825bca7fe65beaee391d30da42e937db621564Steve Block private: 543dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Array> m_propertyNames; 544dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Value> m_propertyName; 545d0825bca7fe65beaee391d30da42e937db621564Steve Block unsigned m_index; 546dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block unsigned m_numSerializedProperties; 547dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool m_nameDone; 548d0825bca7fe65beaee391d30da42e937db621564Steve Block }; 549d0825bca7fe65beaee391d30da42e937db621564Steve Block 550dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class ObjectState : public AbstractObjectState { 551d0825bca7fe65beaee391d30da42e937db621564Steve Block public: 552dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ObjectState(v8::Handle<v8::Object> object, StateBase* next) 553dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : AbstractObjectState(object, next) 554d0825bca7fe65beaee391d30da42e937db621564Steve Block { 555d0825bca7fe65beaee391d30da42e937db621564Steve Block } 556d0825bca7fe65beaee391d30da42e937db621564Steve Block 557dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block protected: 558dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) 559d0825bca7fe65beaee391d30da42e937db621564Steve Block { 560dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return serializer.writeObject(numProperties, this); 561d0825bca7fe65beaee391d30da42e937db621564Steve Block } 562dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block }; 563d0825bca7fe65beaee391d30da42e937db621564Steve Block 564dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block class SparseArrayState : public AbstractObjectState { 565dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block public: 566dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SparseArrayState(v8::Handle<v8::Array> array, StateBase* next) 567dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : AbstractObjectState(array, next) 568d0825bca7fe65beaee391d30da42e937db621564Steve Block { 569d0825bca7fe65beaee391d30da42e937db621564Steve Block } 570d0825bca7fe65beaee391d30da42e937db621564Steve Block 571dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block protected: 572dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) 573d0825bca7fe65beaee391d30da42e937db621564Steve Block { 574dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this); 575d0825bca7fe65beaee391d30da42e937db621564Steve Block } 576d0825bca7fe65beaee391d30da42e937db621564Steve Block }; 577d0825bca7fe65beaee391d30da42e937db621564Steve Block 578dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* push(StateBase* state) 579d0825bca7fe65beaee391d30da42e937db621564Steve Block { 580dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(state); 581d0825bca7fe65beaee391d30da42e937db621564Steve Block ++m_depth; 58281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return checkComposite(state) ? state : handleError(InputError, state); 583d0825bca7fe65beaee391d30da42e937db621564Steve Block } 584d0825bca7fe65beaee391d30da42e937db621564Steve Block 585dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* pop(StateBase* state) 586d0825bca7fe65beaee391d30da42e937db621564Steve Block { 587dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(state); 588d0825bca7fe65beaee391d30da42e937db621564Steve Block --m_depth; 589dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* next = state->nextState(); 590dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block delete state; 591dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return next; 592dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 593dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 59481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch StateBase* handleError(Status errorStatus, StateBase* state) 595dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 59681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(errorStatus != Success); 59781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_status = errorStatus; 598dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block while (state) { 599dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StateBase* tmp = state->nextState(); 600dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block delete state; 601dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block state = tmp; 602dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 603dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return new ErrorState; 604d0825bca7fe65beaee391d30da42e937db621564Steve Block } 605d0825bca7fe65beaee391d30da42e937db621564Steve Block 606dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool checkComposite(StateBase* top) 607d0825bca7fe65beaee391d30da42e937db621564Steve Block { 608dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(top); 609d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_depth > maxDepth) 610d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 611d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!shouldCheckForCycles(m_depth)) 612d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 613dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Handle<v8::Value> composite = top->composite(); 614dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (StateBase* state = top->nextState(); state; state = state->nextState()) { 615d0825bca7fe65beaee391d30da42e937db621564Steve Block if (state->composite() == composite) 616d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 617d0825bca7fe65beaee391d30da42e937db621564Steve Block } 618d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 619d0825bca7fe65beaee391d30da42e937db621564Steve Block } 620d0825bca7fe65beaee391d30da42e937db621564Steve Block 621dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeString(v8::Handle<v8::Value> value) 622dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 623dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::String::Utf8Value stringValue(value); 624dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeString(*stringValue, stringValue.length()); 625dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 626dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 627dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeBlob(v8::Handle<v8::Value> value) 628dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 629dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Blob* blob = V8Blob::toNative(value.As<v8::Object>()); 630dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!blob) 631dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 632f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_writer.writeBlob(blob->url().string(), blob->type(), blob->size()); 633dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 634dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 635dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeFile(v8::Handle<v8::Value> value) 636dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block File* file = V8File::toNative(value.As<v8::Object>()); 638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!file) 639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 640f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_writer.writeFile(file->path(), file->url().string(), file->type()); 641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 643dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeFileList(v8::Handle<v8::Value> value) 644dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 645dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block FileList* fileList = V8FileList::toNative(value.As<v8::Object>()); 646dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!fileList) 647dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 648dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeFileList(*fileList); 649dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 650dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 651dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void writeImageData(v8::Handle<v8::Value> value) 652dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 653dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>()); 654dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!imageData) 655dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 656dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block WTF::ByteArray* pixelArray = imageData->data()->data(); 657dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length()); 658dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 65981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 660e14391e94c850b8bd03680c23b38978db68687a8John Reck void writeRegExp(v8::Handle<v8::Value> value) 661e14391e94c850b8bd03680c23b38978db68687a8John Reck { 662e14391e94c850b8bd03680c23b38978db68687a8John Reck v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>(); 663e14391e94c850b8bd03680c23b38978db68687a8John Reck m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); 664e14391e94c850b8bd03680c23b38978db68687a8John Reck } 665dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 666dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next) 667dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 668dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // FIXME: use plain Array state when we can quickly check that 669dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // an array is not sparse and has only indexed properties. 670dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return new SparseArrayState(array, next); 671dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 672dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 673dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next) 674dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 67581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // FIXME: check not a wrapper 676dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return new ObjectState(object, next); 677dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 678dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 679d0825bca7fe65beaee391d30da42e937db621564Steve Block Writer& m_writer; 68081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch v8::TryCatch& m_tryCatch; 681d0825bca7fe65beaee391d30da42e937db621564Steve Block int m_depth; 68281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Status m_status; 683dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}; 684dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 685dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockSerializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next) 686dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 68781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (value.IsEmpty()) 68881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return reportFailure(next); 689dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (value->IsUndefined()) 690dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeUndefined(); 691dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsNull()) 692dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeNull(); 693dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsTrue()) 694dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeTrue(); 695dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsFalse()) 696dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeFalse(); 697dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsInt32()) 698dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeInt32(value->Int32Value()); 699dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsUint32()) 700dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeUint32(value->Uint32Value()); 701dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsDate()) 702dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeDate(value->NumberValue()); 703dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsNumber()) 704dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_writer.writeNumber(value.As<v8::Number>()->Value()); 705dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsString()) 706dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block writeString(value); 707dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsArray()) 708dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return push(newArrayState(value.As<v8::Array>(), next)); 709dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (V8File::HasInstance(value)) 710dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block writeFile(value); 711dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (V8Blob::HasInstance(value)) 712dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block writeBlob(value); 713dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (V8FileList::HasInstance(value)) 714dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block writeFileList(value); 715dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (V8ImageData::HasInstance(value)) 716dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block writeImageData(value); 717e14391e94c850b8bd03680c23b38978db68687a8John Reck else if (value->IsRegExp()) 718e14391e94c850b8bd03680c23b38978db68687a8John Reck writeRegExp(value); 719dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (value->IsObject()) 720dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return push(newObjectState(value.As<v8::Object>(), next)); 721dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return 0; 722dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 723dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 724dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// Interface used by Reader to create objects of composite types. 725dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass CompositeCreator { 726dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockpublic: 727dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual ~CompositeCreator() { } 728dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 729dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0; 730dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0; 731dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0; 732d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 733d0825bca7fe65beaee391d30da42e937db621564Steve Block 734d0825bca7fe65beaee391d30da42e937db621564Steve Block// Reader is responsible for deserializing primitive types and 735d0825bca7fe65beaee391d30da42e937db621564Steve Block// restoring information about saved objects of composite types. 736d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass Reader { 737d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic: 738dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Reader(const uint8_t* buffer, int length) 739d0825bca7fe65beaee391d30da42e937db621564Steve Block : m_buffer(buffer) 740d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_length(length) 741d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_position(0) 742d0825bca7fe65beaee391d30da42e937db621564Steve Block { 743d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(length >= 0); 744d0825bca7fe65beaee391d30da42e937db621564Steve Block } 745d0825bca7fe65beaee391d30da42e937db621564Steve Block 746d0825bca7fe65beaee391d30da42e937db621564Steve Block bool isEof() const { return m_position >= m_length; } 747d0825bca7fe65beaee391d30da42e937db621564Steve Block 748dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator) 749d0825bca7fe65beaee391d30da42e937db621564Steve Block { 750dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SerializationTag tag; 751dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readTag(&tag)) 752d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 753dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (tag) { 754d0825bca7fe65beaee391d30da42e937db621564Steve Block case InvalidTag: 755d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 756d0825bca7fe65beaee391d30da42e937db621564Steve Block case PaddingTag: 757dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 758d0825bca7fe65beaee391d30da42e937db621564Steve Block case UndefinedTag: 759d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = v8::Undefined(); 760d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 761d0825bca7fe65beaee391d30da42e937db621564Steve Block case NullTag: 762d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = v8::Null(); 763d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 764d0825bca7fe65beaee391d30da42e937db621564Steve Block case TrueTag: 765d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = v8::True(); 766d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 767d0825bca7fe65beaee391d30da42e937db621564Steve Block case FalseTag: 768d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = v8::False(); 769d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 770d0825bca7fe65beaee391d30da42e937db621564Steve Block case StringTag: 771d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!readString(value)) 772d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 773d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 774d0825bca7fe65beaee391d30da42e937db621564Steve Block case Int32Tag: 775d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!readInt32(value)) 776d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 777d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 778dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case Uint32Tag: 779dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readUint32(value)) 780dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 781dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 782dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case DateTag: 783dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readDate(value)) 784dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 785dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 786d0825bca7fe65beaee391d30da42e937db621564Steve Block case NumberTag: 787d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!readNumber(value)) 788d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 789d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 790dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case BlobTag: 791dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readBlob(value)) 792dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 793dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 794dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case FileTag: 795dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readFile(value)) 796dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 797dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 798dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case FileListTag: 799dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readFileList(value)) 800dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 801dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 802dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case ImageDataTag: 803dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readImageData(value)) 804dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 805dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 806dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case ArrayTag: { 807dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t length; 808dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&length)) 809dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 810dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!creator.createArray(length, value)) 811d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 812d0825bca7fe65beaee391d30da42e937db621564Steve Block break; 813d0825bca7fe65beaee391d30da42e937db621564Steve Block } 814e14391e94c850b8bd03680c23b38978db68687a8John Reck case RegExpTag: 815e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!readRegExp(value)) 816e14391e94c850b8bd03680c23b38978db68687a8John Reck return false; 817e14391e94c850b8bd03680c23b38978db68687a8John Reck break; 818dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case ObjectTag: { 819dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t numProperties; 820dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&numProperties)) 821dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 822dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!creator.createObject(numProperties, value)) 823dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 824dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 825dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 826dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case SparseArrayTag: { 827dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t numProperties; 828dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t length; 829dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&numProperties)) 830dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 831dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&length)) 832dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 833dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!creator.createSparseArray(numProperties, length, value)) 834dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 835dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 836dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 837dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 838dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 839dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 840dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return !value->IsEmpty(); 841d0825bca7fe65beaee391d30da42e937db621564Steve Block } 842d0825bca7fe65beaee391d30da42e937db621564Steve Block 843d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate: 844d0825bca7fe65beaee391d30da42e937db621564Steve Block bool readTag(SerializationTag* tag) 845d0825bca7fe65beaee391d30da42e937db621564Steve Block { 846d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_position >= m_length) 847d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 848d0825bca7fe65beaee391d30da42e937db621564Steve Block *tag = static_cast<SerializationTag>(m_buffer[m_position++]); 849d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 850d0825bca7fe65beaee391d30da42e937db621564Steve Block } 851d0825bca7fe65beaee391d30da42e937db621564Steve Block 852d0825bca7fe65beaee391d30da42e937db621564Steve Block bool readString(v8::Handle<v8::Value>* value) 853d0825bca7fe65beaee391d30da42e937db621564Steve Block { 854d0825bca7fe65beaee391d30da42e937db621564Steve Block uint32_t length; 855d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!doReadUint32(&length)) 856d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 857d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_position + length > m_length) 858d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 859dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length); 860dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_position += length; 861dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 862dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 863dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 864dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readWebCoreString(String* string) 865dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 866dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t length; 867dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&length)) 868dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 869dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_position + length > m_length) 870dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 871dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length); 872d0825bca7fe65beaee391d30da42e937db621564Steve Block m_position += length; 873d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 874d0825bca7fe65beaee391d30da42e937db621564Steve Block } 875d0825bca7fe65beaee391d30da42e937db621564Steve Block 876d0825bca7fe65beaee391d30da42e937db621564Steve Block bool readInt32(v8::Handle<v8::Value>* value) 877d0825bca7fe65beaee391d30da42e937db621564Steve Block { 878d0825bca7fe65beaee391d30da42e937db621564Steve Block uint32_t rawValue; 879d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!doReadUint32(&rawValue)) 880d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 881d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue))); 882d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 883d0825bca7fe65beaee391d30da42e937db621564Steve Block } 884d0825bca7fe65beaee391d30da42e937db621564Steve Block 885dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readUint32(v8::Handle<v8::Value>* value) 886d0825bca7fe65beaee391d30da42e937db621564Steve Block { 887dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t rawValue; 888dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&rawValue)) 889dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 890f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch *value = v8::Integer::NewFromUnsigned(rawValue); 891dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 892dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 893dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 894dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readDate(v8::Handle<v8::Value>* value) 895dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 896dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block double numberValue; 897dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadNumber(&numberValue)) 898d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 899dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = v8::Date::New(numberValue); 900dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 901dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 902dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 903dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readNumber(v8::Handle<v8::Value>* value) 904dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 905d0825bca7fe65beaee391d30da42e937db621564Steve Block double number; 906dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadNumber(&number)) 907dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 908d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = v8::Number::New(number); 909d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 910d0825bca7fe65beaee391d30da42e937db621564Steve Block } 911d0825bca7fe65beaee391d30da42e937db621564Steve Block 912dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readImageData(v8::Handle<v8::Value>* value) 913dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 914dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t width; 915dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t height; 916dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t pixelDataLength; 917dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&width)) 918dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 919dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&height)) 920dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 921dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&pixelDataLength)) 922dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 923dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_position + pixelDataLength > m_length) 924dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 925cad810f21b803229eb11403f9209855525a25d57Steve Block RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); 926dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block WTF::ByteArray* pixelArray = imageData->data()->data(); 927dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(pixelArray); 928dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(pixelArray->length() >= pixelDataLength); 929dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); 930dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_position += pixelDataLength; 931cad810f21b803229eb11403f9209855525a25d57Steve Block *value = toV8(imageData.release()); 932dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 933dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 93481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 935e14391e94c850b8bd03680c23b38978db68687a8John Reck bool readRegExp(v8::Handle<v8::Value>* value) 936e14391e94c850b8bd03680c23b38978db68687a8John Reck { 937e14391e94c850b8bd03680c23b38978db68687a8John Reck v8::Handle<v8::Value> pattern; 938e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!readString(&pattern)) 939e14391e94c850b8bd03680c23b38978db68687a8John Reck return false; 940e14391e94c850b8bd03680c23b38978db68687a8John Reck uint32_t flags; 941e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!doReadUint32(&flags)) 942e14391e94c850b8bd03680c23b38978db68687a8John Reck return false; 943e14391e94c850b8bd03680c23b38978db68687a8John Reck *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags)); 944e14391e94c850b8bd03680c23b38978db68687a8John Reck return true; 945e14391e94c850b8bd03680c23b38978db68687a8John Reck } 946dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 947dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readBlob(v8::Handle<v8::Value>* value) 948dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 949f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick String url; 950f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick String type; 951f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick uint64_t size; 952f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!readWebCoreString(&url)) 953f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return false; 954f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!readWebCoreString(&type)) 955dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 956f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!doReadUint64(&size)) 957f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return false; 95868513a70bcd92384395513322f1b801e7bf9c729Steve Block PassRefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, size); 959dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = toV8(blob); 960dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 961dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 962dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 963dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readFile(v8::Handle<v8::Value>* value) 964dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 965dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block String path; 966f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick String url; 967f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick String type; 968dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readWebCoreString(&path)) 969dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 970f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!readWebCoreString(&url)) 971f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return false; 972f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!readWebCoreString(&type)) 973f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return false; 97468513a70bcd92384395513322f1b801e7bf9c729Steve Block PassRefPtr<File> file = File::create(path, KURL(ParsedURLString, url), type); 975dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = toV8(file); 976dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 977dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 978dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 979dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool readFileList(v8::Handle<v8::Value>* value) 980dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 981dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint32_t length; 982dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!doReadUint32(&length)) 983dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 984dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PassRefPtr<FileList> fileList = FileList::create(); 985dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (unsigned i = 0; i < length; ++i) { 986dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block String path; 987f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick String urlString; 988f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick String type; 989dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!readWebCoreString(&path)) 990dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 991f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!readWebCoreString(&urlString)) 992f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return false; 993f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!readWebCoreString(&type)) 994f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return false; 99568513a70bcd92384395513322f1b801e7bf9c729Steve Block fileList->append(File::create(path, KURL(ParsedURLString, urlString), type)); 996dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 997dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = toV8(fileList); 998dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 999dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1000dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1001f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick template<class T> 1002f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick bool doReadUintHelper(T* value) 1003d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1004d0825bca7fe65beaee391d30da42e937db621564Steve Block *value = 0; 1005dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint8_t currentByte; 1006d0825bca7fe65beaee391d30da42e937db621564Steve Block int shift = 0; 1007d0825bca7fe65beaee391d30da42e937db621564Steve Block do { 1008d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_position >= m_length) 1009d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1010d0825bca7fe65beaee391d30da42e937db621564Steve Block currentByte = m_buffer[m_position++]; 1011d0825bca7fe65beaee391d30da42e937db621564Steve Block *value |= ((currentByte & varIntMask) << shift); 1012d0825bca7fe65beaee391d30da42e937db621564Steve Block shift += varIntShift; 1013d0825bca7fe65beaee391d30da42e937db621564Steve Block } while (currentByte & (1 << varIntShift)); 1014d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 1015d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1016d0825bca7fe65beaee391d30da42e937db621564Steve Block 1017f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick bool doReadUint32(uint32_t* value) 1018f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick { 1019f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return doReadUintHelper(value); 1020f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 1021f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 1022f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick bool doReadUint64(uint64_t* value) 1023f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick { 1024f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return doReadUintHelper(value); 1025f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 1026f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 1027dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool doReadNumber(double* number) 1028dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1029dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_position + sizeof(double) > m_length) 1030dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 1031dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); 1032dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (unsigned i = 0; i < sizeof(double); ++i) 1033dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block numberAsByteArray[i] = m_buffer[m_position++]; 1034dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 1035dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1036dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1037dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block const uint8_t* m_buffer; 1038d0825bca7fe65beaee391d30da42e937db621564Steve Block const unsigned m_length; 1039d0825bca7fe65beaee391d30da42e937db621564Steve Block unsigned m_position; 1040d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 1041d0825bca7fe65beaee391d30da42e937db621564Steve Block 1042dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass Deserializer : public CompositeCreator { 1043d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic: 1044dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block explicit Deserializer(Reader& reader) 1045dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : m_reader(reader) 1046d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1047d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1048d0825bca7fe65beaee391d30da42e937db621564Steve Block 1049dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Handle<v8::Value> deserialize() 1050d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1051d0825bca7fe65beaee391d30da42e937db621564Steve Block v8::HandleScope scope; 1052d0825bca7fe65beaee391d30da42e937db621564Steve Block while (!m_reader.isEof()) { 1053d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!doDeserialize()) 1054dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return v8::Null(); 1055d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1056d0825bca7fe65beaee391d30da42e937db621564Steve Block if (stackDepth() != 1) 1057dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return v8::Null(); 1058d0825bca7fe65beaee391d30da42e937db621564Steve Block return scope.Close(element(0)); 1059d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1060d0825bca7fe65beaee391d30da42e937db621564Steve Block 1061dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) 1062dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1063dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (length > stackDepth()) 1064dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 1065dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Array> array = v8::Array::New(length); 1066dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (array.IsEmpty()) 1067dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 1068dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block const int depth = stackDepth() - length; 1069dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (unsigned i = 0; i < length; ++i) 1070dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block array->Set(i, element(depth + i)); 1071dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pop(length); 1072dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = array; 1073dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 1074dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1075dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1076dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) 1077dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1078dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Object> object = v8::Object::New(); 1079dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (object.IsEmpty()) 1080dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 1081dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return initializeObject(object, numProperties, value); 1082dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1083dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1084dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) 1085dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1086dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Array> array = v8::Array::New(length); 1087dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (array.IsEmpty()) 1088dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 1089dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return initializeObject(array, numProperties, value); 1090dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1091dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1092d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate: 1093dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value) 1094dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1095dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block unsigned length = 2 * numProperties; 1096dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (length > stackDepth()) 1097dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 1098dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { 1099dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Value> propertyName = element(i); 1100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block v8::Local<v8::Value> propertyValue = element(i + 1); 1101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block object->Set(propertyName, propertyValue); 1102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pop(length); 1104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *value = object; 1105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 1106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1108d0825bca7fe65beaee391d30da42e937db621564Steve Block bool doDeserialize() 1109d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1110d0825bca7fe65beaee391d30da42e937db621564Steve Block v8::Local<v8::Value> value; 1111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!m_reader.read(&value, *this)) 1112d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!value.IsEmpty()) 1114d0825bca7fe65beaee391d30da42e937db621564Steve Block push(value); 1115d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 1116d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1117d0825bca7fe65beaee391d30da42e937db621564Steve Block 1118d0825bca7fe65beaee391d30da42e937db621564Steve Block void push(v8::Local<v8::Value> value) { m_stack.append(value); } 1119d0825bca7fe65beaee391d30da42e937db621564Steve Block 1120d0825bca7fe65beaee391d30da42e937db621564Steve Block void pop(unsigned length) 1121d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1122d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(length <= m_stack.size()); 1123d0825bca7fe65beaee391d30da42e937db621564Steve Block m_stack.shrink(m_stack.size() - length); 1124d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1125d0825bca7fe65beaee391d30da42e937db621564Steve Block 1126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block unsigned stackDepth() const { return m_stack.size(); } 1127d0825bca7fe65beaee391d30da42e937db621564Steve Block 1128d0825bca7fe65beaee391d30da42e937db621564Steve Block v8::Local<v8::Value> element(unsigned index) 1129d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1130d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(index < m_stack.size()); 1131d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_stack[index]; 1132d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1133d0825bca7fe65beaee391d30da42e937db621564Steve Block 1134d0825bca7fe65beaee391d30da42e937db621564Steve Block Reader& m_reader; 1135d0825bca7fe65beaee391d30da42e937db621564Steve Block Vector<v8::Local<v8::Value> > m_stack; 1136d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 1137d0825bca7fe65beaee391d30da42e937db621564Steve Block 1138d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace 1139d0825bca7fe65beaee391d30da42e937db621564Steve Block 1140545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid SerializedScriptValue::deserializeAndSetProperty(v8::Handle<v8::Object> object, const char* propertyName, 1141545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch v8::PropertyAttribute attribute, SerializedScriptValue* value) 1142545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 1143545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!value) 1144545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return; 1145545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch v8::Handle<v8::Value> deserialized = value->deserialize(); 1146545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch object->ForceSet(v8::String::NewSymbol(propertyName), deserialized, attribute); 1147545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1148545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 114981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid SerializedScriptValue::deserializeAndSetProperty(v8::Handle<v8::Object> object, const char* propertyName, 115081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch v8::PropertyAttribute attribute, PassRefPtr<SerializedScriptValue> value) 115181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 115281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch deserializeAndSetProperty(object, propertyName, attribute, value.get()); 115381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 115481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1155545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, bool& didThrow) 1156545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 1157545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return adoptRef(new SerializedScriptValue(value, didThrow)); 1158545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1159545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1160545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value) 1161545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 1162545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch bool didThrow; 1163545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return adoptRef(new SerializedScriptValue(value, didThrow)); 1164545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1165545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1166545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(String data) 1167545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 11682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return adoptRef(new SerializedScriptValue(data)); 1169545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1170545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1171545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(String data) 1172545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 11732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Writer writer; 11742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block writer.writeWebCoreString(data); 11752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block String wireData = StringImpl::adopt(writer.data()); 11762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return adoptRef(new SerializedScriptValue(wireData)); 1177545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1178545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1179545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create() 1180545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 1181545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return adoptRef(new SerializedScriptValue()); 1182545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1183545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1184ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochSerializedScriptValue* SerializedScriptValue::nullValue() 11855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 11862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, nullValue, (0)); 11872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!nullValue) { 11882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Writer writer; 11892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block writer.writeNull(); 11902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block String wireData = StringImpl::adopt(writer.data()); 11912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block nullValue = adoptRef(new SerializedScriptValue(wireData)); 11922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 11935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return nullValue.get(); 11945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 11955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1196ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochSerializedScriptValue* SerializedScriptValue::undefinedValue() 1197ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 11982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, undefinedValue, (0)); 11992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!undefinedValue) { 12002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Writer writer; 12012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block writer.writeUndefined(); 12022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block String wireData = StringImpl::adopt(writer.data()); 12032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block undefinedValue = adoptRef(new SerializedScriptValue(wireData)); 12042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1205ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return undefinedValue.get(); 1206ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 1207ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 1208545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::release() 1209545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 12102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data)); 1211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_data = String().crossThreadString(); 1212545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return result.release(); 1213545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1214545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1215545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochSerializedScriptValue::SerializedScriptValue() 1216545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 1217545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 1218545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockSerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, bool& didThrow) 1220d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 1221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block didThrow = false; 1222d0825bca7fe65beaee391d30da42e937db621564Steve Block Writer writer; 122381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Serializer::Status status; 122481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 122581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch v8::TryCatch tryCatch; 122681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Serializer serializer(writer, tryCatch); 122781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch status = serializer.serialize(value); 122881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (status == Serializer::JSException) { 122981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // If there was a JS exception thrown, re-throw it. 123081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch didThrow = true; 123181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch tryCatch.ReThrow(); 123281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return; 123381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 123481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 123581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (status == Serializer::InputError) { 123681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // If there was an input error, throw a new exception outside 123781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // of the TryCatch scope. 123881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch didThrow = true; 1239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block throwError(NOT_SUPPORTED_ERR); 124081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return; 124181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 124281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (status == Serializer::JSFailure) { 124381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // If there was a JS failure (but no exception), there's not 124481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // much we can do except for unwinding the C++ stack by 124581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // pretending there was a JS exception. 1246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block didThrow = true; 1247d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 1248d0825bca7fe65beaee391d30da42e937db621564Steve Block } 124981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(status == Serializer::Success); 1250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_data = String(StringImpl::adopt(writer.data())).crossThreadString(); 1251d0825bca7fe65beaee391d30da42e937db621564Steve Block} 1252d0825bca7fe65beaee391d30da42e937db621564Steve Block 12532fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockSerializedScriptValue::SerializedScriptValue(String wireData) 1254d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 12552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_data = wireData.crossThreadString(); 1256d0825bca7fe65beaee391d30da42e937db621564Steve Block} 1257d0825bca7fe65beaee391d30da42e937db621564Steve Block 1258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockv8::Handle<v8::Value> SerializedScriptValue::deserialize() 1259d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 1260d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!m_data.impl()) 1261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return v8::Null(); 1262d0825bca7fe65beaee391d30da42e937db621564Steve Block COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 1263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length()); 1264d0825bca7fe65beaee391d30da42e937db621564Steve Block Deserializer deserializer(reader); 1265d0825bca7fe65beaee391d30da42e937db621564Steve Block return deserializer.deserialize(); 1266d0825bca7fe65beaee391d30da42e937db621564Steve Block} 1267d0825bca7fe65beaee391d30da42e937db621564Steve Block 1268d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace WebCore 1269