const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey) { ASSERT(limit >= p); if (p >= limit) return 0; unsigned char type = *p++; switch (type) { case IDBKeyNullTypeByte: foundKey = IDBKey::createInvalid(); return p; case IDBKeyArrayTypeByte: { int64_t length; p = decodeVarInt(p, limit, length); if (!p) return 0; if (length < 0) return 0; IDBKey::KeyArray array; while (length--) { RefPtr<IDBKey> key; p = decodeIDBKey(p, limit, key); if (!p) return 0; array.append(key); } foundKey = IDBKey::createArray(array); return p; } case IDBKeyStringTypeByte: { String s; p = decodeStringWithLength(p, limit, s); if (!p) return 0; foundKey = IDBKey::createString(s); return p; } case IDBKeyDateTypeByte: { double d; p = decodeDouble(p, limit, &d); if (!p) return 0; foundKey = IDBKey::createDate(d); return p; } case IDBKeyNumberTypeByte: { double d; p = decodeDouble(p, limit, &d); if (!p) return 0; foundKey = IDBKey::createNumber(d); return p; } } ASSERT_NOT_REACHED(); return 0; }
static void convertToWebIDBKeyArray(const IDBKey::KeyArray& array, WebVector<WebIDBKey>& result) { WebVector<WebIDBKey> keys(array.size()); WebVector<WebIDBKey> subkeys; for (size_t i = 0; i < array.size(); ++i) { IDBKey* key = array[i]; switch (key->getType()) { case IDBKey::ArrayType: convertToWebIDBKeyArray(key->array(), subkeys); keys[i] = WebIDBKey::createArray(subkeys); break; case IDBKey::BinaryType: keys[i] = WebIDBKey::createBinary(key->binary()); break; case IDBKey::StringType: keys[i] = WebIDBKey::createString(key->string()); break; case IDBKey::DateType: keys[i] = WebIDBKey::createDate(key->date()); break; case IDBKey::NumberType: keys[i] = WebIDBKey::createNumber(key->number()); break; case IDBKey::InvalidType: keys[i] = WebIDBKey::createInvalid(); break; case IDBKey::MinType: ASSERT_NOT_REACHED(); break; } } result.swap(keys); }
static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vector<v8::Handle<v8::Array> >& stack, v8::Isolate* isolate) { if (value->IsNumber() && !std::isnan(value->NumberValue())) return IDBKey::createNumber(value->NumberValue()); if (value->IsString()) return IDBKey::createString(toCoreString(value.As<v8::String>())); if (value->IsDate() && !std::isnan(value->NumberValue())) return IDBKey::createDate(value->NumberValue()); if (value->IsArray()) { v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); if (stack.contains(array)) return 0; if (stack.size() >= maximumDepth) return 0; stack.append(array); IDBKey::KeyArray subkeys; uint32_t length = array->Length(); for (uint32_t i = 0; i < length; ++i) { v8::Local<v8::Value> item = array->Get(v8::Int32::New(i, isolate)); RefPtr<IDBKey> subkey = createIDBKeyFromValue(item, stack, isolate); if (!subkey) subkeys.append(IDBKey::createInvalid()); else subkeys.append(subkey); } stack.removeLast(); return IDBKey::createArray(subkeys); } return 0; }
static IDBKey* convertFromWebIDBKeyArray(const WebVector<WebIDBKey>& array) { IDBKey::KeyArray keys; keys.reserveCapacity(array.size()); for (size_t i = 0; i < array.size(); ++i) { switch (array[i].keyType()) { case WebIDBKeyTypeArray: keys.append(convertFromWebIDBKeyArray(array[i].array())); break; case WebIDBKeyTypeBinary: keys.append(IDBKey::createBinary(array[i].binary())); break; case WebIDBKeyTypeString: keys.append(IDBKey::createString(array[i].string())); break; case WebIDBKeyTypeDate: keys.append(IDBKey::createDate(array[i].date())); break; case WebIDBKeyTypeNumber: keys.append(IDBKey::createNumber(array[i].number())); break; case WebIDBKeyTypeInvalid: keys.append(IDBKey::createInvalid()); break; case WebIDBKeyTypeNull: case WebIDBKeyTypeMin: ASSERT_NOT_REACHED(); break; } } return IDBKey::createArray(keys); }
static PassRefPtr<IDBKey> idbKeyFromInspectorObject(InspectorObject* key) { RefPtr<IDBKey> idbKey; String type; if (!key->getString("type", &type)) return 0; DEFINE_STATIC_LOCAL(String, number, ("number")); DEFINE_STATIC_LOCAL(String, string, ("string")); DEFINE_STATIC_LOCAL(String, date, ("date")); DEFINE_STATIC_LOCAL(String, array, ("array")); if (type == number) { double number; if (!key->getNumber("number", &number)) return 0; idbKey = IDBKey::createNumber(number); } else if (type == string) { String string; if (!key->getString("string", &string)) return 0; idbKey = IDBKey::createString(string); } else if (type == date) { double date; if (!key->getNumber("date", &date)) return 0; idbKey = IDBKey::createDate(date); } else if (type == array) { IDBKey::KeyArray keyArray; RefPtr<InspectorArray> array = key->getArray("array"); for (size_t i = 0; i < array->length(); ++i) { RefPtr<InspectorValue> value = array->get(i); RefPtr<InspectorObject> object; if (!value->asObject(&object)) return 0; keyArray.append(idbKeyFromInspectorObject(object.get())); } idbKey = IDBKey::createArray(keyArray); } else return 0; return idbKey.release(); }
static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolate, const ScriptValue& value, const IDBKeyPath& keyPath, bool allowExperimentalTypes = false) { ASSERT(!keyPath.isNull()); v8::HandleScope handleScope(isolate); if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); ++i) { IDBKey* key = createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, array[i], allowExperimentalTypes); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath.string(), allowExperimentalTypes); }
static PassRefPtr<Key> keyFromIDBKey(IDBKey* idbKey) { if (!idbKey || !idbKey->isValid()) return 0; RefPtr<Key> key; switch (idbKey->type()) { case IDBKey::InvalidType: case IDBKey::MinType: return 0; case IDBKey::NumberType: { RefPtr<Key> tmpKey = Key::create().setType(Key::Type::Number); key = tmpKey; key->setNumber(idbKey->number()); break; } case IDBKey::StringType: { RefPtr<Key> tmpKey = Key::create().setType(Key::Type::String); key = tmpKey; key->setString(idbKey->string()); break; } case IDBKey::DateType: { RefPtr<Key> tmpKey = Key::create().setType(Key::Type::Date); key = tmpKey; key->setDate(idbKey->date()); break; } case IDBKey::ArrayType: { RefPtr<Key> tmpKey = Key::create().setType(Key::Type::Array); key = tmpKey; RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::Key> > array = TypeBuilder::Array<TypeBuilder::IndexedDB::Key>::create(); IDBKey::KeyArray keyArray = idbKey->array(); for (size_t i = 0; i < keyArray.size(); ++i) array->addItem(keyFromIDBKey(keyArray[i].get())); key->setArray(array); break; } } return key.release(); }
static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value> value, Vector<v8::Handle<v8::Array> >& stack, bool allowExperimentalTypes = false) { if (value->IsNumber() && !std::isnan(value->NumberValue())) return IDBKey::createNumber(value->NumberValue()); if (value->IsString()) return IDBKey::createString(toCoreString(value.As<v8::String>())); if (value->IsDate() && !std::isnan(value->NumberValue())) return IDBKey::createDate(value->NumberValue()); if (value->IsUint8Array() && (allowExperimentalTypes || RuntimeEnabledFeatures::indexedDBExperimentalEnabled())) { // Per discussion in https://www.w3.org/Bugs/Public/show_bug.cgi?id=23332 the // input type is constrained to Uint8Array to match the output type. ArrayBufferView* view = blink::V8ArrayBufferView::toImpl(value->ToObject()); const char* start = static_cast<const char*>(view->baseAddress()); size_t length = view->byteLength(); return IDBKey::createBinary(SharedBuffer::create(start, length)); } if (value->IsArray()) { v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); if (stack.contains(array)) return 0; if (stack.size() >= maximumDepth) return 0; stack.append(array); IDBKey::KeyArray subkeys; uint32_t length = array->Length(); for (uint32_t i = 0; i < length; ++i) { v8::Local<v8::Value> item = array->Get(v8::Int32::New(isolate, i)); IDBKey* subkey = createIDBKeyFromValue(isolate, item, stack, allowExperimentalTypes); if (!subkey) subkeys.append(IDBKey::createInvalid()); else subkeys.append(subkey); } stack.removeLast(); return IDBKey::createArray(subkeys); } return 0; }
PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState* state, const ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent(); ASSERT(isolate->InContext()); v8::HandleScope handleScope(isolate); if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); ++i) { RefPtr<IDBKey> key = createIDBKeyFromScriptValueAndKeyPath(value, array[i], isolate); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string(), isolate); }
PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState* requestState, const ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); ExecState* exec = requestState->exec(); if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); i++) { RefPtr<IDBKey> key = createIDBKeyFromScriptValueAndKeyPath(exec, value, array[i]); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath.string()); }
PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromSerializedValueAndKeyPath"); ASSERT(!keyPath.isNull()); RefPtr<SerializedScriptValue> value = prpValue; if (keyPath.type() == IDBKeyPath::ArrayType) { IDBKey::KeyArray result; const Vector<String>& array = keyPath.array(); for (size_t i = 0; i < array.size(); ++i) { RefPtr<IDBKey> key = createIDBKeyFromSerializedValueAndKeyPath(value, array[i]); if (!key) return 0; result.append(key); } return IDBKey::createArray(result); } ASSERT(keyPath.type() == IDBKeyPath::StringType); return createIDBKeyFromSerializedValueAndKeyPath(value, keyPath.string()); }
static PassRefPtr<IDBKey> createIDBKeyFromValue(ExecState* exec, JSValue value, Vector<JSArray*>& stack) { if (value.isNumber() && !std::isnan(value.toNumber(exec))) return IDBKey::createNumber(value.toNumber(exec)); if (value.isString()) return IDBKey::createString(value.toString(exec)->value(exec)); if (value.inherits(&DateInstance::s_info) && !std::isnan(valueToDate(exec, value))) return IDBKey::createDate(valueToDate(exec, value)); if (value.isObject()) { JSObject* object = asObject(value); if (isJSArray(object) || object->inherits(&JSArray::s_info)) { JSArray* array = asArray(object); size_t length = array->length(); if (stack.contains(array)) return 0; if (stack.size() >= maximumDepth) return 0; stack.append(array); IDBKey::KeyArray subkeys; for (size_t i = 0; i < length; i++) { JSValue item = array->getIndex(exec, i); RefPtr<IDBKey> subkey = createIDBKeyFromValue(exec, item, stack); if (!subkey) subkeys.append(IDBKey::createInvalid()); else subkeys.append(subkey); } stack.removeLast(); return IDBKey::createArray(subkeys); } } return 0; }