// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_ #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_ #include #include "base/basictypes.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "content/common/indexed_db/indexed_db_key.h" #include "content/common/indexed_db/indexed_db_key_path.h" namespace content { CONTENT_EXPORT extern const unsigned char kMinimumIndexId; CONTENT_EXPORT std::string MaxIDBKey(); CONTENT_EXPORT std::string MinIDBKey(); CONTENT_EXPORT void EncodeByte(unsigned char value, std::string* into); CONTENT_EXPORT void EncodeBool(bool value, std::string* into); CONTENT_EXPORT void EncodeInt(int64 value, std::string* into); CONTENT_EXPORT void EncodeVarInt(int64 value, std::string* into); CONTENT_EXPORT void EncodeString(const base::string16& value, std::string* into); CONTENT_EXPORT void EncodeStringWithLength(const base::string16& value, std::string* into); CONTENT_EXPORT void EncodeBinary(const std::string& value, std::string* into); CONTENT_EXPORT void EncodeDouble(double value, std::string* into); CONTENT_EXPORT void EncodeIDBKey(const IndexedDBKey& value, std::string* into); CONTENT_EXPORT void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeByte(base::StringPiece* slice, unsigned char* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBool(base::StringPiece* slice, bool* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeInt(base::StringPiece* slice, int64* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeVarInt(base::StringPiece* slice, int64* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeString(base::StringPiece* slice, base::string16* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeStringWithLength( base::StringPiece* slice, base::string16* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBinary(base::StringPiece* slice, std::string* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeDouble(base::StringPiece* slice, double* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKey( base::StringPiece* slice, scoped_ptr* value); CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKeyPath( base::StringPiece* slice, IndexedDBKeyPath* value); CONTENT_EXPORT int CompareEncodedStringsWithLength(base::StringPiece* slice1, base::StringPiece* slice2, bool* ok); CONTENT_EXPORT WARN_UNUSED_RESULT bool ExtractEncodedIDBKey( base::StringPiece* slice, std::string* result); CONTENT_EXPORT int CompareEncodedIDBKeys(const std::string& a, const std::string& b, bool* ok); CONTENT_EXPORT int Compare(const base::StringPiece& a, const base::StringPiece& b, bool index_keys); class KeyPrefix { public: KeyPrefix(); explicit KeyPrefix(int64 database_id); KeyPrefix(int64 database_id, int64 object_store_id); KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id); static KeyPrefix CreateWithSpecialIndex(int64 database_id, int64 object_store_id, int64 index_id); static bool Decode(base::StringPiece* slice, KeyPrefix* result); std::string Encode() const; static std::string EncodeEmpty(); int Compare(const KeyPrefix& other) const; enum Type { GLOBAL_METADATA, DATABASE_METADATA, OBJECT_STORE_DATA, EXISTS_ENTRY, INDEX_DATA, INVALID_TYPE }; static const size_t kMaxDatabaseIdSizeBits = 3; static const size_t kMaxObjectStoreIdSizeBits = 3; static const size_t kMaxIndexIdSizeBits = 2; static const size_t kMaxDatabaseIdSizeBytes = 1ULL << kMaxDatabaseIdSizeBits; // 8 static const size_t kMaxObjectStoreIdSizeBytes = 1ULL << kMaxObjectStoreIdSizeBits; // 8 static const size_t kMaxIndexIdSizeBytes = 1ULL << kMaxIndexIdSizeBits; // 4 static const size_t kMaxDatabaseIdBits = kMaxDatabaseIdSizeBytes * 8 - 1; // 63 static const size_t kMaxObjectStoreIdBits = kMaxObjectStoreIdSizeBytes * 8 - 1; // 63 static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1; // 31 static const int64 kMaxDatabaseId = (1ULL << kMaxDatabaseIdBits) - 1; // max signed int64 static const int64 kMaxObjectStoreId = (1ULL << kMaxObjectStoreIdBits) - 1; // max signed int64 static const int64 kMaxIndexId = (1ULL << kMaxIndexIdBits) - 1; // max signed int32 static bool IsValidDatabaseId(int64 database_id); static bool IsValidObjectStoreId(int64 index_id); static bool IsValidIndexId(int64 index_id); static bool ValidIds(int64 database_id, int64 object_store_id, int64 index_id) { return IsValidDatabaseId(database_id) && IsValidObjectStoreId(object_store_id) && IsValidIndexId(index_id); } static bool ValidIds(int64 database_id, int64 object_store_id) { return IsValidDatabaseId(database_id) && IsValidObjectStoreId(object_store_id); } Type type() const; int64 database_id_; int64 object_store_id_; int64 index_id_; static const int64 kInvalidId = -1; private: static std::string EncodeInternal(int64 database_id, int64 object_store_id, int64 index_id); // Special constructor for CreateWithSpecialIndex() KeyPrefix(enum Type, int64 database_id, int64 object_store_id, int64 index_id); }; class SchemaVersionKey { public: CONTENT_EXPORT static std::string Encode(); }; class MaxDatabaseIdKey { public: CONTENT_EXPORT static std::string Encode(); }; class DataVersionKey { public: static std::string Encode(); }; class DatabaseFreeListKey { public: DatabaseFreeListKey(); static bool Decode(base::StringPiece* slice, DatabaseFreeListKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id); static CONTENT_EXPORT std::string EncodeMaxKey(); int64 DatabaseId() const; int Compare(const DatabaseFreeListKey& other) const; private: int64 database_id_; }; class DatabaseNameKey { public: static bool Decode(base::StringPiece* slice, DatabaseNameKey* result); CONTENT_EXPORT static std::string Encode(const std::string& origin_identifier, const base::string16& database_name); static std::string EncodeMinKeyForOrigin( const std::string& origin_identifier); static std::string EncodeStopKeyForOrigin( const std::string& origin_identifier); base::string16 origin() const { return origin_; } base::string16 database_name() const { return database_name_; } int Compare(const DatabaseNameKey& other); private: base::string16 origin_; // TODO(jsbell): Store encoded strings, or just // pointers. base::string16 database_name_; }; class DatabaseMetaDataKey { public: enum MetaDataType { ORIGIN_NAME = 0, DATABASE_NAME = 1, USER_VERSION = 2, MAX_OBJECT_STORE_ID = 3, USER_INT_VERSION = 4, MAX_SIMPLE_METADATA_TYPE = 5 }; CONTENT_EXPORT static std::string Encode(int64 database_id, MetaDataType type); }; class ObjectStoreMetaDataKey { public: enum MetaDataType { NAME = 0, KEY_PATH = 1, AUTO_INCREMENT = 2, EVICTABLE = 3, LAST_VERSION = 4, MAX_INDEX_ID = 5, HAS_KEY_PATH = 6, KEY_GENERATOR_CURRENT_NUMBER = 7 }; ObjectStoreMetaDataKey(); static bool Decode(base::StringPiece* slice, ObjectStoreMetaDataKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id, unsigned char meta_data_type); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, int64 object_store_id); int64 ObjectStoreId() const; unsigned char MetaDataType() const; int Compare(const ObjectStoreMetaDataKey& other); private: int64 object_store_id_; unsigned char meta_data_type_; }; class IndexMetaDataKey { public: enum MetaDataType { NAME = 0, UNIQUE = 1, KEY_PATH = 2, MULTI_ENTRY = 3 }; IndexMetaDataKey(); static bool Decode(base::StringPiece* slice, IndexMetaDataKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id, int64 index_id, unsigned char meta_data_type); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, int64 object_store_id); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, int64 object_store_id, int64 index_id); int Compare(const IndexMetaDataKey& other); int64 IndexId() const; unsigned char meta_data_type() const { return meta_data_type_; } private: int64 object_store_id_; int64 index_id_; unsigned char meta_data_type_; }; class ObjectStoreFreeListKey { public: ObjectStoreFreeListKey(); static bool Decode(base::StringPiece* slice, ObjectStoreFreeListKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id); int64 ObjectStoreId() const; int Compare(const ObjectStoreFreeListKey& other); private: int64 object_store_id_; }; class IndexFreeListKey { public: IndexFreeListKey(); static bool Decode(base::StringPiece* slice, IndexFreeListKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id, int64 index_id); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, int64 object_store_id); int Compare(const IndexFreeListKey& other); int64 ObjectStoreId() const; int64 IndexId() const; private: int64 object_store_id_; int64 index_id_; }; class ObjectStoreNamesKey { public: // TODO(jsbell): We never use this to look up object store ids, // because a mapping is kept in the IndexedDBDatabase. Can the // mapping become unreliable? Can we remove this? static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result); CONTENT_EXPORT static std::string Encode( int64 database_id, const base::string16& object_store_name); int Compare(const ObjectStoreNamesKey& other); base::string16 object_store_name() const { return object_store_name_; } private: // TODO(jsbell): Store the encoded string, or just pointers to it. base::string16 object_store_name_; }; class IndexNamesKey { public: IndexNamesKey(); // TODO(jsbell): We never use this to look up index ids, because a mapping // is kept at a higher level. static bool Decode(base::StringPiece* slice, IndexNamesKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id, const base::string16& index_name); int Compare(const IndexNamesKey& other); base::string16 index_name() const { return index_name_; } private: int64 object_store_id_; base::string16 index_name_; }; class ObjectStoreDataKey { public: static bool Decode(base::StringPiece* slice, ObjectStoreDataKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id, const std::string encoded_user_key); static std::string Encode(int64 database_id, int64 object_store_id, const IndexedDBKey& user_key); int Compare(const ObjectStoreDataKey& other, bool* ok); scoped_ptr user_key() const; static const int64 kSpecialIndexNumber; ObjectStoreDataKey(); ~ObjectStoreDataKey(); private: std::string encoded_user_key_; }; class ExistsEntryKey { public: ExistsEntryKey(); ~ExistsEntryKey(); static bool Decode(base::StringPiece* slice, ExistsEntryKey* result); CONTENT_EXPORT static std::string Encode(int64 database_id, int64 object_store_id, const std::string& encoded_key); static std::string Encode(int64 database_id, int64 object_store_id, const IndexedDBKey& user_key); int Compare(const ExistsEntryKey& other, bool* ok); scoped_ptr user_key() const; static const int64 kSpecialIndexNumber; private: std::string encoded_user_key_; DISALLOW_COPY_AND_ASSIGN(ExistsEntryKey); }; class IndexDataKey { public: IndexDataKey(); ~IndexDataKey(); static bool Decode(base::StringPiece* slice, IndexDataKey* result); CONTENT_EXPORT static std::string Encode( int64 database_id, int64 object_store_id, int64 index_id, const std::string& encoded_user_key, const std::string& encoded_primary_key, int64 sequence_number); static std::string Encode(int64 database_id, int64 object_store_id, int64 index_id, const IndexedDBKey& user_key); static std::string Encode(int64 database_id, int64 object_store_id, int64 index_id, const IndexedDBKey& user_key, const IndexedDBKey& user_primary_key); static std::string EncodeMinKey(int64 database_id, int64 object_store_id, int64 index_id); CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, int64 object_store_id, int64 index_id); int Compare(const IndexDataKey& other, bool only_compare_index_keys, bool* ok); int64 DatabaseId() const; int64 ObjectStoreId() const; int64 IndexId() const; scoped_ptr user_key() const; scoped_ptr primary_key() const; private: int64 database_id_; int64 object_store_id_; int64 index_id_; std::string encoded_user_key_; std::string encoded_primary_key_; int64 sequence_number_; DISALLOW_COPY_AND_ASSIGN(IndexDataKey); }; } // namespace content #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_