/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_indexeddatabase_h__ #define mozilla_dom_indexeddatabase_h__ #include "DatabaseFileInfoFwd.h" #include "js/StructuredClone.h" #include "mozilla/InitializedOnce.h" #include "mozilla/Variant.h" #include "nsCOMPtr.h" #include "nsTArray.h" #include "SafeRefPtr.h" namespace mozilla::dom { class Blob; class IDBDatabase; class IDBMutableFile; namespace indexedDB { struct StructuredCloneFileBase { enum FileType { eBlob, eMutableFile, eStructuredClone, eWasmBytecode, eWasmCompiled, eEndGuard }; FileType Type() const { return mType; } protected: explicit StructuredCloneFileBase(FileType aType) : mType{aType} {} FileType mType; }; struct StructuredCloneFileChild : StructuredCloneFileBase { StructuredCloneFileChild(const StructuredCloneFileChild&) = delete; StructuredCloneFileChild& operator=(const StructuredCloneFileChild&) = delete; #ifdef NS_BUILD_REFCNT_LOGGING // In IndexedDatabaseInlines.h StructuredCloneFileChild(StructuredCloneFileChild&&); #else StructuredCloneFileChild(StructuredCloneFileChild&&) = default; #endif StructuredCloneFileChild& operator=(StructuredCloneFileChild&&) = delete; // In IndexedDatabaseInlines.h ~StructuredCloneFileChild(); // In IndexedDatabaseInlines.h explicit StructuredCloneFileChild(FileType aType); // In IndexedDatabaseInlines.h StructuredCloneFileChild(FileType aType, RefPtr aBlob); // In IndexedDatabaseInlines.h explicit StructuredCloneFileChild(RefPtr aMutableFile); const dom::Blob& Blob() const { return *mContents->as>(); } // XXX This is currently used for a number of reasons. Bug 1620560 will remove // the need for one of them, but the uses of do_GetWeakReference in // IDBDatabase::GetOrCreateFileActorForBlob and WrapAsJSObject in // CopyingStructuredCloneReadCallback are probably harder to change. dom::Blob& MutableBlob() const { return *mContents->as>(); } // In IndexedDatabaseInlines.h RefPtr BlobPtr() const; bool HasBlob() const { return mContents->is>(); } const IDBMutableFile& MutableFile() const { return *mContents->as>(); } IDBMutableFile& MutableMutableFile() const { return *mContents->as>(); } bool HasMutableFile() const { return mContents->is>(); } private: InitializedOnce< const Variant, RefPtr>> mContents; }; struct StructuredCloneFileParent : StructuredCloneFileBase { StructuredCloneFileParent(const StructuredCloneFileParent&) = delete; StructuredCloneFileParent& operator=(const StructuredCloneFileParent&) = delete; #ifdef NS_BUILD_REFCNT_LOGGING // In IndexedDatabaseInlines.h StructuredCloneFileParent(StructuredCloneFileParent&&); #else StructuredCloneFileParent(StructuredCloneFileParent&&) = default; #endif StructuredCloneFileParent& operator=(StructuredCloneFileParent&&) = delete; // In IndexedDatabaseInlines.h StructuredCloneFileParent(FileType aType, SafeRefPtr aFileInfo); // In IndexedDatabaseInlines.h ~StructuredCloneFileParent(); // XXX This is used for a schema upgrade hack in UpgradeSchemaFrom19_0To20_0. // When this is eventually removed, this function can be removed, and mType // can be declared const in the base class. void MutateType(FileType aNewType) { mType = aNewType; } const DatabaseFileInfo& FileInfo() const { return ***mContents; } // In IndexedDatabaseInlines.h SafeRefPtr FileInfoPtr() const; private: InitializedOnce>> mContents; }; struct StructuredCloneReadInfoBase { // In IndexedDatabaseInlines.h explicit StructuredCloneReadInfoBase(JSStructuredCloneData&& aData) : mData{std::move(aData)} {} const JSStructuredCloneData& Data() const { return mData; } JSStructuredCloneData ReleaseData() { return std::move(mData); } private: JSStructuredCloneData mData; }; template struct StructuredCloneReadInfo : StructuredCloneReadInfoBase { using StructuredCloneFile = StructuredCloneFileT; // In IndexedDatabaseInlines.h explicit StructuredCloneReadInfo(JS::StructuredCloneScope aScope); // In IndexedDatabaseInlines.h StructuredCloneReadInfo(); // In IndexedDatabaseInlines.h StructuredCloneReadInfo(JSStructuredCloneData&& aData, nsTArray aFiles); #ifdef NS_BUILD_REFCNT_LOGGING // In IndexedDatabaseInlines.h ~StructuredCloneReadInfo(); // In IndexedDatabaseInlines.h // // This custom implementation of the move ctor is only necessary because of // MOZ_COUNT_CTOR. It is less efficient as the compiler-generated move ctor, // since it unnecessarily clears elements on the source. StructuredCloneReadInfo(StructuredCloneReadInfo&& aOther) noexcept; #else StructuredCloneReadInfo(StructuredCloneReadInfo&& aOther) = default; #endif StructuredCloneReadInfo& operator=(StructuredCloneReadInfo&& aOther) = default; StructuredCloneReadInfo(const StructuredCloneReadInfo& aOther) = delete; StructuredCloneReadInfo& operator=(const StructuredCloneReadInfo& aOther) = delete; // In IndexedDatabaseInlines.h size_t Size() const; // XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0). // If support for older schemas is dropped, we can probably remove this method // and make mFiles InitializedOnce. StructuredCloneFile& MutableFile(const size_t aIndex) { return mFiles[aIndex]; } const nsTArray& Files() const { return mFiles; } nsTArray ReleaseFiles() { return std::move(mFiles); } bool HasFiles() const { return !mFiles.IsEmpty(); } private: nsTArray mFiles; }; struct StructuredCloneReadInfoChild : StructuredCloneReadInfo { inline StructuredCloneReadInfoChild(JSStructuredCloneData&& aData, nsTArray aFiles, IDBDatabase* aDatabase); IDBDatabase* Database() const { return mDatabase; } private: IDBDatabase* mDatabase; }; // This is only defined in the header file to satisfy the clang-plugin static // analysis, it could be placed in ActorsParent.cpp otherwise. struct StructuredCloneReadInfoParent : StructuredCloneReadInfo { StructuredCloneReadInfoParent(JSStructuredCloneData&& aData, nsTArray aFiles, bool aHasPreprocessInfo) : StructuredCloneReadInfo{std::move(aData), std::move(aFiles)}, mHasPreprocessInfo{aHasPreprocessInfo} {} bool HasPreprocessInfo() const { return mHasPreprocessInfo; } private: bool mHasPreprocessInfo; }; template JSObject* CommonStructuredCloneReadCallback( JSContext* aCx, JSStructuredCloneReader* aReader, const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, StructuredCloneReadInfo* aCloneReadInfo, IDBDatabase* aDatabase); template JSObject* StructuredCloneReadCallback( JSContext* aCx, JSStructuredCloneReader* aReader, const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, void* aClosure); } // namespace indexedDB } // namespace mozilla::dom MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( mozilla::dom::indexedDB::StructuredCloneReadInfo< mozilla::dom::indexedDB::StructuredCloneFileChild>); MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( mozilla::dom::indexedDB::StructuredCloneReadInfo< mozilla::dom::indexedDB::StructuredCloneFileParent>); MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( mozilla::dom::indexedDB::StructuredCloneReadInfoChild); MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( mozilla::dom::indexedDB::StructuredCloneReadInfoParent); #endif // mozilla_dom_indexeddatabase_h__