1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_indexeddatabase_h__ 8 #define mozilla_dom_indexeddatabase_h__ 9 10 #include "DatabaseFileInfoFwd.h" 11 #include "js/StructuredClone.h" 12 #include "mozilla/InitializedOnce.h" 13 #include "mozilla/Variant.h" 14 #include "nsCOMPtr.h" 15 #include "nsTArray.h" 16 #include "SafeRefPtr.h" 17 18 namespace mozilla { 19 namespace dom { 20 21 class Blob; 22 class IDBDatabase; 23 class IDBMutableFile; 24 25 namespace indexedDB { 26 27 struct StructuredCloneFileBase { 28 enum FileType { 29 eBlob, 30 eMutableFile, 31 eStructuredClone, 32 eWasmBytecode, 33 eWasmCompiled, 34 eEndGuard 35 }; 36 TypeStructuredCloneFileBase37 FileType Type() const { return mType; } 38 39 protected: StructuredCloneFileBaseStructuredCloneFileBase40 explicit StructuredCloneFileBase(FileType aType) : mType{aType} {} 41 42 FileType mType; 43 }; 44 45 struct StructuredCloneFileChild : StructuredCloneFileBase { 46 StructuredCloneFileChild(const StructuredCloneFileChild&) = delete; 47 StructuredCloneFileChild& operator=(const StructuredCloneFileChild&) = delete; 48 #ifdef NS_BUILD_REFCNT_LOGGING 49 // In IndexedDatabaseInlines.h 50 StructuredCloneFileChild(StructuredCloneFileChild&&); 51 #else 52 StructuredCloneFileChild(StructuredCloneFileChild&&) = default; 53 #endif 54 StructuredCloneFileChild& operator=(StructuredCloneFileChild&&) = delete; 55 56 // In IndexedDatabaseInlines.h 57 ~StructuredCloneFileChild(); 58 59 // In IndexedDatabaseInlines.h 60 explicit StructuredCloneFileChild(FileType aType); 61 62 // In IndexedDatabaseInlines.h 63 StructuredCloneFileChild(FileType aType, RefPtr<Blob> aBlob); 64 65 // In IndexedDatabaseInlines.h 66 explicit StructuredCloneFileChild(RefPtr<IDBMutableFile> aMutableFile); 67 BlobStructuredCloneFileChild68 const dom::Blob& Blob() const { return *mContents->as<RefPtr<dom::Blob>>(); } 69 70 // XXX This is currently used for a number of reasons. Bug 1620560 will remove 71 // the need for one of them, but the uses of do_GetWeakReference in 72 // IDBDatabase::GetOrCreateFileActorForBlob and WrapAsJSObject in 73 // CopyingStructuredCloneReadCallback are probably harder to change. MutableBlobStructuredCloneFileChild74 dom::Blob& MutableBlob() const { return *mContents->as<RefPtr<dom::Blob>>(); } 75 76 // In IndexedDatabaseInlines.h 77 RefPtr<dom::Blob> BlobPtr() const; 78 HasBlobStructuredCloneFileChild79 bool HasBlob() const { return mContents->is<RefPtr<dom::Blob>>(); } 80 MutableFileStructuredCloneFileChild81 const IDBMutableFile& MutableFile() const { 82 return *mContents->as<RefPtr<IDBMutableFile>>(); 83 } 84 MutableMutableFileStructuredCloneFileChild85 IDBMutableFile& MutableMutableFile() const { 86 return *mContents->as<RefPtr<IDBMutableFile>>(); 87 } 88 HasMutableFileStructuredCloneFileChild89 bool HasMutableFile() const { 90 return mContents->is<RefPtr<IDBMutableFile>>(); 91 } 92 93 private: 94 InitializedOnce< 95 const Variant<Nothing, RefPtr<dom::Blob>, RefPtr<IDBMutableFile>>> 96 mContents; 97 }; 98 99 struct StructuredCloneFileParent : StructuredCloneFileBase { 100 StructuredCloneFileParent(const StructuredCloneFileParent&) = delete; 101 StructuredCloneFileParent& operator=(const StructuredCloneFileParent&) = 102 delete; 103 #ifdef NS_BUILD_REFCNT_LOGGING 104 // In IndexedDatabaseInlines.h 105 StructuredCloneFileParent(StructuredCloneFileParent&&); 106 #else 107 StructuredCloneFileParent(StructuredCloneFileParent&&) = default; 108 #endif 109 StructuredCloneFileParent& operator=(StructuredCloneFileParent&&) = delete; 110 111 // In IndexedDatabaseInlines.h 112 StructuredCloneFileParent(FileType aType, 113 SafeRefPtr<DatabaseFileInfo> aFileInfo); 114 115 // In IndexedDatabaseInlines.h 116 ~StructuredCloneFileParent(); 117 118 // XXX This is used for a schema upgrade hack in UpgradeSchemaFrom19_0To20_0. 119 // When this is eventually removed, this function can be removed, and mType 120 // can be declared const in the base class. MutateTypeStructuredCloneFileParent121 void MutateType(FileType aNewType) { mType = aNewType; } 122 FileInfoStructuredCloneFileParent123 const DatabaseFileInfo& FileInfo() const { return ***mContents; } 124 125 // In IndexedDatabaseInlines.h 126 SafeRefPtr<DatabaseFileInfo> FileInfoPtr() const; 127 128 private: 129 InitializedOnce<const Maybe<SafeRefPtr<DatabaseFileInfo>>> mContents; 130 }; 131 132 struct StructuredCloneReadInfoBase { 133 // In IndexedDatabaseInlines.h StructuredCloneReadInfoBaseStructuredCloneReadInfoBase134 explicit StructuredCloneReadInfoBase(JSStructuredCloneData&& aData) 135 : mData{std::move(aData)} {} 136 DataStructuredCloneReadInfoBase137 const JSStructuredCloneData& Data() const { return mData; } ReleaseDataStructuredCloneReadInfoBase138 JSStructuredCloneData ReleaseData() { return std::move(mData); } 139 140 private: 141 JSStructuredCloneData mData; 142 }; 143 144 template <typename StructuredCloneFileT> 145 struct StructuredCloneReadInfo : StructuredCloneReadInfoBase { 146 using StructuredCloneFile = StructuredCloneFileT; 147 148 // In IndexedDatabaseInlines.h 149 explicit StructuredCloneReadInfo(JS::StructuredCloneScope aScope); 150 151 // In IndexedDatabaseInlines.h 152 StructuredCloneReadInfo(); 153 154 // In IndexedDatabaseInlines.h 155 StructuredCloneReadInfo(JSStructuredCloneData&& aData, 156 nsTArray<StructuredCloneFile> aFiles); 157 158 #ifdef NS_BUILD_REFCNT_LOGGING 159 // In IndexedDatabaseInlines.h 160 ~StructuredCloneReadInfo(); 161 162 // In IndexedDatabaseInlines.h 163 // 164 // This custom implementation of the move ctor is only necessary because of 165 // MOZ_COUNT_CTOR. It is less efficient as the compiler-generated move ctor, 166 // since it unnecessarily clears elements on the source. 167 StructuredCloneReadInfo(StructuredCloneReadInfo&& aOther) noexcept; 168 #else 169 StructuredCloneReadInfo(StructuredCloneReadInfo&& aOther) = default; 170 #endif 171 StructuredCloneReadInfo& operator=(StructuredCloneReadInfo&& aOther) = 172 default; 173 174 StructuredCloneReadInfo(const StructuredCloneReadInfo& aOther) = delete; 175 StructuredCloneReadInfo& operator=(const StructuredCloneReadInfo& aOther) = 176 delete; 177 178 // In IndexedDatabaseInlines.h 179 size_t Size() const; 180 181 // XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0). 182 // If support for older schemas is dropped, we can probably remove this method 183 // and make mFiles InitializedOnce. MutableFileStructuredCloneReadInfo184 StructuredCloneFile& MutableFile(const size_t aIndex) { 185 return mFiles[aIndex]; 186 } FilesStructuredCloneReadInfo187 const nsTArray<StructuredCloneFile>& Files() const { return mFiles; } 188 ReleaseFilesStructuredCloneReadInfo189 nsTArray<StructuredCloneFile> ReleaseFiles() { return std::move(mFiles); } 190 HasFilesStructuredCloneReadInfo191 bool HasFiles() const { return !mFiles.IsEmpty(); } 192 193 private: 194 nsTArray<StructuredCloneFile> mFiles; 195 }; 196 197 struct StructuredCloneReadInfoChild 198 : StructuredCloneReadInfo<StructuredCloneFileChild> { 199 inline StructuredCloneReadInfoChild(JSStructuredCloneData&& aData, 200 nsTArray<StructuredCloneFileChild> aFiles, 201 IDBDatabase* aDatabase); 202 DatabaseStructuredCloneReadInfoChild203 IDBDatabase* Database() const { return mDatabase; } 204 205 private: 206 IDBDatabase* mDatabase; 207 }; 208 209 // This is only defined in the header file to satisfy the clang-plugin static 210 // analysis, it could be placed in ActorsParent.cpp otherwise. 211 struct StructuredCloneReadInfoParent 212 : StructuredCloneReadInfo<StructuredCloneFileParent> { StructuredCloneReadInfoParentStructuredCloneReadInfoParent213 StructuredCloneReadInfoParent(JSStructuredCloneData&& aData, 214 nsTArray<StructuredCloneFileParent> aFiles, 215 bool aHasPreprocessInfo) 216 : StructuredCloneReadInfo{std::move(aData), std::move(aFiles)}, 217 mHasPreprocessInfo{aHasPreprocessInfo} {} 218 HasPreprocessInfoStructuredCloneReadInfoParent219 bool HasPreprocessInfo() const { return mHasPreprocessInfo; } 220 221 private: 222 bool mHasPreprocessInfo; 223 }; 224 225 template <typename StructuredCloneReadInfo> 226 JSObject* CommonStructuredCloneReadCallback( 227 JSContext* aCx, JSStructuredCloneReader* aReader, 228 const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, 229 StructuredCloneReadInfo* aCloneReadInfo, IDBDatabase* aDatabase); 230 231 template <typename StructuredCloneReadInfoType> 232 JSObject* StructuredCloneReadCallback( 233 JSContext* aCx, JSStructuredCloneReader* aReader, 234 const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, 235 void* aClosure); 236 237 } // namespace indexedDB 238 } // namespace dom 239 } // namespace mozilla 240 241 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( 242 mozilla::dom::indexedDB::StructuredCloneReadInfo< 243 mozilla::dom::indexedDB::StructuredCloneFileChild>); 244 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( 245 mozilla::dom::indexedDB::StructuredCloneReadInfo< 246 mozilla::dom::indexedDB::StructuredCloneFileParent>); 247 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( 248 mozilla::dom::indexedDB::StructuredCloneReadInfoChild); 249 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR( 250 mozilla::dom::indexedDB::StructuredCloneReadInfoParent); 251 252 #endif // mozilla_dom_indexeddatabase_h__ 253