chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_VALUE_WRAPPING_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_VALUE_WRAPPING_H_

#include <memory>
#include <utility>

#include "base/dcheck_is_on.h"
#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h"

namespace blink {

class BlobDataHandle;
class ExceptionState;
class IDBValue;
class ScriptState;
class ScriptValue;
class SerializedScriptValue;

// Logic for serializing V8 values for storage in IndexedDB.
//
// An IDBValueWrapper instance drives the serialization of a single V8 value to
// IndexedDB. An instance's lifecycle goes through the following stages:
// 1) Cloning - Right after an instance is constructed, its internal
//    representation is optimized for structured cloning via the Clone() method.
//    This may be necessary when extracting the primary key and/or index keys
//    for the serialized value.
// 2) Wrapping - DoneCloning() transitions the instance to an internal
//    representation optimized IPC and disk storage. See below for details.
// 3) Reading results - After any desired wrapping is performed, the Take*()
//    methods yield the serialized value components passed to the backing store.
//    To avoid unnecessary copies, the Take*() methods move out parts of the
//    internal representation, so each Take*() method can be called at most
//    once.
//
// Example usage:
//     auto wrapper = new IDBValueWrapper();
//     wrapper.Clone(...);  // Structured clone used to extract keys.
//     wrapper.DoneCloning();
//     wrapper.TakeWireBytes();
//     wrapper.TakeBlobDataHandles();
//     wrapper.TakeBlobInfo();
//
// V8 values are first serialized via SerializedScriptValue (SSV), which is
// essentially a byte array plus an array of attached Blobs. The SSV output's
// byte array is then further compressed via Snappy. If the compressed array is
// not too large, it will be stored directly in IndexedDB's backing store,
// together with references to the attached Blobs.
//
// Values that are still "large" after compression are converted into a Blob
// (additional to those already attached). Specifically, the byte array in the
// SSV output is replaced with a "wrapped value" marker, and stored inside a
// Blob that is tacked to the end of the SSV's Blob array. IndexedDB's backing
// store receives the "wrapped value" marker and the references to the Blobs,
// while the large byte array in the SSV output is handled by the Blob storage
// system.
//
// In summary:
// "normal" v8::Value -> SSV + Snappy -> IDBValue (stores SSV output) -> LevelDB
// "large" v8::Value -> SSV + Snappy -> IDBValue (stores SSV output) ->
//     Blob (stores SSV output) + IDBValue (stores Blob reference) -> LevelDB
//
// Full picture that accounts for Blob attachments:
// "normal" v8::Value -> SSV (byte array, Blob attachments) -> Snappy ->
//     IDBValue (bytes: compressed SSV byte array, blobs: SSV Blob attachments)
//     -> LevelDB
// "large" v8::Value -> SSV (byte array, Blob attachments) -> Snappy ->
//     IDBValue (bytes: "wrapped value" marker,
//               blobs: SSV Blob attachments +
//                      [wrapper Blob(compressed SSV byte array)] ->
//     LevelDB
class MODULES_EXPORT IDBValueWrapper {};

// State and logic for unwrapping large IndexedDB values from Blobs.
//
// See IDBValueWrapper for an explanation of the wrapping concept.
//
// Once created, an IDBValueUnwrapper instance can be used to unwrap multiple
// Blobs. For each Blob to be unwrapped, the caller should first call Parse().
// If the method succeeds, the IDBValueUnwrapper will store the parse state,
// which can be obtained using WrapperBlobSize() and WrapperBlobHandle().
class MODULES_EXPORT IDBValueUnwrapper {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_VALUE_WRAPPING_H_