FileSystemRootDirectoryEntry.cpp (4585B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "FileSystemRootDirectoryEntry.h" 8 9 #include "CallbackRunnables.h" 10 #include "FileSystemRootDirectoryReader.h" 11 #include "mozilla/dom/FileSystemUtils.h" 12 #include "nsReadableUtils.h" 13 14 namespace mozilla::dom { 15 16 NS_IMPL_CYCLE_COLLECTION_INHERITED(FileSystemRootDirectoryEntry, 17 FileSystemDirectoryEntry, mEntries) 18 19 NS_IMPL_ADDREF_INHERITED(FileSystemRootDirectoryEntry, FileSystemDirectoryEntry) 20 NS_IMPL_RELEASE_INHERITED(FileSystemRootDirectoryEntry, 21 FileSystemDirectoryEntry) 22 23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FileSystemRootDirectoryEntry) 24 NS_INTERFACE_MAP_END_INHERITING(FileSystemDirectoryEntry) 25 26 FileSystemRootDirectoryEntry::FileSystemRootDirectoryEntry( 27 nsIGlobalObject* aGlobal, Sequence<RefPtr<FileSystemEntry>> aEntries, 28 FileSystem* aFileSystem) 29 : FileSystemDirectoryEntry(aGlobal, nullptr, nullptr, aFileSystem), 30 mEntries(std::move(aEntries)) { 31 MOZ_ASSERT(aGlobal); 32 } 33 34 FileSystemRootDirectoryEntry::~FileSystemRootDirectoryEntry() = default; 35 36 void FileSystemRootDirectoryEntry::GetName(nsAString& aName, 37 ErrorResult& aRv) const { 38 aName.Truncate(); 39 } 40 41 void FileSystemRootDirectoryEntry::GetFullPath(nsAString& aPath, 42 ErrorResult& aRv) const { 43 aPath.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL); 44 } 45 46 already_AddRefed<FileSystemDirectoryReader> 47 FileSystemRootDirectoryEntry::CreateReader() { 48 RefPtr<FileSystemDirectoryReader> reader = 49 new FileSystemRootDirectoryReader(this, Filesystem(), mEntries); 50 return reader.forget(); 51 } 52 53 void FileSystemRootDirectoryEntry::GetInternal( 54 const nsAString& aPath, const FileSystemFlags& aFlag, 55 const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, 56 const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, 57 GetInternalType aType) { 58 if (!aSuccessCallback.WasPassed() && !aErrorCallback.WasPassed()) { 59 return; 60 } 61 62 if (aFlag.mCreate) { 63 ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback, 64 NS_ERROR_DOM_SECURITY_ERR); 65 return; 66 } 67 68 nsTArray<nsString> parts; 69 if (!FileSystemUtils::IsValidRelativeDOMPath(aPath, parts)) { 70 ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback, 71 NS_ERROR_DOM_NOT_FOUND_ERR); 72 return; 73 } 74 75 MOZ_ASSERT(!parts.IsEmpty()); 76 77 RefPtr<FileSystemEntry> entry; 78 for (uint32_t i = 0; i < mEntries.Length(); ++i) { 79 ErrorResult rv; 80 nsAutoString name; 81 mEntries[i]->GetName(name, rv); 82 83 if (NS_WARN_IF(rv.Failed())) { 84 ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback, 85 rv.StealNSResult()); 86 return; 87 } 88 89 if (name == parts[0]) { 90 entry = mEntries[i]; 91 break; 92 } 93 } 94 95 // Not found. 96 if (!entry) { 97 ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback, 98 NS_ERROR_DOM_NOT_FOUND_ERR); 99 return; 100 } 101 102 // No subdirectory in the path. 103 if (parts.Length() == 1) { 104 if ((entry->IsFile() && aType == eGetDirectory) || 105 (entry->IsDirectory() && aType == eGetFile)) { 106 ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback, 107 NS_ERROR_DOM_TYPE_MISMATCH_ERR); 108 return; 109 } 110 111 if (aSuccessCallback.WasPassed()) { 112 RefPtr<EntryCallbackRunnable> runnable = 113 new EntryCallbackRunnable(&aSuccessCallback.Value(), entry); 114 115 FileSystemUtils::DispatchRunnable(GetParentObject(), runnable.forget()); 116 } 117 return; 118 } 119 120 // Subdirectories, but this is a file. 121 if (entry->IsFile()) { 122 ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback, 123 NS_ERROR_DOM_NOT_FOUND_ERR); 124 return; 125 } 126 127 // Let's recreate a path without the first directory. 128 nsAutoString path; 129 StringJoinAppend( 130 path, 131 NS_LITERAL_STRING_FROM_CSTRING(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL), 132 Span{parts}.From(1)); 133 134 auto* directoryEntry = static_cast<FileSystemDirectoryEntry*>(entry.get()); 135 directoryEntry->GetInternal(path, aFlag, aSuccessCallback, aErrorCallback, 136 aType); 137 } 138 139 } // namespace mozilla::dom