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; }
const char* DatabaseNameKey::decode(const char* start, const char* limit, DatabaseNameKey* result) { KeyPrefix prefix; const char* p = KeyPrefix::decode(start, limit, &prefix); if (!p) return p; ASSERT(!prefix.m_databaseId); ASSERT(!prefix.m_objectStoreId); ASSERT(!prefix.m_indexId); if (p == limit) return 0; unsigned char typeByte = *p++; ASSERT_UNUSED(typeByte, typeByte == kDatabaseNameTypeByte); if (p == limit) return 0; p = decodeStringWithLength(p, limit, result->m_origin); if (!p) return 0; return decodeStringWithLength(p, limit, result->m_databaseName); }
IDBKeyPath decodeIDBKeyPath(const char* p, const char* limit) { // May be typed, or may be a raw string. An invalid leading // byte sequence is used to identify typed coding. New records are // always written as typed. if (p == limit || (limit - p >= 2 && (*p != IDBKeyPathTypeCodedByte1 || *(p + 1) != IDBKeyPathTypeCodedByte2))) return IDBKeyPath(decodeString(p, limit)); p += 2; ASSERT(p != limit); IDBKeyPath::Type type = static_cast<IDBKeyPath::Type>(*p++); switch (type) { case IDBKeyPath::NullType: ASSERT(p == limit); return IDBKeyPath(); case IDBKeyPath::StringType: { String string; p = decodeStringWithLength(p, limit, string); ASSERT(p == limit); return IDBKeyPath(string); } case IDBKeyPath::ArrayType: { Vector<String> array; int64_t count; p = decodeVarInt(p, limit, count); ASSERT(p); ASSERT(count >= 0); while (count--) { String string; p = decodeStringWithLength(p, limit, string); ASSERT(p); array.append(string); } ASSERT(p == limit); return IDBKeyPath(array); } } ASSERT_NOT_REACHED(); return IDBKeyPath(); }
// FIXME: We never use this to look up object store ids, because a mapping // is kept in the IDBDatabaseBackendImpl. Can the mapping become unreliable? // Can we remove this? const char* ObjectStoreNamesKey::decode(const char* start, const char* limit, ObjectStoreNamesKey* result) { KeyPrefix prefix; const char* p = KeyPrefix::decode(start, limit, &prefix); if (!p) return 0; ASSERT(prefix.m_databaseId); ASSERT(!prefix.m_objectStoreId); ASSERT(!prefix.m_indexId); if (p == limit) return 0; unsigned char typeByte = 0; p = decodeByte(p, limit, typeByte); ASSERT_UNUSED(typeByte, typeByte == ObjectStoreNamesTypeByte); return decodeStringWithLength(p, limit, result->m_objectStoreName); }