FileSystemDirectoryHandle.cpp (5698B)
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 #include "FileSystemDirectoryHandle.h" 8 9 #include <cstdint> 10 11 #include "FileSystemDirectoryIteratorFactory.h" 12 #include "fs/FileSystemRequestHandler.h" 13 #include "js/StructuredClone.h" 14 #include "js/TypeDecls.h" 15 #include "mozilla/ErrorResult.h" 16 #include "mozilla/dom/FileSystemDirectoryHandleBinding.h" 17 #include "mozilla/dom/FileSystemHandleBinding.h" 18 #include "mozilla/dom/FileSystemLog.h" 19 #include "mozilla/dom/FileSystemManager.h" 20 #include "mozilla/dom/PFileSystemManager.h" 21 #include "mozilla/dom/Promise.h" 22 #include "mozilla/dom/StorageManager.h" 23 #include "nsJSUtils.h" 24 25 namespace mozilla::dom { 26 27 FileSystemDirectoryHandle::FileSystemDirectoryHandle( 28 nsIGlobalObject* aGlobal, RefPtr<FileSystemManager>& aManager, 29 const fs::FileSystemEntryMetadata& aMetadata, 30 fs::FileSystemRequestHandler* aRequestHandler) 31 : FileSystemHandle(aGlobal, aManager, aMetadata, aRequestHandler) {} 32 33 FileSystemDirectoryHandle::FileSystemDirectoryHandle( 34 nsIGlobalObject* aGlobal, RefPtr<FileSystemManager>& aManager, 35 const fs::FileSystemEntryMetadata& aMetadata) 36 : FileSystemDirectoryHandle(aGlobal, aManager, aMetadata, 37 new fs::FileSystemRequestHandler()) {} 38 39 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(FileSystemDirectoryHandle, 40 FileSystemHandle) 41 NS_IMPL_CYCLE_COLLECTION_INHERITED(FileSystemDirectoryHandle, FileSystemHandle) 42 43 // WebIDL Boilerplate 44 45 JSObject* FileSystemDirectoryHandle::WrapObject( 46 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 47 return FileSystemDirectoryHandle_Binding::Wrap(aCx, this, aGivenProto); 48 } 49 50 // WebIDL Interface 51 52 FileSystemHandleKind FileSystemDirectoryHandle::Kind() const { 53 return FileSystemHandleKind::Directory; 54 } 55 56 void FileSystemDirectoryHandle::InitAsyncIteratorData( 57 IteratorData& aData, iterator_t::IteratorType aType, ErrorResult& aError) { 58 aData.mImpl = 59 fs::FileSystemDirectoryIteratorFactory::Create(mMetadata, aType); 60 } 61 62 already_AddRefed<Promise> FileSystemDirectoryHandle::GetNextIterationResult( 63 FileSystemDirectoryHandle::iterator_t* aIterator, ErrorResult& aError) { 64 LOG_VERBOSE(("GetNextIterationResult")); 65 return aIterator->Data().mImpl->Next(mGlobal, mManager, aError); 66 } 67 68 already_AddRefed<Promise> FileSystemDirectoryHandle::GetFileHandle( 69 const nsAString& aName, const FileSystemGetFileOptions& aOptions, 70 ErrorResult& aError) { 71 MOZ_ASSERT(!mMetadata.entryId().IsEmpty()); 72 73 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 74 if (aError.Failed()) { 75 return nullptr; 76 } 77 78 fs::Name name(aName); 79 fs::FileSystemChildMetadata metadata(mMetadata.entryId(), name); 80 mRequestHandler->GetFileHandle(mManager, metadata, aOptions.mCreate, promise, 81 aError); 82 if (aError.Failed()) { 83 return nullptr; 84 } 85 86 return promise.forget(); 87 } 88 89 already_AddRefed<Promise> FileSystemDirectoryHandle::GetDirectoryHandle( 90 const nsAString& aName, const FileSystemGetDirectoryOptions& aOptions, 91 ErrorResult& aError) { 92 MOZ_ASSERT(!mMetadata.entryId().IsEmpty()); 93 94 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 95 if (aError.Failed()) { 96 return nullptr; 97 } 98 99 fs::Name name(aName); 100 fs::FileSystemChildMetadata metadata(mMetadata.entryId(), name); 101 mRequestHandler->GetDirectoryHandle(mManager, metadata, aOptions.mCreate, 102 promise, aError); 103 if (aError.Failed()) { 104 return nullptr; 105 } 106 107 return promise.forget(); 108 } 109 110 already_AddRefed<Promise> FileSystemDirectoryHandle::RemoveEntry( 111 const nsAString& aName, const FileSystemRemoveOptions& aOptions, 112 ErrorResult& aError) { 113 MOZ_ASSERT(!mMetadata.entryId().IsEmpty()); 114 115 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 116 if (aError.Failed()) { 117 return nullptr; 118 } 119 120 fs::Name name(aName); 121 fs::FileSystemChildMetadata metadata(mMetadata.entryId(), name); 122 123 mRequestHandler->RemoveEntry(mManager, metadata, aOptions.mRecursive, promise, 124 aError); 125 if (aError.Failed()) { 126 return nullptr; 127 } 128 129 return promise.forget(); 130 } 131 132 already_AddRefed<Promise> FileSystemDirectoryHandle::Resolve( 133 FileSystemHandle& aPossibleDescendant, ErrorResult& aError) { 134 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 135 if (aError.Failed()) { 136 return nullptr; 137 } 138 139 LOG_VERBOSE(("Resolve")); 140 141 fs::FileSystemEntryPair pair(mMetadata.entryId(), 142 aPossibleDescendant.GetId()); 143 mRequestHandler->Resolve(mManager, pair, promise, aError); 144 if (aError.Failed()) { 145 return nullptr; 146 } 147 148 return promise.forget(); 149 } 150 151 // [Serializable] implementation 152 153 // static 154 already_AddRefed<FileSystemDirectoryHandle> 155 FileSystemDirectoryHandle::ReadStructuredClone( 156 JSContext* aCx, nsIGlobalObject* aGlobal, 157 JSStructuredCloneReader* aReader) { 158 uint32_t kind = UINT32_MAX; 159 160 if (!JS_ReadBytes(aReader, reinterpret_cast<void*>(&kind), 161 sizeof(uint32_t))) { 162 return nullptr; 163 } 164 165 if (kind != static_cast<uint32_t>(FileSystemHandleKind::Directory)) { 166 return nullptr; 167 } 168 169 RefPtr<FileSystemDirectoryHandle> result = 170 FileSystemHandle::ConstructDirectoryHandle(aCx, aGlobal, aReader); 171 if (!result) { 172 return nullptr; 173 } 174 175 return result.forget(); 176 } 177 178 } // namespace mozilla::dom