15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/modules/v8/IDBBindingUtilities.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/SerializedScriptValue.h"
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Binding.h"
31f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8DOMStringList.h"
32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8HiddenValue.h"
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h"
34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/custom/V8Uint8ArrayCustom.h"
35f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBCursor.h"
36f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBCursorWithValue.h"
37f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBDatabase.h"
38f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBIndex.h"
39f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBKeyRange.h"
40f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBObjectStore.h"
41f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBRequest.h"
42f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8IDBTransaction.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/indexeddb/IDBKey.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/indexeddb/IDBKeyPath.h"
45c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "modules/indexeddb/IDBKeyRange.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/indexeddb/IDBTracing.h"
4776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "platform/RuntimeEnabledFeatures.h"
48a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/SharedBuffer.h"
4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/ArrayBufferView.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/MathExtras.h"
5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/Uint8Array.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Vector.h"
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatic v8::Handle<v8::Value> deserializeIDBValueBuffer(v8::Isolate*, SharedBuffer*, const Vector<blink::WebBlobInfo>*);
57a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
58a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static v8::Handle<v8::Value> toV8(const IDBKeyPath& value, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
59a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
60a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    switch (value.type()) {
61a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBKeyPath::NullType:
62a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Null(isolate);
63a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBKeyPath::StringType:
64a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8String(isolate, value.string());
65a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBKeyPath::ArrayType:
66323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        RefPtrWillBeRawPtr<DOMStringList> keyPaths = DOMStringList::create();
67a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        for (Vector<String>::const_iterator it = value.array().begin(); it != value.array().end(); ++it)
68a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            keyPaths->append(*it);
69a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(keyPaths.release(), creationContext, isolate);
70a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
71a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT_NOT_REACHED();
72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return v8::Undefined(isolate);
73a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
74a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static v8::Handle<v8::Value> toV8(const IDBKey* key, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!key) {
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // This should be undefined, not null.
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBKeyRange
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return v8Undefined();
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (key->type()) {
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case IDBKey::InvalidType:
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case IDBKey::MinType:
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT_NOT_REACHED();
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return v8Undefined();
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case IDBKey::NumberType:
898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return v8::Number::New(isolate, key->number());
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case IDBKey::StringType:
91a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8String(isolate, key->string());
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case IDBKey::BinaryType:
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return toV8(Uint8Array::create(reinterpret_cast<const unsigned char*>(key->binary()->data()), key->binary()->size()), creationContext, isolate);
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case IDBKey::DateType:
95a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Date::New(isolate, key->date());
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case IDBKey::ArrayType:
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        {
98a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            v8::Local<v8::Array> array = v8::Array::New(isolate, key->array().size());
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            for (size_t i = 0; i < key->array().size(); ++i)
100a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                array->Set(i, toV8(key->array()[i].get(), creationContext, isolate));
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return array;
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT_NOT_REACHED();
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return v8Undefined();
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
110a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
111a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!impl)
112a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Null(isolate);
113a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
114a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    switch (impl->type()) {
115a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::UndefinedType:
116a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Undefined(isolate);
117a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::NullType:
118a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Null(isolate);
119a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::DOMStringListType:
120a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->domStringList(), creationContext, isolate);
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case IDBAny::IDBCursorType: {
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // Ensure request wrapper is kept alive at least as long as the cursor wrapper,
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // so that event listeners are retained.
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        v8::Handle<v8::Value> cursor = toV8(impl->idbCursor(), creationContext, isolate);
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        v8::Handle<v8::Value> request = toV8(impl->idbCursor()->request(), creationContext, isolate);
126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(), V8HiddenValue::idbCursorRequest(isolate), request);
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return cursor;
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case IDBAny::IDBCursorWithValueType: {
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // Ensure request wrapper is kept alive at least as long as the cursor wrapper,
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // so that event listeners are retained.
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        v8::Handle<v8::Value> cursor = toV8(impl->idbCursorWithValue(), creationContext, isolate);
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        v8::Handle<v8::Value> request = toV8(impl->idbCursorWithValue()->request(), creationContext, isolate);
134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(), V8HiddenValue::idbCursorRequest(isolate), request);
13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return cursor;
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
137a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::IDBDatabaseType:
138a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->idbDatabase(), creationContext, isolate);
139a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::IDBIndexType:
140a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->idbIndex(), creationContext, isolate);
141a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::IDBObjectStoreType:
142a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->idbObjectStore(), creationContext, isolate);
143a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::IDBTransactionType:
144a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->idbTransaction(), creationContext, isolate);
145a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::BufferType:
146f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return deserializeIDBValueBuffer(isolate, impl->buffer(), impl->blobInfo());
147a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::StringType:
148a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8String(isolate, impl->string());
149a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::IntegerType:
150a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Number::New(isolate, impl->integer());
151a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::KeyType:
152a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->key(), creationContext, isolate);
153a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::KeyPathType:
154a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return toV8(impl->keyPath(), creationContext, isolate);
155a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case IDBAny::BufferKeyAndKeyPathType: {
156f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        v8::Handle<v8::Value> value = deserializeIDBValueBuffer(isolate, impl->buffer(), impl->blobInfo());
157a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Handle<v8::Value> key = toV8(impl->key(), creationContext, isolate);
1586f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        bool injected = injectV8KeyIntoV8Value(isolate, key, value, impl->keyPath());
159a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        ASSERT_UNUSED(injected, injected);
160a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return value;
161a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
162a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
163a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
164a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT_NOT_REACHED();
165a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return v8::Undefined(isolate);
166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
167a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const size_t maximumDepth = 2000;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
170d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value> value, Vector<v8::Handle<v8::Array> >& stack, bool allowExperimentalTypes = false)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (value->IsNumber() && !std::isnan(value->NumberValue()))
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IDBKey::createNumber(value->NumberValue());
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value->IsString())
17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return IDBKey::createString(toCoreString(value.As<v8::String>()));
176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (value->IsDate() && !std::isnan(value->NumberValue()))
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IDBKey::createDate(value->NumberValue());
17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (value->IsUint8Array() && (allowExperimentalTypes || RuntimeEnabledFeatures::indexedDBExperimentalEnabled())) {
17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // Per discussion in https://www.w3.org/Bugs/Public/show_bug.cgi?id=23332 the
18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // input type is constrained to Uint8Array to match the output type.
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ArrayBufferView* view = blink::V8ArrayBufferView::toImpl(value->ToObject());
18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        const char* start = static_cast<const char*>(view->baseAddress());
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        size_t length = view->byteLength();
18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return IDBKey::createBinary(SharedBuffer::create(start, length));
18509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value->IsArray()) {
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (stack.contains(array))
190d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            return 0;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (stack.size() >= maximumDepth)
192d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            return 0;
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stack.append(array);
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IDBKey::KeyArray subkeys;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        uint32_t length = array->Length();
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (uint32_t i = 0; i < length; ++i) {
19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            v8::Local<v8::Value> item = array->Get(v8::Int32::New(isolate, i));
199d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            IDBKey* subkey = createIDBKeyFromValue(isolate, item, stack, allowExperimentalTypes);
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!subkey)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                subkeys.append(IDBKey::createInvalid());
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                subkeys.append(subkey);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stack.removeLast();
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IDBKey::createArray(subkeys);
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
209d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return 0;
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
212d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value> value, bool allowExperimentalTypes = false)
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<v8::Handle<v8::Array> > stack;
215d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (IDBKey* key = createIDBKeyFromValue(isolate, value, stack, allowExperimentalTypes))
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return key;
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IDBKey::createInvalid();
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename T>
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value)
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Local<v8::Object> object = v8Value->ToObject();
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!object->Has(indexOrName))
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8Value = object->Get(indexOrName);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename T>
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool setValue(v8::Handle<v8::Value>& v8Object, T indexOrName, const v8::Handle<v8::Value>& v8Value)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Local<v8::Object> object = v8Object->ToObject();
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return object->Set(indexOrName, v8Value);
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2376f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochstatic bool get(v8::Isolate* isolate, v8::Handle<v8::Value>& object, const String& keyPathElement, v8::Handle<v8::Value>& result)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (object->IsString() && keyPathElement == "length") {
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int32_t length = v8::Handle<v8::String>::Cast(object)->Length();
2418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        result = v8::Number::New(isolate, length);
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
244a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return object->IsObject() && getValueFrom(v8String(isolate, keyPathElement), result);
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool canSet(v8::Handle<v8::Value>& object, const String& keyPathElement)
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return object->IsObject();
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochstatic bool set(v8::Isolate* isolate, v8::Handle<v8::Value>& object, const String& keyPathElement, const v8::Handle<v8::Value>& v8Value)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
254a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return canSet(object, keyPathElement) && setValue(object, v8String(isolate, keyPathElement), v8Value);
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2576f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochstatic v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Value> currentValue(rootValue);
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(index <= keyPathElements.size());
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < index; ++i) {
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        v8::Handle<v8::Value> parentValue(currentValue);
2636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (!get(isolate, parentValue, keyPathElements[i], currentValue))
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return v8Undefined();
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return currentValue;
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochstatic bool canInjectNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!rootValue->IsObject())
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Value> currentValue(rootValue);
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(index <= keyPathElements.size());
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < index; ++i) {
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        v8::Handle<v8::Value> parentValue(currentValue);
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String& keyPathElement = keyPathElements[i];
2816f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (!get(isolate, parentValue, keyPathElement, currentValue))
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return canSet(parentValue, keyPathElement);
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2886f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochstatic v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Value> currentValue(rootValue);
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(index <= keyPathElements.size());
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < index; ++i) {
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        v8::Handle<v8::Value> parentValue(currentValue);
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String& keyPathElement = keyPathElements[i];
2966f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (!get(isolate, parentValue, keyPathElement, currentValue)) {
29709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            v8::Handle<v8::Object> object = v8::Object::New(isolate);
2986f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            if (!set(isolate, parentValue, keyPathElement, object))
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return v8Undefined();
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            currentValue = object;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return currentValue;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
307d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolate, const ScriptValue& value, const String& keyPath, bool allowExperimentalTypes)
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> keyPathElements;
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBKeyPathParseError error;
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBParseKeyPath(keyPath, keyPathElements, error);
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(error == IDBKeyPathParseErrorNone);
313a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(isolate->InContext());
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3153464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(isolate);
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Value> v8Value(value.v8Value());
3176f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(isolate, v8Value, keyPathElements, keyPathElements.size()));
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (v8Key.IsEmpty())
319d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return 0;
3206f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return createIDBKeyFromValue(isolate, v8Key, allowExperimentalTypes);
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
323d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolate, const ScriptValue& value, const IDBKeyPath& keyPath, bool allowExperimentalTypes = false)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!keyPath.isNull());
3263464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(isolate);
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (keyPath.type() == IDBKeyPath::ArrayType) {
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IDBKey::KeyArray result;
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Vector<String>& array = keyPath.array();
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < array.size(); ++i) {
331d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            IDBKey* key = createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, array[i], allowExperimentalTypes);
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!key)
333d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                return 0;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.append(key);
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IDBKey::createArray(result);
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(keyPath.type() == IDBKeyPath::StringType);
3406f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath.string(), allowExperimentalTypes);
34109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
34209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
343d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)IDBKey* createIDBKeyFromScriptValueAndKeyPath(v8::Isolate* isolate, const ScriptValue& value, const IDBKeyPath& keyPath)
34409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
34509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath");
3466f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath);
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
349f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatic v8::Handle<v8::Value> deserializeIDBValueBuffer(v8::Isolate* isolate, SharedBuffer* buffer, const Vector<blink::WebBlobInfo>* blobInfo)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
351a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(isolate->InContext());
352a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!buffer)
353a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return v8::Null(isolate);
354a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
355a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // FIXME: The extra copy here can be eliminated by allowing SerializedScriptValue to take a raw const char* or const uint8_t*.
356a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    Vector<uint8_t> value;
357a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    value.append(buffer->data(), buffer->size());
358a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::createFromWireBytes(value);
359f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    return serializedValue->deserialize(isolate, 0, blobInfo);
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochbool injectV8KeyIntoV8Value(v8::Isolate* isolate, v8::Handle<v8::Value> key, v8::Handle<v8::Value> value, const IDBKeyPath& keyPath)
363926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
364a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    IDB_TRACE("injectIDBV8KeyIntoV8Value");
365a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(isolate->InContext());
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(keyPath.type() == IDBKeyPath::StringType);
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> keyPathElements;
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBKeyPathParseError error;
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(error == IDBKeyPathParseErrorNone);
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!keyPathElements.size())
374a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return false;
37551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3763464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(isolate);
3776f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(isolate, value, keyPathElements, keyPathElements.size() - 1));
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parent.IsEmpty())
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3816f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (!set(isolate, parent, keyPathElements.last(), key))
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3876f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochbool canInjectIDBKeyIntoScriptValue(v8::Isolate* isolate, const ScriptValue& scriptValue, const IDBKeyPath& keyPath)
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDB_TRACE("canInjectIDBKeyIntoScriptValue");
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(keyPath.type() == IDBKeyPath::StringType);
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> keyPathElements;
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBKeyPathParseError error;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(error == IDBKeyPathParseErrorNone);
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!keyPathElements.size())
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Value> v8Value(scriptValue.v8Value());
4006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return canInjectNthValueOnKeyPath(isolate, v8Value, keyPathElements, keyPathElements.size() - 1);
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
403d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ScriptValue idbAnyToScriptValue(ScriptState* scriptState, IDBAny* any)
404a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
4056f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    v8::Isolate* isolate = scriptState->isolate();
406a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    v8::HandleScope handleScope(isolate);
407d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    v8::Handle<v8::Value> v8Value(toV8(any, scriptState->context()->Global(), isolate));
408323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return ScriptValue(scriptState, v8Value);
409a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
410a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
411d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ScriptValue idbKeyToScriptValue(ScriptState* scriptState, IDBKey* key)
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4136f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    v8::Isolate* isolate = scriptState->isolate();
4143464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(isolate);
415d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    v8::Handle<v8::Value> v8Value(toV8(key, scriptState->context()->Global(), isolate));
416323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return ScriptValue(scriptState, v8Value);
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
419d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)IDBKey* scriptValueToIDBKey(v8::Isolate* isolate, const ScriptValue& scriptValue)
420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
421a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(isolate->InContext());
4223464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(isolate);
423926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    v8::Handle<v8::Value> v8Value(scriptValue.v8Value());
4246f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return createIDBKeyFromValue(isolate, v8Value);
425926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
426926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
427d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)IDBKeyRange* scriptValueToIDBKeyRange(v8::Isolate* isolate, const ScriptValue& scriptValue)
428c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
429c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    v8::HandleScope handleScope(isolate);
430c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    v8::Handle<v8::Value> value(scriptValue.v8Value());
4317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return V8IDBKeyRange::toImplWithTypeCheck(isolate, value);
432c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
433c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
434197021e6b966cfb06891637935ef33fff06433d1Ben MurdochScriptValue deserializeScriptValue(ScriptState* scriptState, SerializedScriptValue* serializedValue, const Vector<blink::WebBlobInfo>* blobInfo)
435197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
436197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::Isolate* isolate = scriptState->isolate();
437197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::HandleScope handleScope(isolate);
438197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (serializedValue)
439197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return ScriptValue(scriptState, serializedValue->deserialize(isolate, 0, blobInfo));
440197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return ScriptValue(scriptState, v8::Null(isolate));
441197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
442197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
443197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
444d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void assertPrimaryKeyValidOrInjectable(ScriptState* scriptState, PassRefPtr<SharedBuffer> buffer, const Vector<blink::WebBlobInfo>* blobInfo, IDBKey* key, const IDBKeyPath& keyPath)
445a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
446f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    ScriptState::Scope scope(scriptState);
4476f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    v8::Isolate* isolate = scriptState->isolate();
4486f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ScriptValue keyValue = idbKeyToScriptValue(scriptState, key);
449323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    ScriptValue scriptValue(scriptState, deserializeIDBValueBuffer(isolate, buffer.get(), blobInfo));
450a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
45109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // This assertion is about already persisted data, so allow experimental types.
45209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const bool allowExperimentalTypes = true;
453d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    IDBKey* expectedKey = createIDBKeyFromScriptValueAndKeyPathInternal(isolate, scriptValue, keyPath, allowExperimentalTypes);
454d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ASSERT(!expectedKey || expectedKey->isEqual(key));
455a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
4566f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptValue.v8Value(), keyPath);
457a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT_UNUSED(injected, injected);
458a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
459a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#endif
460a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
461c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
462