chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h

// Copyright 2013 The Chromium Authors
// 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 <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "components/services/storage/indexed_db/locks/partitioned_lock_id.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h"

namespace content {

namespace indexed_db {
// 0 - Initial version.
// 1 - Adds UserIntVersion to DatabaseMetaData.
// 2 - Adds DataVersion to to global metadata.
// 3 - Adds metadata needed for blob support.
// 4 - Adds size & last_modified to 'file' blob_info encodings.
// 5 - One time verification that blob files exist on disk.
const constexpr int64_t kLatestKnownSchemaVersion =;
// Migration from version 2 to 3 occurred in 2014, and migration to version 4
// began in early 2020, so we currently continue to support schema that are as
// old as 2014.
const constexpr int64_t kEarliestSupportedSchemaVersion =;
}  // namespace indexed_db

CONTENT_EXPORT extern const unsigned char kMinimumIndexId;

CONTENT_EXPORT std::string MaxIDBKey();
CONTENT_EXPORT std::string MinIDBKey();

// DatabaseId, BlobNumber
BlobJournalEntryType;
BlobJournalType;

CONTENT_EXPORT void EncodeByte(unsigned char value, std::string* into);
CONTENT_EXPORT void EncodeBool(bool value, std::string* into);

// Unlike EncodeVarInt, this is a 'dumb' implementation of a variable int
// encoder. It writes, little-endian', until there are no more '1' bits in the
// number. The Decoder must know how to calculate the size of the encoded int,
// typically by having this reside at the end of the value or key.
CONTENT_EXPORT void EncodeInt(int64_t value, std::string* into);
CONTENT_EXPORT void EncodeString(const std::u16string& value,
                                 std::string* into);
CONTENT_EXPORT void EncodeStringWithLength(const std::u16string& value,
                                           std::string* into);
CONTENT_EXPORT void EncodeBinary(const std::string& value, std::string* into);
CONTENT_EXPORT void EncodeBinary(base::span<const uint8_t> value,
                                 std::string* into);
CONTENT_EXPORT void EncodeDouble(double value, std::string* into);
// This version will CHECK if encoding fails. This is generally preferred to
// handling an error.
CONTENT_EXPORT void EncodeIDBKey(const blink::IndexedDBKey& value,
                                 std::string* into);
// This version will return `true` on success. It exists so tests can run
// without crashing.
[[nodiscard]] CONTENT_EXPORT bool MaybeEncodeIDBKey(
    const blink::IndexedDBKey& value,
    std::string* into);
// This function creates a byte stream that can be directly compared to other
// byte streams on a byte-by-byte basis and retain semantic ordering. This
// enables the value to be stored as a SQLite blob without a specialized
// collation operation. Unlike `EncodeIDBKey`, which makes use of length bytes,
// this operation re-encodes variable-length values in a way that supports
// sentinels.
CONTENT_EXPORT void EncodeSortableIDBKey(const blink::IndexedDBKey& value,
                                         std::string* into);
CONTENT_EXPORT void EncodeIDBKeyPath(const blink::IndexedDBKeyPath& value,
                                     std::string* into);
CONTENT_EXPORT void EncodeBlobJournal(const BlobJournalType& journal,
                                      std::string* into);

[[nodiscard]] CONTENT_EXPORT bool DecodeByte(std::string_view* slice,
                                             unsigned char* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeBool(std::string_view* slice,
                                             bool* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeInt(std::string_view* slice,
                                            int64_t* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeString(std::string_view* slice,
                                               std::u16string* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeStringWithLength(
    std::string_view* slice,
    std::u16string* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeBinary(std::string_view* slice,
                                               std::string* value);
// The returned span is only valid as long as the date behind |slice| is
// still valid.
[[nodiscard]] CONTENT_EXPORT bool DecodeBinary(
    std::string_view* slice,
    base::span<const uint8_t>* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeDouble(std::string_view* slice,
                                               double* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeIDBKey(
    std::string_view* slice,
    std::unique_ptr<blink::IndexedDBKey>* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeSortableIDBKey(
    std::string_view serialized,
    blink::IndexedDBKey* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeIDBKeyPath(
    std::string_view* slice,
    blink::IndexedDBKeyPath* value);
[[nodiscard]] CONTENT_EXPORT bool DecodeBlobJournal(std::string_view* slice,
                                                    BlobJournalType* journal);

CONTENT_EXPORT int CompareEncodedStringsWithLength(std::string_view* slice1,
                                                   std::string_view* slice2,
                                                   bool* ok);

[[nodiscard]] CONTENT_EXPORT bool ExtractEncodedIDBKey(std::string_view* slice,
                                                       std::string* result);

CONTENT_EXPORT int CompareEncodedIDBKeys(std::string_view* slice1,
                                         std::string_view* slice2,
                                         bool* ok);

CONTENT_EXPORT int Compare(std::string_view a,
                           std::string_view b,
                           bool index_keys);

CONTENT_EXPORT int CompareKeys(std::string_view a, std::string_view b);

CONTENT_EXPORT int CompareIndexKeys(std::string_view a, std::string_view b);

// Logging support.
std::string IndexedDBKeyToDebugString(std::string_view key);

// TODO(estade): these lock id factories have nothing to do with level db
// coding and don't belong in this file.

// We can't use the database ID for the database lock because we need to hold
// this lock before we start reading/writing the database metadata, at which
// point we don't yet know the ID, but do know the name (which is unique
// anyway).
CONTENT_EXPORT PartitionedLockId
GetDatabaseLockId(std::u16string database_name);
CONTENT_EXPORT PartitionedLockId GetObjectStoreLockId(int64_t database_id,
                                                      int64_t object_store_id);

// TODO(dmurph): Modify all decoding methods to return something more sensible,
// as it is not obvious that they modify the input slice to remove the decoded
// bit. https://crbug.com/922225
class KeyPrefix {};

class SchemaVersionKey {};

class MaxDatabaseIdKey {};

class DataVersionKey {};

class RecoveryBlobJournalKey {};

class ActiveBlobJournalKey {};

class EarliestSweepKey {};

class EarliestCompactionKey {};

class ScopesPrefix {};

class DatabaseFreeListKey {};

class DatabaseNameKey {};

class DatabaseMetaDataKey {};

class ObjectStoreMetaDataKey {};

class IndexMetaDataKey {};

class ObjectStoreFreeListKey {};

class IndexFreeListKey {};

class ObjectStoreNamesKey {};

class IndexNamesKey {};

class ObjectStoreDataKey {};

class ExistsEntryKey {};

class CONTENT_EXPORT BlobEntryKey {};

class IndexDataKey {};

}  // namespace content

#endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_