зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 12 changesets (bug 1761370, bug 1789116, bug 1784405, bug 1786465, bug 1772540, bug 1789871, bug 1789932, bug 1777365) for causing FileSystem related wpt failures CLOSED TREE
Backed out changeset fdfc118c8655 (bug 1784405) Backed out changeset f14ea4093d57 (bug 1777365) Backed out changeset f1c5606ca6e0 (bug 1786465) Backed out changeset 37390dc34f1e (bug 1789871) Backed out changeset 249ebf125b3f (bug 1761370) Backed out changeset 650ff0bfe280 (bug 1789116) Backed out changeset 36c6c340fe64 (bug 1786465) Backed out changeset 4058c1a74e18 (bug 1761370) Backed out changeset 1193594d1bb1 (bug 1761370) Backed out changeset 8bb8c4b1614e (bug 1761370) Backed out changeset 260c04c9aa1c (bug 1772540) Backed out changeset a2df6e3df72a (bug 1789932)
This commit is contained in:
Родитель
a181c16953
Коммит
fb95a6dc3d
|
@ -1,36 +0,0 @@
|
|||
BasedOnStyle: Google
|
||||
|
||||
# Prevent the loss of indentation with these macros
|
||||
MacroBlockBegin: "^\
|
||||
JS_BEGIN_MACRO|\
|
||||
NS_INTERFACE_MAP_BEGIN|\
|
||||
NS_INTERFACE_TABLE_HEAD|\
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION|\
|
||||
NS_IMPL_CYCLE_COLLECTION_.*_BEGIN|\
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED|\
|
||||
NS_INTERFACE_TABLE_BEGIN|\
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED|\
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED|\
|
||||
NS_QUERYFRAME_HEAD$"
|
||||
MacroBlockEnd: "^\
|
||||
JS_END_MACRO|\
|
||||
NS_INTERFACE_MAP_END|\
|
||||
NS_IMPL_CYCLE_COLLECTION_.*_END|\
|
||||
NS_INTERFACE_TABLE_END|\
|
||||
NS_INTERFACE_TABLE_TAIL.*|\
|
||||
NS_INTERFACE_MAP_END_.*|\
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END_INHERITED|\
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED|\
|
||||
NS_QUERYFRAME_TAIL.*$"
|
||||
|
||||
SortIncludes: true
|
||||
IndentPPDirectives: AfterHash
|
||||
StatementMacros: [MARKUPMAP, ASSERT_TRUE, ASSERT_FALSE, TEST, CHECK]
|
||||
|
||||
# The Google coding style states:
|
||||
# You should do this consistently within a single file, so, when modifying an
|
||||
# existing file, use the style in that file.
|
||||
# Let's be more prescriptive and default to the one used in the Mozilla
|
||||
# coding style
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
|
@ -7,9 +7,9 @@
|
|||
#ifndef DOM_FS_FILESYSTEMDIRECTORYHANDLE_H_
|
||||
#define DOM_FS_FILESYSTEMDIRECTORYHANDLE_H_
|
||||
|
||||
#include "mozilla/dom/FileSystemDirectoryIterator.h"
|
||||
#include "mozilla/dom/FileSystemHandle.h"
|
||||
#include "mozilla/dom/IterableIterator.h"
|
||||
#include "mozilla/dom/FileSystemDirectoryIterator.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
#ifndef DOM_FS_FILESYSTEMDIRECTORYITERATOR_H_
|
||||
#define DOM_FS_FILESYSTEMDIRECTORYITERATOR_H_
|
||||
|
||||
#include "mozilla/dom/IterableIterator.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/IterableIterator.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FileSystemFileHandle.h"
|
||||
|
||||
#include "fs/FileSystemRequestHandler.h"
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
@ -77,7 +77,7 @@ already_AddRefed<Promise> FileSystemFileHandle::CreateSyncAccessHandle(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
mRequestHandler->GetAccessHandle(mManager, mMetadata, promise);
|
||||
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/FileSystemHandleBinding.h"
|
||||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "mozilla/dom/Promise-inl.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/StorageManager.h"
|
||||
#include "xpcpublic.h"
|
||||
|
@ -104,76 +103,7 @@ already_AddRefed<Promise> FileSystemHandle::IsSameEntry(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Handles the case of "dir = createdir foo; removeEntry(foo); file =
|
||||
// createfile foo; issameentry(dir, file)"
|
||||
const bool result = mMetadata.entryId().Equals(aOther.mMetadata.entryId()) &&
|
||||
Kind() == aOther.Kind();
|
||||
promise->MaybeResolve(result);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> FileSystemHandle::Move(const nsAString& aName,
|
||||
ErrorResult& aError) {
|
||||
LOG(("Move %s to %s", NS_ConvertUTF16toUTF8(mMetadata.entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(aName).get()));
|
||||
|
||||
fs::EntryId parent; // empty means same directory
|
||||
return Move(parent, aName, aError);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> FileSystemHandle::Move(
|
||||
FileSystemDirectoryHandle& aParent, ErrorResult& aError) {
|
||||
LOG(("Move %s to %s/%s", NS_ConvertUTF16toUTF8(mMetadata.entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(aParent.mMetadata.entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(mMetadata.entryName()).get()));
|
||||
return Move(aParent, mMetadata.entryName(), aError);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> FileSystemHandle::Move(
|
||||
FileSystemDirectoryHandle& aParent, const nsAString& aName,
|
||||
ErrorResult& aError) {
|
||||
LOG(("Move %s to %s/%s", NS_ConvertUTF16toUTF8(mMetadata.entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(aParent.mMetadata.entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(aName).get()));
|
||||
return Move(aParent.mMetadata.entryId(), aName, aError);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> FileSystemHandle::Move(const fs::EntryId& aParentId,
|
||||
const nsAString& aName,
|
||||
ErrorResult& aError) {
|
||||
RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError);
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fs::Name name(aName);
|
||||
if (!aParentId.IsEmpty()) {
|
||||
fs::FileSystemChildMetadata newMetadata;
|
||||
newMetadata.parentId() = aParentId;
|
||||
newMetadata.childName() = aName;
|
||||
mRequestHandler->MoveEntry(mManager, this, mMetadata, newMetadata, promise);
|
||||
} else {
|
||||
mRequestHandler->RenameEntry(mManager, this, mMetadata, name, promise);
|
||||
}
|
||||
|
||||
// Other handles to this will be broken, and the spec is ok with this, but we
|
||||
// need to update our EntryId and name
|
||||
promise->AddCallbacksWithCycleCollectedArgs(
|
||||
[name](JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv,
|
||||
FileSystemHandle* aHandle) {
|
||||
// XXX Fix entryId!
|
||||
LOG(("Changing FileSystemHandle name from %s to %s",
|
||||
NS_ConvertUTF16toUTF8(aHandle->mMetadata.entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(name).get()));
|
||||
aHandle->mMetadata.entryName() = name;
|
||||
},
|
||||
[](JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv,
|
||||
FileSystemHandle* aHandle) {
|
||||
LOG(("reject of move for %s",
|
||||
NS_ConvertUTF16toUTF8(aHandle->mMetadata.entryName()).get()));
|
||||
},
|
||||
RefPtr(this));
|
||||
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
|
|
@ -7,21 +7,12 @@
|
|||
#ifndef DOM_FS_FILESYSTEMHANDLE_H_
|
||||
#define DOM_FS_FILESYSTEMHANDLE_H_
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
namespace mozilla {
|
||||
extern LazyLogModule gOPFSLog;
|
||||
}
|
||||
|
||||
#define LOG(args) MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Verbose, args)
|
||||
|
||||
#define LOG_DEBUG(args) \
|
||||
MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -82,21 +73,6 @@ class FileSystemHandle : public nsISupports, public nsWrapperCache {
|
|||
virtual bool WriteStructuredClone(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter) const;
|
||||
|
||||
already_AddRefed<Promise> Move(const nsAString& aName, ErrorResult& aError);
|
||||
|
||||
already_AddRefed<Promise> Move(FileSystemDirectoryHandle& aParent,
|
||||
ErrorResult& aError);
|
||||
|
||||
already_AddRefed<Promise> Move(FileSystemDirectoryHandle& aParent,
|
||||
const nsAString& aName, ErrorResult& aError);
|
||||
|
||||
already_AddRefed<Promise> Move(const fs::EntryId& aParentId,
|
||||
const nsAString& aName, ErrorResult& aError);
|
||||
|
||||
void UpdateMetadata(const fs::FileSystemEntryMetadata& aMetadata) {
|
||||
mMetadata = aMetadata;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~FileSystemHandle() = default;
|
||||
|
||||
|
@ -112,8 +88,7 @@ class FileSystemHandle : public nsISupports, public nsWrapperCache {
|
|||
|
||||
RefPtr<FileSystemManager> mManager;
|
||||
|
||||
// move() can change names/directories
|
||||
fs::FileSystemEntryMetadata mMetadata;
|
||||
const fs::FileSystemEntryMetadata mMetadata;
|
||||
|
||||
const UniquePtr<fs::FileSystemRequestHandler> mRequestHandler;
|
||||
};
|
||||
|
|
|
@ -6,106 +6,19 @@
|
|||
|
||||
#include "FileSystemSyncAccessHandle.h"
|
||||
|
||||
#include "fs/FileSystemRequestHandler.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/FileSystemAccessHandleChild.h"
|
||||
#include "mozilla/dom/FileSystemHandleBinding.h"
|
||||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "mozilla/dom/FileSystemSyncAccessHandleBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "private/pprio.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
LazyLogModule gOPFSLog("OPFS");
|
||||
|
||||
}
|
||||
#define LOG(args) MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Verbose, args)
|
||||
|
||||
#define LOG_DEBUG(args) \
|
||||
MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
/**
|
||||
* TODO: Duplicated from netwerk/cache2/CacheFileIOManager.cpp
|
||||
* Please remove after bug 1286601 is fixed,
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1286601
|
||||
*/
|
||||
static nsresult TruncFile(PRFileDesc* aFD, int64_t aEOF) {
|
||||
#if defined(XP_UNIX)
|
||||
if (ftruncate(PR_FileDesc2NativeHandle(aFD), aEOF) != 0) {
|
||||
NS_ERROR("ftruncate failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
int64_t cnt = PR_Seek64(aFD, aEOF, PR_SEEK_SET);
|
||||
if (cnt == -1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!SetEndOfFile((HANDLE)PR_FileDesc2NativeHandle(aFD))) {
|
||||
NS_ERROR("SetEndOfFile failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#else
|
||||
MOZ_ASSERT(false, "Not implemented!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
FileSystemSyncAccessHandle::FileSystemSyncAccessHandle(
|
||||
nsIGlobalObject* aGlobal, RefPtr<FileSystemManager>& aManager,
|
||||
RefPtr<FileSystemAccessHandleChild> aActor,
|
||||
const fs::FileSystemEntryMetadata& aMetadata,
|
||||
fs::FileSystemRequestHandler* aRequestHandler)
|
||||
: mGlobal(aGlobal),
|
||||
mManager(aManager),
|
||||
mActor(std::move(aActor)),
|
||||
mMetadata(aMetadata),
|
||||
mRequestHandler(aRequestHandler) {}
|
||||
|
||||
FileSystemSyncAccessHandle::FileSystemSyncAccessHandle(
|
||||
nsIGlobalObject* aGlobal, RefPtr<FileSystemManager>& aManager,
|
||||
RefPtr<FileSystemAccessHandleChild> aActor,
|
||||
const fs::FileSystemEntryMetadata& aMetadata)
|
||||
: FileSystemSyncAccessHandle(aGlobal, aManager, std::move(aActor),
|
||||
aMetadata,
|
||||
new fs::FileSystemRequestHandler()) {
|
||||
LOG(("Created SyncAccessHandle %p for fd %p", this,
|
||||
mActor->MutableFileDescPtr()));
|
||||
}
|
||||
|
||||
FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle() {
|
||||
if (mActor) {
|
||||
mActor->Close();
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FileSystemSyncAccessHandle)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemSyncAccessHandle)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(FileSystemSyncAccessHandle)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(FileSystemSyncAccessHandle)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FileSystemSyncAccessHandle)
|
||||
// Don't unlink mManager!
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FileSystemSyncAccessHandle)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
void FileSystemSyncAccessHandle::ClearActor() {
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
mActor = nullptr;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemSyncAccessHandle);
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(FileSystemSyncAccessHandle);
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FileSystemSyncAccessHandle, mGlobal);
|
||||
|
||||
// WebIDL Boilerplate
|
||||
|
||||
|
@ -122,125 +35,14 @@ JSObject* FileSystemSyncAccessHandle::WrapObject(
|
|||
|
||||
uint64_t FileSystemSyncAccessHandle::Read(
|
||||
const MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer,
|
||||
const FileSystemReadWriteOptions& aOptions, ErrorResult& aRv) {
|
||||
if (!mActor) {
|
||||
aRv.ThrowInvalidStateError("SyncAccessHandle is closed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc = mActor->MutableFileDescPtr();
|
||||
|
||||
// read directly from filehandle, blocking
|
||||
|
||||
// Handle seek before read ('at')
|
||||
if (aOptions.mAt.WasPassed()) {
|
||||
uint64_t at = aOptions.mAt.Value();
|
||||
LOG(("%p: Seeking to %" PRIu64, fileDesc, at));
|
||||
int64_t where = PR_Seek64(fileDesc, (PROffset64)at, PR_SEEK_SET);
|
||||
if (where == -1) {
|
||||
LOG(("Read at %" PRIu64 " failed to seek (errno %d)", at, errno));
|
||||
return 0;
|
||||
}
|
||||
if (where != (int64_t)at) {
|
||||
LOG(("Read at %" PRIu64 " failed to seek (%" PRId64 " instead)", at,
|
||||
where));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* data;
|
||||
size_t length;
|
||||
if (aBuffer.IsArrayBuffer()) {
|
||||
const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
|
||||
buffer.ComputeState();
|
||||
data = buffer.Data();
|
||||
length = buffer.Length();
|
||||
} else if (aBuffer.IsArrayBufferView()) {
|
||||
const ArrayBufferView& buffer = aBuffer.GetAsArrayBufferView();
|
||||
buffer.ComputeState();
|
||||
data = buffer.Data();
|
||||
length = buffer.Length();
|
||||
} else {
|
||||
// really impossible
|
||||
LOG(("Impossible read source"));
|
||||
return 0;
|
||||
}
|
||||
// for read starting past the end of the file, return 0, which should happen
|
||||
// automatically
|
||||
LOG(("%p: Reading %zu bytes", fileDesc, length));
|
||||
// Unfortunately, PR_Read() is limited to int32
|
||||
uint64_t result = 0;
|
||||
while (length > 0) {
|
||||
PRInt32 iter_len = (length > PR_INT32_MAX) ? PR_INT32_MAX : length;
|
||||
PRInt32 temp = PR_Read(fileDesc, data, iter_len);
|
||||
if (temp == -1 || temp == 0 /* EOF*/) {
|
||||
return result; // per spec, 2.6.1 #11
|
||||
}
|
||||
result += temp;
|
||||
length -= temp;
|
||||
}
|
||||
return result;
|
||||
const FileSystemReadWriteOptions& aOptions) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t FileSystemSyncAccessHandle::Write(
|
||||
const MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer,
|
||||
const FileSystemReadWriteOptions& aOptions, ErrorResult& aRv) {
|
||||
if (!mActor) {
|
||||
aRv.ThrowInvalidStateError("SyncAccessHandle is closed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc = mActor->MutableFileDescPtr();
|
||||
|
||||
// Write directly from filehandle, blocking
|
||||
|
||||
// Handle seek before write ('at')
|
||||
if (aOptions.mAt.WasPassed()) {
|
||||
uint64_t at = aOptions.mAt.Value();
|
||||
LOG(("%p: Seeking to %" PRIu64, fileDesc, at));
|
||||
int64_t where = PR_Seek64(fileDesc, (PROffset64)at, PR_SEEK_SET);
|
||||
if (where == -1) {
|
||||
LOG(("Write at %" PRIu64 " failed to seek (errno %d)", at, errno));
|
||||
return 0;
|
||||
}
|
||||
if (where != (int64_t)at) {
|
||||
LOG(("Write at %" PRIu64 " failed to seek (%" PRId64 " instead)", at,
|
||||
where));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// if we seek past the end of the file and write, it implicitly extends it
|
||||
// with 0's
|
||||
const uint8_t* data;
|
||||
size_t length;
|
||||
if (aBuffer.IsArrayBuffer()) {
|
||||
const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
|
||||
buffer.ComputeState();
|
||||
data = buffer.Data();
|
||||
length = buffer.Length();
|
||||
} else if (aBuffer.IsArrayBufferView()) {
|
||||
const ArrayBufferView& buffer = aBuffer.GetAsArrayBufferView();
|
||||
buffer.ComputeState();
|
||||
data = buffer.Data();
|
||||
length = buffer.Length();
|
||||
} else {
|
||||
LOG(("Impossible write source"));
|
||||
return 0;
|
||||
}
|
||||
LOG(("%p: Writing %zu bytes", fileDesc, length));
|
||||
// Unfortunately, PR_Write() is limited to int32
|
||||
uint64_t result = 0;
|
||||
while (length > 0) {
|
||||
PRInt32 iter_len = (length > PR_INT32_MAX) ? PR_INT32_MAX : length;
|
||||
PRInt32 temp = PR_Write(fileDesc, data, iter_len);
|
||||
if (temp == -1) {
|
||||
return result; // per spec, 2.6.2 #13
|
||||
}
|
||||
result += temp;
|
||||
length -= temp;
|
||||
}
|
||||
return result;
|
||||
const FileSystemReadWriteOptions& aOptions) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> FileSystemSyncAccessHandle::Truncate(
|
||||
|
@ -250,20 +52,7 @@ already_AddRefed<Promise> FileSystemSyncAccessHandle::Truncate(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mActor) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc = mActor->MutableFileDescPtr();
|
||||
|
||||
// truncate filehandle (can extend with 0's)
|
||||
LOG_DEBUG(("%p: Truncate to %" PRIu64, fileDesc, aSize));
|
||||
if (NS_WARN_IF(NS_FAILED(TruncFile(fileDesc, aSize)))) {
|
||||
promise->MaybeReject(NS_ErrorAccordingToNSPR());
|
||||
} else {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
}
|
||||
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -275,21 +64,7 @@ already_AddRefed<Promise> FileSystemSyncAccessHandle::GetSize(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mActor) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc = mActor->MutableFileDescPtr();
|
||||
|
||||
// get current size of filehandle
|
||||
PRFileInfo64 info;
|
||||
if (PR_GetOpenFileInfo64(fileDesc, &info) == PR_FAILURE) {
|
||||
promise->MaybeReject(NS_ERROR_FAILURE);
|
||||
} else {
|
||||
LOG_DEBUG(("%p: GetSize %" PRIu64, fileDesc, info.size));
|
||||
promise->MaybeResolve(int64_t(info.size));
|
||||
}
|
||||
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -301,21 +76,7 @@ already_AddRefed<Promise> FileSystemSyncAccessHandle::Flush(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mActor) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc = mActor->MutableFileDescPtr();
|
||||
|
||||
// flush filehandle
|
||||
LOG_DEBUG(("%p: Flush", fileDesc));
|
||||
int32_t cnt = PR_Sync(fileDesc);
|
||||
if (cnt == -1) {
|
||||
promise->MaybeReject(NS_ErrorAccordingToNSPR());
|
||||
} else {
|
||||
promise->MaybeResolve(NS_OK);
|
||||
}
|
||||
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -327,21 +88,9 @@ already_AddRefed<Promise> FileSystemSyncAccessHandle::Close(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mActor) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc = mActor->MutableFileDescPtr();
|
||||
|
||||
MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Debug,
|
||||
("%p: Closing", fileDesc));
|
||||
|
||||
mActor->Close();
|
||||
MOZ_ASSERT(!mActor);
|
||||
|
||||
promise->MaybeResolveWithUndefined();
|
||||
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef DOM_FS_FILESYSTEMSYNCACCESSHANDLE_H_
|
||||
#define DOM_FS_FILESYSTEMSYNCACCESSHANDLE_H_
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
@ -16,45 +14,21 @@
|
|||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
extern LazyLogModule gOPFSLog;
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace ipc {
|
||||
class FileDescriptor;
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
class FileSystemAccessHandleChild;
|
||||
struct FileSystemReadWriteOptions;
|
||||
class FileSystemManager;
|
||||
class MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer;
|
||||
class Promise;
|
||||
|
||||
namespace fs {
|
||||
class FileSystemRequestHandler;
|
||||
} // namespace fs
|
||||
|
||||
class FileSystemSyncAccessHandle final : public nsISupports,
|
||||
public nsWrapperCache {
|
||||
public:
|
||||
FileSystemSyncAccessHandle(nsIGlobalObject* aGlobal,
|
||||
RefPtr<FileSystemManager>& aManager,
|
||||
RefPtr<FileSystemAccessHandleChild> aActor,
|
||||
const fs::FileSystemEntryMetadata& aMetadata,
|
||||
fs::FileSystemRequestHandler* aRequestHandler);
|
||||
|
||||
FileSystemSyncAccessHandle(nsIGlobalObject* aGlobal,
|
||||
RefPtr<FileSystemManager>& aManager,
|
||||
RefPtr<FileSystemAccessHandleChild> aActor,
|
||||
const fs::FileSystemEntryMetadata& aMetadata);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(FileSystemSyncAccessHandle)
|
||||
|
||||
void ClearActor();
|
||||
|
||||
// WebIDL Boilerplate
|
||||
nsIGlobalObject* GetParentObject() const;
|
||||
|
||||
|
@ -64,11 +38,11 @@ class FileSystemSyncAccessHandle final : public nsISupports,
|
|||
// WebIDL Interface
|
||||
uint64_t Read(
|
||||
const MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer,
|
||||
const FileSystemReadWriteOptions& aOptions, ErrorResult& aRv);
|
||||
const FileSystemReadWriteOptions& aOptions);
|
||||
|
||||
uint64_t Write(
|
||||
const MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer,
|
||||
const FileSystemReadWriteOptions& aOptions, ErrorResult& aRv);
|
||||
const FileSystemReadWriteOptions& aOptions);
|
||||
|
||||
already_AddRefed<Promise> Truncate(uint64_t aSize, ErrorResult& aError);
|
||||
|
||||
|
@ -79,17 +53,9 @@ class FileSystemSyncAccessHandle final : public nsISupports,
|
|||
already_AddRefed<Promise> Close(ErrorResult& aError);
|
||||
|
||||
private:
|
||||
virtual ~FileSystemSyncAccessHandle();
|
||||
virtual ~FileSystemSyncAccessHandle() = default;
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
|
||||
RefPtr<FileSystemManager> mManager;
|
||||
|
||||
RefPtr<FileSystemAccessHandleChild> mActor;
|
||||
|
||||
const fs::FileSystemEntryMetadata mMetadata;
|
||||
|
||||
const UniquePtr<fs::FileSystemRequestHandler> mRequestHandler;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "FileSystemAccessHandleChild.h"
|
||||
|
||||
#include "mozilla/dom/FileSystemSyncAccessHandle.h"
|
||||
#include "private/pprio.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
FileSystemAccessHandleChild::FileSystemAccessHandleChild(
|
||||
const ::mozilla::ipc::FileDescriptor& aFileDescriptor)
|
||||
: mAccessHandle(nullptr) {
|
||||
auto rawFD = aFileDescriptor.ClonePlatformHandle();
|
||||
mFileDesc = PR_ImportFile(PROsfd(rawFD.release()));
|
||||
}
|
||||
|
||||
FileSystemAccessHandleChild::~FileSystemAccessHandleChild() = default;
|
||||
|
||||
void FileSystemAccessHandleChild::SetAccessHandle(
|
||||
FileSystemSyncAccessHandle* aAccessHandle) {
|
||||
MOZ_ASSERT(aAccessHandle);
|
||||
MOZ_ASSERT(!mAccessHandle);
|
||||
|
||||
mAccessHandle = aAccessHandle;
|
||||
}
|
||||
|
||||
PRFileDesc* FileSystemAccessHandleChild::MutableFileDescPtr() const {
|
||||
MOZ_ASSERT(mFileDesc);
|
||||
|
||||
return mFileDesc;
|
||||
}
|
||||
|
||||
void FileSystemAccessHandleChild::Close() {
|
||||
MOZ_ASSERT(mFileDesc);
|
||||
|
||||
PR_Close(mFileDesc);
|
||||
mFileDesc = nullptr;
|
||||
|
||||
PFileSystemAccessHandleChild::Send__delete__(this);
|
||||
}
|
||||
|
||||
void FileSystemAccessHandleChild::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
if (mFileDesc) {
|
||||
PR_Close(mFileDesc);
|
||||
mFileDesc = nullptr;
|
||||
}
|
||||
|
||||
if (mAccessHandle) {
|
||||
mAccessHandle->ClearActor();
|
||||
mAccessHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -1,42 +0,0 @@
|
|||
/* -*- 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 DOM_FS_CHILD_FILESYSTEMACCESSHANDLECHILD_H_
|
||||
#define DOM_FS_CHILD_FILESYSTEMACCESSHANDLECHILD_H_
|
||||
|
||||
#include "mozilla/dom/PFileSystemAccessHandleChild.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class FileSystemSyncAccessHandle;
|
||||
|
||||
class FileSystemAccessHandleChild : public PFileSystemAccessHandleChild {
|
||||
public:
|
||||
explicit FileSystemAccessHandleChild(const FileDescriptor& aFileDescriptor);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(FileSystemAccessHandleChild, override)
|
||||
|
||||
void SetAccessHandle(FileSystemSyncAccessHandle* aAccessHandle);
|
||||
|
||||
PRFileDesc* MutableFileDescPtr() const;
|
||||
|
||||
void Close();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
virtual ~FileSystemAccessHandleChild();
|
||||
|
||||
// Use a weak ref so actor does not hold DOM object alive past content use.
|
||||
// The weak reference is cleared in FileSystemSyncAccessHandle destructor.
|
||||
FileSystemSyncAccessHandle* MOZ_NON_OWNING_REF mAccessHandle;
|
||||
|
||||
PRFileDesc* mFileDesc;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // DOM_FS_CHILD_FILESYSTEMACCESSHANDLECHILD_H_
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "FileSystemManagerChild.h"
|
||||
|
||||
#include "FileSystemAccessHandleChild.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
already_AddRefed<PFileSystemAccessHandleChild>
|
||||
FileSystemManagerChild::AllocPFileSystemAccessHandleChild(
|
||||
const FileDescriptor& aFileDescriptor) {
|
||||
return MakeAndAddRef<FileSystemAccessHandleChild>(aFileDescriptor);
|
||||
}
|
||||
|
||||
::mozilla::ipc::IPCResult FileSystemManagerChild::RecvCloseAll(
|
||||
CloseAllResolver&& aResolver) {
|
||||
for (const auto& item : ManagedPFileSystemAccessHandleChild()) {
|
||||
auto* child = static_cast<FileSystemAccessHandleChild*>(item);
|
||||
child->Close();
|
||||
}
|
||||
|
||||
aResolver(NS_OK);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -12,14 +12,93 @@
|
|||
|
||||
namespace mozilla::dom {
|
||||
|
||||
// XXX This can be greatly simplified if bug 1786484 gets fixed.
|
||||
// See: https://phabricator.services.mozilla.com/D155351
|
||||
// https://phabricator.services.mozilla.com/D155352
|
||||
|
||||
class FileSystemManagerChild : public PFileSystemManagerChild {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(FileSystemManagerChild, Destroy())
|
||||
|
||||
already_AddRefed<PFileSystemAccessHandleChild>
|
||||
AllocPFileSystemAccessHandleChild(const FileDescriptor& aFileDescriptor);
|
||||
virtual void SendGetRootHandle(
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendGetRootHandleMsg(
|
||||
std::forward<
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
::mozilla::ipc::IPCResult RecvCloseAll(CloseAllResolver&& aResolver);
|
||||
virtual void SendGetDirectoryHandle(
|
||||
const FileSystemGetHandleRequest& aRequest,
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendGetDirectoryHandleMsg(
|
||||
aRequest,
|
||||
std::forward<
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
virtual void SendGetFileHandle(
|
||||
const FileSystemGetHandleRequest& aRequest,
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendGetFileHandleMsg(
|
||||
aRequest,
|
||||
std::forward<
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetHandleResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
virtual void SendGetFile(
|
||||
const FileSystemGetFileRequest& aRequest,
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetFileResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendGetFileMsg(
|
||||
aRequest,
|
||||
std::forward<mozilla::ipc::ResolveCallback<FileSystemGetFileResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
virtual void SendResolve(
|
||||
const FileSystemResolveRequest& aRequest,
|
||||
mozilla::ipc::ResolveCallback<FileSystemResolveResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendResolveMsg(
|
||||
aRequest,
|
||||
std::forward<mozilla::ipc::ResolveCallback<FileSystemResolveResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
virtual void SendGetEntries(
|
||||
const FileSystemGetEntriesRequest& aRequest,
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetEntriesResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendGetEntriesMsg(
|
||||
aRequest,
|
||||
std::forward<
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetEntriesResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
virtual void SendRemoveEntry(
|
||||
const FileSystemRemoveEntryRequest& aRequest,
|
||||
mozilla::ipc::ResolveCallback<FileSystemRemoveEntryResponse>&& aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject) {
|
||||
PFileSystemManagerChild::SendRemoveEntryMsg(
|
||||
aRequest,
|
||||
std::forward<
|
||||
mozilla::ipc::ResolveCallback<FileSystemRemoveEntryResponse>>(
|
||||
aResolve),
|
||||
std::forward<mozilla::ipc::RejectCallback>(aReject));
|
||||
}
|
||||
|
||||
virtual void Shutdown() {
|
||||
if (CanSend()) {
|
||||
|
@ -34,6 +113,21 @@ class FileSystemManagerChild : public PFileSystemManagerChild {
|
|||
Shutdown();
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
using PFileSystemManagerChild::SendGetRootHandleMsg;
|
||||
|
||||
using PFileSystemManagerChild::SendGetDirectoryHandleMsg;
|
||||
|
||||
using PFileSystemManagerChild::SendGetFileHandleMsg;
|
||||
|
||||
using PFileSystemManagerChild::SendGetFileMsg;
|
||||
|
||||
using PFileSystemManagerChild::SendResolveMsg;
|
||||
|
||||
using PFileSystemManagerChild::SendGetEntriesMsg;
|
||||
|
||||
using PFileSystemManagerChild::SendRemoveEntryMsg;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -9,26 +9,14 @@
|
|||
#include "FileSystemEntryMetadataArray.h"
|
||||
#include "fs/FileSystemConstants.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileSystemAccessHandleChild.h"
|
||||
#include "mozilla/dom/FileSystemDirectoryHandle.h"
|
||||
#include "mozilla/dom/FileSystemFileHandle.h"
|
||||
#include "mozilla/dom/FileSystemHandle.h"
|
||||
#include "mozilla/dom/FileSystemHelpers.h"
|
||||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "mozilla/dom/FileSystemManagerChild.h"
|
||||
#include "mozilla/dom/FileSystemSyncAccessHandle.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
|
||||
namespace mozilla {
|
||||
extern LazyLogModule gOPFSLog;
|
||||
}
|
||||
|
||||
#define LOG(args) MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Verbose, args)
|
||||
|
||||
#define LOG_DEBUG(args) \
|
||||
MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
namespace mozilla::dom::fs {
|
||||
|
||||
using mozilla::ipc::RejectCallback;
|
||||
|
@ -101,22 +89,6 @@ RefPtr<FileSystemFileHandle> MakeResolution(
|
|||
return result;
|
||||
}
|
||||
|
||||
RefPtr<FileSystemSyncAccessHandle> MakeResolution(
|
||||
nsIGlobalObject* aGlobal, FileSystemGetAccessHandleResponse&& aResponse,
|
||||
const RefPtr<FileSystemSyncAccessHandle>& /* aReturns */,
|
||||
const FileSystemEntryMetadata& aMetadata,
|
||||
RefPtr<FileSystemManager>& aManager) {
|
||||
auto* const actor = static_cast<FileSystemAccessHandleChild*>(
|
||||
aResponse.get_PFileSystemAccessHandleChild());
|
||||
|
||||
RefPtr<FileSystemSyncAccessHandle> result =
|
||||
new FileSystemSyncAccessHandle(aGlobal, aManager, actor, aMetadata);
|
||||
|
||||
actor->SetAccessHandle(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RefPtr<File> MakeResolution(nsIGlobalObject* aGlobal,
|
||||
FileSystemGetFileResponse&& aResponse,
|
||||
const RefPtr<File>& /* aResult */,
|
||||
|
@ -161,59 +133,14 @@ void ResolveCallback(
|
|||
|
||||
MOZ_ASSERT(FileSystemRemoveEntryResponse::Tnsresult == aResponse.type());
|
||||
const auto& status = aResponse.get_nsresult();
|
||||
switch (status) {
|
||||
case NS_ERROR_FILE_ACCESS_DENIED:
|
||||
aPromise->MaybeRejectWithNotAllowedError("Permission denied");
|
||||
break;
|
||||
case NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR:
|
||||
aPromise->MaybeRejectWithInvalidModificationError("Disallowed by system");
|
||||
break;
|
||||
default:
|
||||
if (NS_FAILED(status)) {
|
||||
aPromise->MaybeRejectWithUnknownError("Unknown failure");
|
||||
} else {
|
||||
aPromise->MaybeResolveWithUndefined();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void ResolveCallback(
|
||||
FileSystemMoveEntryResponse&& aResponse,
|
||||
RefPtr<Promise> aPromise) { // NOLINT(performance-unnecessary-value-param)
|
||||
MOZ_ASSERT(aPromise);
|
||||
QM_TRY(OkIf(Promise::PromiseState::Pending == aPromise->State()), QM_VOID);
|
||||
|
||||
MOZ_ASSERT(FileSystemMoveEntryResponse::Tnsresult == aResponse.type());
|
||||
const auto& status = aResponse.get_nsresult();
|
||||
switch (status) {
|
||||
case NS_OK:
|
||||
aPromise->MaybeResolveWithUndefined();
|
||||
break;
|
||||
case NS_ERROR_FILE_ACCESS_DENIED:
|
||||
aPromise->MaybeRejectWithNotAllowedError("Permission denied");
|
||||
break;
|
||||
case NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR:
|
||||
aPromise->MaybeRejectWithInvalidModificationError("Disallowed by system");
|
||||
break;
|
||||
case NS_ERROR_DOM_NOT_FOUND_ERR:
|
||||
aPromise->MaybeRejectWithNotFoundError("Entry not found");
|
||||
break;
|
||||
case NS_ERROR_DOM_INVALID_MODIFICATION_ERR:
|
||||
aPromise->MaybeRejectWithInvalidModificationError("Invalid modification");
|
||||
break;
|
||||
case NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR:
|
||||
aPromise->MaybeRejectWithNoModificationAllowedError(
|
||||
"No modification allowed");
|
||||
break;
|
||||
default:
|
||||
if (NS_FAILED(status)) {
|
||||
aPromise->MaybeRejectWithUnknownError("Unknown failure");
|
||||
} else {
|
||||
aPromise->MaybeResolveWithUndefined();
|
||||
}
|
||||
break;
|
||||
if (NS_ERROR_FILE_ACCESS_DENIED == status) {
|
||||
aPromise->MaybeRejectWithNotAllowedError("Permission denied");
|
||||
} else if (NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR == status) {
|
||||
aPromise->MaybeRejectWithInvalidModificationError("Disallowed by system");
|
||||
} else if (NS_FAILED(status)) {
|
||||
aPromise->MaybeRejectWithUnknownError("Unknown failure");
|
||||
} else {
|
||||
aPromise->MaybeResolveWithUndefined();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,12 +258,6 @@ void FileSystemRequestHandler::GetDirectoryHandle(
|
|||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(!aDirectory.parentId().IsEmpty());
|
||||
MOZ_ASSERT(aPromise);
|
||||
LOG(("getDirectoryHandle"));
|
||||
|
||||
if (!IsValidName(aDirectory.childName())) {
|
||||
aPromise->MaybeRejectWithTypeError("Invalid directory name");
|
||||
return;
|
||||
}
|
||||
|
||||
FileSystemGetHandleRequest request(aDirectory, aCreate);
|
||||
|
||||
|
@ -360,12 +281,6 @@ void FileSystemRequestHandler::GetFileHandle(
|
|||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(!aFile.parentId().IsEmpty());
|
||||
MOZ_ASSERT(aPromise);
|
||||
LOG(("getFileHandle"));
|
||||
|
||||
if (!IsValidName(aFile.childName())) {
|
||||
aPromise->MaybeRejectWithTypeError("Invalid filename");
|
||||
return;
|
||||
}
|
||||
|
||||
FileSystemGetHandleRequest request(aFile, aCreate);
|
||||
|
||||
|
@ -382,26 +297,6 @@ void FileSystemRequestHandler::GetFileHandle(
|
|||
std::move(onReject));
|
||||
}
|
||||
|
||||
void FileSystemRequestHandler::GetAccessHandle(
|
||||
RefPtr<FileSystemManager>& aManager, const FileSystemEntryMetadata& aFile,
|
||||
const RefPtr<Promise>& aPromise) {
|
||||
MOZ_ASSERT(aPromise);
|
||||
LOG(("getAccessHandle"));
|
||||
|
||||
FileSystemGetAccessHandleRequest request(aFile.entryId());
|
||||
|
||||
auto&& onResolve = SelectResolveCallback<FileSystemGetAccessHandleResponse,
|
||||
RefPtr<FileSystemSyncAccessHandle>>(
|
||||
aPromise, aFile, aManager);
|
||||
auto&& onReject = GetRejectCallback(aPromise);
|
||||
|
||||
QM_TRY(OkIf(aManager->Actor()), QM_VOID, [aPromise](const auto&) {
|
||||
aPromise->MaybeRejectWithUnknownError("Invalid actor");
|
||||
});
|
||||
aManager->Actor()->SendGetAccessHandle(request, std::move(onResolve),
|
||||
std::move(onReject));
|
||||
}
|
||||
|
||||
void FileSystemRequestHandler::GetFile(
|
||||
RefPtr<FileSystemManager>& aManager, const FileSystemEntryMetadata& aFile,
|
||||
RefPtr<Promise> aPromise) { // NOLINT(performance-unnecessary-value-param)
|
||||
|
@ -454,12 +349,6 @@ void FileSystemRequestHandler::RemoveEntry(
|
|||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(!aEntry.parentId().IsEmpty());
|
||||
MOZ_ASSERT(aPromise);
|
||||
LOG(("removeEntry"));
|
||||
|
||||
if (!IsValidName(aEntry.childName())) {
|
||||
aPromise->MaybeRejectWithTypeError("Invalid name");
|
||||
return;
|
||||
}
|
||||
|
||||
FileSystemRemoveEntryRequest request(aEntry, aRecursive);
|
||||
|
||||
|
@ -475,63 +364,6 @@ void FileSystemRequestHandler::RemoveEntry(
|
|||
std::move(onReject));
|
||||
}
|
||||
|
||||
void FileSystemRequestHandler::MoveEntry(
|
||||
RefPtr<FileSystemManager>& aManager, FileSystemHandle* aHandle,
|
||||
const FileSystemEntryMetadata& aEntry,
|
||||
const FileSystemChildMetadata& aNewEntry,
|
||||
RefPtr<Promise> aPromise) { // NOLINT(performance-unnecessary-value-param)
|
||||
MOZ_ASSERT(aPromise);
|
||||
LOG(("MoveEntry"));
|
||||
|
||||
// reject invalid names: empty, path separators, current & parent directories
|
||||
if (!IsValidName(aNewEntry.childName())) {
|
||||
aPromise->MaybeRejectWithTypeError("Invalid name");
|
||||
return;
|
||||
}
|
||||
|
||||
FileSystemMoveEntryRequest request(aEntry, aNewEntry);
|
||||
|
||||
RefPtr<FileSystemHandle> handle(aHandle);
|
||||
auto&& onResolve =
|
||||
SelectResolveCallback<FileSystemMoveEntryResponse, void>(aPromise);
|
||||
|
||||
auto&& onReject = GetRejectCallback(aPromise);
|
||||
|
||||
QM_TRY(OkIf(aManager && aManager->Actor()), QM_VOID, [aPromise](const auto&) {
|
||||
aPromise->MaybeRejectWithUnknownError("Invalid actor");
|
||||
});
|
||||
aManager->Actor()->SendMoveEntry(request, std::move(onResolve),
|
||||
std::move(onReject));
|
||||
}
|
||||
|
||||
void FileSystemRequestHandler::RenameEntry(
|
||||
RefPtr<FileSystemManager>& aManager, FileSystemHandle* aHandle,
|
||||
const FileSystemEntryMetadata& aEntry, const Name& aName,
|
||||
RefPtr<Promise> aPromise) { // NOLINT(performance-unnecessary-value-param)
|
||||
MOZ_ASSERT(!aEntry.entryId().IsEmpty());
|
||||
MOZ_ASSERT(aPromise);
|
||||
LOG(("RenameEntry"));
|
||||
|
||||
// reject invalid names: empty, path separators, current & parent directories
|
||||
if (!IsValidName(aName)) {
|
||||
aPromise->MaybeRejectWithTypeError("Invalid name");
|
||||
return;
|
||||
}
|
||||
|
||||
FileSystemRenameEntryRequest request(aEntry, aName);
|
||||
|
||||
auto&& onResolve =
|
||||
SelectResolveCallback<FileSystemMoveEntryResponse, void>(aPromise);
|
||||
|
||||
auto&& onReject = GetRejectCallback(aPromise);
|
||||
|
||||
QM_TRY(OkIf(aManager && aManager->Actor()), QM_VOID, [aPromise](const auto&) {
|
||||
aPromise->MaybeRejectWithUnknownError("Invalid actor");
|
||||
});
|
||||
aManager->Actor()->SendRenameEntry(request, std::move(onResolve),
|
||||
std::move(onReject));
|
||||
}
|
||||
|
||||
void FileSystemRequestHandler::Resolve(
|
||||
RefPtr<FileSystemManager>& aManager,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
|
|
|
@ -5,16 +5,13 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
"FileSystemAccessHandleChild.h",
|
||||
"FileSystemManagerChild.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"FileSystemAccessHandleChild.cpp",
|
||||
"FileSystemBackgroundRequestHandler.cpp",
|
||||
"FileSystemChildFactory.cpp",
|
||||
"FileSystemDirectoryIteratorFactory.cpp",
|
||||
"FileSystemManagerChild.cpp",
|
||||
"FileSystemRequestHandler.cpp",
|
||||
]
|
||||
|
||||
|
|
|
@ -42,10 +42,6 @@ class FileSystemRequestHandler {
|
|||
const FileSystemEntryMetadata& aFile,
|
||||
RefPtr<Promise> aPromise);
|
||||
|
||||
virtual void GetAccessHandle(RefPtr<FileSystemManager>& aManager,
|
||||
const FileSystemEntryMetadata& aFile,
|
||||
const RefPtr<Promise>& aPromise);
|
||||
|
||||
virtual void GetEntries(RefPtr<FileSystemManager>& aManager,
|
||||
const EntryId& aDirectory, PageNumber aPage,
|
||||
RefPtr<Promise> aPromise,
|
||||
|
@ -55,17 +51,6 @@ class FileSystemRequestHandler {
|
|||
const FileSystemChildMetadata& aEntry,
|
||||
bool aRecursive, RefPtr<Promise> aPromise);
|
||||
|
||||
virtual void MoveEntry(RefPtr<FileSystemManager>& aManager,
|
||||
FileSystemHandle* aHandle,
|
||||
const FileSystemEntryMetadata& aEntry,
|
||||
const FileSystemChildMetadata& aNewEntry,
|
||||
RefPtr<Promise> aPromise);
|
||||
|
||||
virtual void RenameEntry(RefPtr<FileSystemManager>& aManager,
|
||||
FileSystemHandle* aHandle,
|
||||
const FileSystemEntryMetadata& aEntry,
|
||||
const Name& aName, RefPtr<Promise> aPromise);
|
||||
|
||||
virtual void Resolve(RefPtr<FileSystemManager>& aManager,
|
||||
const FileSystemEntryPair& aEndpoints,
|
||||
RefPtr<Promise> aPromise);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "FileSystemAccessHandleParent.h"
|
||||
|
||||
#include "FileSystemDataManager.h"
|
||||
#include "mozilla/dom/FileSystemManagerParent.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
FileSystemAccessHandleParent::FileSystemAccessHandleParent(
|
||||
RefPtr<FileSystemManagerParent> aManager, const fs::EntryId& aEntryId)
|
||||
: mManager(std::move(aManager)), mEntryId(aEntryId) {}
|
||||
|
||||
FileSystemAccessHandleParent::~FileSystemAccessHandleParent() = default;
|
||||
|
||||
void FileSystemAccessHandleParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
LOG(("Closing SyncAccessHandle"));
|
||||
mManager->DataManagerStrongRef()->UnlockExclusive(mEntryId);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- 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 DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_
|
||||
#define DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_
|
||||
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/PFileSystemAccessHandleParent.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class FileSystemManagerParent;
|
||||
|
||||
class FileSystemAccessHandleParent : public PFileSystemAccessHandleParent {
|
||||
public:
|
||||
FileSystemAccessHandleParent(RefPtr<FileSystemManagerParent> aManager,
|
||||
const fs::EntryId& aEntryId);
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileSystemAccessHandleParent, override)
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
virtual ~FileSystemAccessHandleParent();
|
||||
|
||||
const RefPtr<FileSystemManagerParent> mManager;
|
||||
|
||||
const fs::EntryId mEntryId;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_
|
|
@ -12,8 +12,8 @@
|
|||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla::dom::fs::data {
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#ifndef DOM_FS_PARENT_FILESYSTEMHASHSOURCE_H_
|
||||
#define DOM_FS_PARENT_FILESYSTEMHASHSOURCE_H_
|
||||
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/dom/QMResult.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "FileSystemDatabaseManager.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/FileSystemAccessHandleParent.h"
|
||||
#include "mozilla/dom/FileSystemDataManager.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/QMResult.h"
|
||||
|
@ -16,7 +15,6 @@
|
|||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -42,33 +40,17 @@ FileSystemManagerParent::~FileSystemManagerParent() {
|
|||
LOG(("Destroying FileSystemManagerParent %p", this));
|
||||
}
|
||||
|
||||
void FileSystemManagerParent::AssertIsOnIOTarget() const {
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
mDataManager->AssertIsOnIOTarget();
|
||||
}
|
||||
|
||||
const RefPtr<fs::data::FileSystemDataManager>&
|
||||
FileSystemManagerParent::DataManagerStrongRef() const {
|
||||
return mDataManager;
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetRootHandle(
|
||||
GetRootHandleResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetRootHandleMsg(
|
||||
GetRootHandleMsgResolver&& aResolver) {
|
||||
FileSystemGetHandleResponse response(mRootEntry);
|
||||
aResolver(response);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetDirectoryHandle(
|
||||
IPCResult FileSystemManagerParent::RecvGetDirectoryHandleMsg(
|
||||
FileSystemGetHandleRequest&& aRequest,
|
||||
GetDirectoryHandleResolver&& aResolver) {
|
||||
LOG(("GetDirectoryHandle %s ",
|
||||
NS_ConvertUTF16toUTF8(aRequest.handle().childName()).get()));
|
||||
AssertIsOnIOTarget();
|
||||
GetDirectoryHandleMsgResolver&& aResolver) {
|
||||
MOZ_ASSERT(!aRequest.handle().parentId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
|
@ -89,9 +71,9 @@ IPCResult FileSystemManagerParent::RecvGetDirectoryHandle(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetFileHandle(
|
||||
FileSystemGetHandleRequest&& aRequest, GetFileHandleResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
IPCResult FileSystemManagerParent::RecvGetFileHandleMsg(
|
||||
FileSystemGetHandleRequest&& aRequest,
|
||||
GetFileHandleMsgResolver&& aResolver) {
|
||||
MOZ_ASSERT(!aRequest.handle().parentId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
|
@ -108,80 +90,20 @@ IPCResult FileSystemManagerParent::RecvGetFileHandle(
|
|||
|
||||
FileSystemGetHandleResponse response(entryId);
|
||||
aResolver(response);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FileSystemManagerParent::RecvGetAccessHandle(
|
||||
const FileSystemGetAccessHandleRequest& aRequest,
|
||||
GetAccessHandleResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
if (!mDataManager->LockExclusive(aRequest.entryId())) {
|
||||
aResolver(NS_ERROR_FAILURE);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
auto autoUnlock =
|
||||
MakeScopeExit([self = RefPtr<FileSystemManagerParent>(this), aRequest] {
|
||||
self->mDataManager->UnlockExclusive(aRequest.entryId());
|
||||
});
|
||||
|
||||
auto reportError = [aResolver](nsresult rv) { aResolver(rv); };
|
||||
|
||||
nsString type;
|
||||
fs::TimeStamp lastModifiedMilliSeconds;
|
||||
fs::Path path;
|
||||
nsCOMPtr<nsIFile> file;
|
||||
QM_TRY(MOZ_TO_RESULT(mDataManager->MutableDatabaseManagerPtr()->GetFile(
|
||||
{aRequest.entryId(), aRequest.entryId()}, type,
|
||||
lastModifiedMilliSeconds, path, file)),
|
||||
IPC_OK(), reportError);
|
||||
|
||||
if (MOZ_LOG_TEST(gOPFSLog, mozilla::LogLevel::Debug)) {
|
||||
nsAutoString path;
|
||||
if (NS_SUCCEEDED(file->GetPath(path))) {
|
||||
LOG(("Opening %s", NS_ConvertUTF16toUTF8(path).get()));
|
||||
}
|
||||
}
|
||||
|
||||
FILE* fileHandle;
|
||||
QM_TRY(MOZ_TO_RESULT(file->OpenANSIFileDesc("r+", &fileHandle)), IPC_OK(),
|
||||
reportError);
|
||||
|
||||
LOG(("Opened"));
|
||||
|
||||
FileDescriptor fileDescriptor =
|
||||
mozilla::ipc::FILEToFileDescriptor(fileHandle);
|
||||
|
||||
auto accessHandleParent =
|
||||
MakeRefPtr<FileSystemAccessHandleParent>(this, aRequest.entryId());
|
||||
|
||||
autoUnlock.release();
|
||||
|
||||
if (!SendPFileSystemAccessHandleConstructor(accessHandleParent,
|
||||
fileDescriptor)) {
|
||||
aResolver(NS_ERROR_FAILURE);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
aResolver(FileSystemGetAccessHandleResponse(accessHandleParent));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetFile(
|
||||
FileSystemGetFileRequest&& aRequest, GetFileResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetFileMsg(
|
||||
FileSystemGetFileRequest&& aRequest, GetFileMsgResolver&& aResolver) {
|
||||
FileSystemGetFileResponse response(NS_ERROR_NOT_IMPLEMENTED);
|
||||
aResolver(response);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvResolve(
|
||||
FileSystemResolveRequest&& aRequest, ResolveResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
IPCResult FileSystemManagerParent::RecvResolveMsg(
|
||||
FileSystemResolveRequest&& aRequest, ResolveMsgResolver&& aResolver) {
|
||||
MOZ_ASSERT(!aRequest.endpoints().parentId().IsEmpty());
|
||||
MOZ_ASSERT(!aRequest.endpoints().childId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
@ -217,9 +139,8 @@ IPCResult FileSystemManagerParent::RecvResolve(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetEntries(
|
||||
FileSystemGetEntriesRequest&& aRequest, GetEntriesResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
IPCResult FileSystemManagerParent::RecvGetEntriesMsg(
|
||||
FileSystemGetEntriesRequest&& aRequest, GetEntriesMsgResolver&& aResolver) {
|
||||
MOZ_ASSERT(!aRequest.parentId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
|
@ -239,11 +160,9 @@ IPCResult FileSystemManagerParent::RecvGetEntries(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvRemoveEntry(
|
||||
FileSystemRemoveEntryRequest&& aRequest, RemoveEntryResolver&& aResolver) {
|
||||
LOG(("RemoveEntry %s",
|
||||
NS_ConvertUTF16toUTF8(aRequest.handle().childName()).get()));
|
||||
AssertIsOnIOTarget();
|
||||
IPCResult FileSystemManagerParent::RecvRemoveEntryMsg(
|
||||
FileSystemRemoveEntryRequest&& aRequest,
|
||||
RemoveEntryMsgResolver&& aResolver) {
|
||||
MOZ_ASSERT(!aRequest.handle().parentId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
|
@ -282,79 +201,23 @@ IPCResult FileSystemManagerParent::RecvRemoveEntry(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvMoveEntry(
|
||||
FileSystemMoveEntryRequest&& aRequest, MoveEntryResolver&& aResolver) {
|
||||
LOG(("MoveEntry %s to %s",
|
||||
NS_ConvertUTF16toUTF8(aRequest.handle().entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(aRequest.destHandle().childName()).get()));
|
||||
MOZ_ASSERT(!aRequest.handle().entryId().IsEmpty());
|
||||
MOZ_ASSERT(!aRequest.destHandle().parentId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
IPCResult FileSystemManagerParent::RecvCloseFile(
|
||||
FileSystemGetFileRequest&& aRequest) {
|
||||
LOG(("Closing file")); // painful to print out the id
|
||||
|
||||
auto reportError = [&aResolver](const QMResult& aRv) {
|
||||
FileSystemMoveEntryResponse response(ToNSResult(aRv));
|
||||
aResolver(response);
|
||||
};
|
||||
|
||||
QM_TRY_UNWRAP(EntryId parentId,
|
||||
mDataManager->MutableDatabaseManagerPtr()->GetParentEntryId(
|
||||
aRequest.handle().entryId()),
|
||||
IPC_OK(), reportError);
|
||||
FileSystemChildMetadata sourceHandle;
|
||||
sourceHandle.parentId() = parentId;
|
||||
sourceHandle.childName() = aRequest.handle().entryName();
|
||||
|
||||
QM_TRY_UNWRAP(bool moved,
|
||||
mDataManager->MutableDatabaseManagerPtr()->MoveEntry(
|
||||
sourceHandle, aRequest.destHandle()),
|
||||
IPC_OK(), reportError);
|
||||
|
||||
fs::FileSystemMoveEntryResponse response(moved ? NS_OK : NS_ERROR_FAILURE);
|
||||
aResolver(response);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvRenameEntry(
|
||||
FileSystemRenameEntryRequest&& aRequest, MoveEntryResolver&& aResolver) {
|
||||
// if destHandle's parentId is empty, then we're renaming in the same
|
||||
// directory
|
||||
LOG(("RenameEntry %s to %s",
|
||||
NS_ConvertUTF16toUTF8(aRequest.handle().entryName()).get(),
|
||||
NS_ConvertUTF16toUTF8(aRequest.name()).get()));
|
||||
MOZ_ASSERT(!aRequest.handle().entryId().IsEmpty());
|
||||
MOZ_ASSERT(mDataManager);
|
||||
|
||||
auto reportError = [&aResolver](const QMResult& aRv) {
|
||||
FileSystemMoveEntryResponse response(ToNSResult(aRv));
|
||||
aResolver(response);
|
||||
};
|
||||
|
||||
QM_TRY_UNWRAP(EntryId parentId,
|
||||
mDataManager->MutableDatabaseManagerPtr()->GetParentEntryId(
|
||||
aRequest.handle().entryId()),
|
||||
IPC_OK(), reportError);
|
||||
FileSystemChildMetadata sourceHandle;
|
||||
sourceHandle.parentId() = parentId;
|
||||
sourceHandle.childName() = aRequest.handle().entryName();
|
||||
|
||||
FileSystemChildMetadata newHandle;
|
||||
newHandle.parentId() = parentId;
|
||||
newHandle.childName() = aRequest.name();
|
||||
|
||||
QM_TRY_UNWRAP(bool moved,
|
||||
mDataManager->MutableDatabaseManagerPtr()->MoveEntry(
|
||||
sourceHandle, newHandle),
|
||||
IPC_OK(), reportError);
|
||||
|
||||
fs::FileSystemMoveEntryResponse response(moved ? NS_OK : NS_ERROR_FAILURE);
|
||||
IPCResult FileSystemManagerParent::RecvGetAccessHandle(
|
||||
FileSystemGetFileRequest&& aRequest, GetAccessHandleResolver&& aResolver) {
|
||||
FileSystemGetAccessHandleResponse response(NS_ERROR_NOT_IMPLEMENTED);
|
||||
aResolver(response);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult FileSystemManagerParent::RecvGetWritable(
|
||||
FileSystemGetFileRequest&& aRequest, GetWritableResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
FileSystemGetAccessHandleResponse response(NS_ERROR_NOT_IMPLEMENTED);
|
||||
aResolver(response);
|
||||
|
||||
|
@ -363,8 +226,6 @@ IPCResult FileSystemManagerParent::RecvGetWritable(
|
|||
|
||||
IPCResult FileSystemManagerParent::RecvNeedQuota(
|
||||
FileSystemQuotaRequest&& aRequest, NeedQuotaResolver&& aResolver) {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
aResolver(0u);
|
||||
|
||||
return IPC_OK();
|
||||
|
@ -379,22 +240,17 @@ void FileSystemManagerParent::RequestAllowToClose() {
|
|||
|
||||
mRequestedAllowToClose.Flip();
|
||||
|
||||
// XXX Send a message to the child and wait for a response before closing!
|
||||
|
||||
InvokeAsync(mDataManager->MutableIOTargetPtr(), __func__,
|
||||
[self = RefPtr<FileSystemManagerParent>(this)]() {
|
||||
return self->SendCloseAll();
|
||||
})
|
||||
->Then(mDataManager->MutableIOTargetPtr(), __func__,
|
||||
[self = RefPtr<FileSystemManagerParent>(this)](
|
||||
const CloseAllPromise::ResolveOrRejectValue& aValue) {
|
||||
self->Close();
|
||||
self->Close();
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
});
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
void FileSystemManagerParent::OnChannelClose() {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
if (!mAllowedToClose) {
|
||||
AllowToClose();
|
||||
}
|
||||
|
@ -403,8 +259,6 @@ void FileSystemManagerParent::OnChannelClose() {
|
|||
}
|
||||
|
||||
void FileSystemManagerParent::OnChannelError() {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
if (!mAllowedToClose) {
|
||||
AllowToClose();
|
||||
}
|
||||
|
@ -413,8 +267,6 @@ void FileSystemManagerParent::OnChannelError() {
|
|||
}
|
||||
|
||||
void FileSystemManagerParent::AllowToClose() {
|
||||
AssertIsOnIOTarget();
|
||||
|
||||
mAllowedToClose.Flip();
|
||||
|
||||
InvokeAsync(mDataManager->MutableBackgroundTargetPtr(), __func__,
|
||||
|
|
|
@ -34,40 +34,35 @@ class FileSystemManagerParent : public PFileSystemManagerParent {
|
|||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileSystemManagerParent, override)
|
||||
|
||||
void AssertIsOnIOTarget() const;
|
||||
mozilla::ipc::IPCResult RecvGetRootHandleMsg(
|
||||
GetRootHandleMsgResolver&& aResolver);
|
||||
|
||||
const RefPtr<fs::data::FileSystemDataManager>& DataManagerStrongRef() const;
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetRootHandle(GetRootHandleResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetDirectoryHandle(
|
||||
mozilla::ipc::IPCResult RecvGetDirectoryHandleMsg(
|
||||
FileSystemGetHandleRequest&& aRequest,
|
||||
GetDirectoryHandleResolver&& aResolver);
|
||||
GetDirectoryHandleMsgResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetFileHandle(
|
||||
FileSystemGetHandleRequest&& aRequest, GetFileHandleResolver&& aResolver);
|
||||
mozilla::ipc::IPCResult RecvGetFileHandleMsg(
|
||||
FileSystemGetHandleRequest&& aRequest,
|
||||
GetFileHandleMsgResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetFileMsg(FileSystemGetFileRequest&& aRequest,
|
||||
GetFileMsgResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvResolveMsg(FileSystemResolveRequest&& aRequest,
|
||||
ResolveMsgResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetEntriesMsg(
|
||||
FileSystemGetEntriesRequest&& aRequest,
|
||||
GetEntriesMsgResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRemoveEntryMsg(
|
||||
FileSystemRemoveEntryRequest&& aRequest,
|
||||
RemoveEntryMsgResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvCloseFile(FileSystemGetFileRequest&& aRequest);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetAccessHandle(
|
||||
const FileSystemGetAccessHandleRequest& aRequest,
|
||||
GetAccessHandleResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetFile(FileSystemGetFileRequest&& aRequest,
|
||||
GetFileResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvResolve(FileSystemResolveRequest&& aRequest,
|
||||
ResolveResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetEntries(FileSystemGetEntriesRequest&& aRequest,
|
||||
GetEntriesResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRemoveEntry(
|
||||
FileSystemRemoveEntryRequest&& aRequest, RemoveEntryResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvMoveEntry(FileSystemMoveEntryRequest&& aRequest,
|
||||
MoveEntryResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRenameEntry(
|
||||
FileSystemRenameEntryRequest&& aRequest, MoveEntryResolver&& aResolver);
|
||||
FileSystemGetFileRequest&& aRequest, GetAccessHandleResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetWritable(FileSystemGetFileRequest&& aRequest,
|
||||
GetWritableResolver&& aResolver);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
extern LazyLogModule gOPFSLog;
|
||||
LazyLogModule gOPFSLog("OPFS");
|
||||
}
|
||||
|
||||
#define LOG(args) MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Verbose, args)
|
||||
|
@ -27,6 +27,7 @@ extern LazyLogModule gOPFSLog;
|
|||
MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
mozilla::ipc::IPCResult CreateFileSystemManagerParent(
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
|
||||
mozilla::ipc::Endpoint<PFileSystemManagerParent>&& aParentEndpoint,
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
#include "GetDirectoryForOrigin.h"
|
||||
|
||||
#include "FileSystemHashSource.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/dom/QMResult.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
namespace mozilla::dom::fs {
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
#ifndef DOM_FS_PARENT_RESULTSTATEMENT_H_
|
||||
#define DOM_FS_PARENT_RESULTSTATEMENT_H_
|
||||
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
|
|
|
@ -10,11 +10,8 @@
|
|||
#include "FileSystemDatabaseManagerVersion001.h"
|
||||
#include "FileSystemFileManager.h"
|
||||
#include "FileSystemHashSource.h"
|
||||
#include "GetDirectoryForOrigin.h"
|
||||
#include "SchemaVersion001.h"
|
||||
#include "fs/FileSystemConstants.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "GetDirectoryForOrigin.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/dom/FileSystemManagerParent.h"
|
||||
|
@ -24,6 +21,8 @@
|
|||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "nsBaseHashtable.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
@ -33,6 +32,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "SchemaVersion001.h"
|
||||
|
||||
namespace mozilla::dom::fs::data {
|
||||
|
||||
|
@ -205,11 +205,9 @@ Result<EntryId, QMResult> GetEntryHandle(
|
|||
|
||||
FileSystemDataManager::FileSystemDataManager(
|
||||
const quota::OriginMetadata& aOriginMetadata,
|
||||
MovingNotNull<nsCOMPtr<nsIEventTarget>> aIOTarget,
|
||||
MovingNotNull<RefPtr<TaskQueue>> aIOTaskQueue)
|
||||
: mOriginMetadata(aOriginMetadata),
|
||||
mBackgroundTarget(WrapNotNull(GetCurrentSerialEventTarget())),
|
||||
mIOTarget(std::move(aIOTarget)),
|
||||
mIOTaskQueue(std::move(aIOTaskQueue)),
|
||||
mRegCount(0),
|
||||
mState(State::Initial) {}
|
||||
|
@ -268,11 +266,10 @@ FileSystemDataManager::GetOrCreateFileSystemDataManager(
|
|||
nsCString taskQueueName("OPFS "_ns + aOriginMetadata.mOrigin);
|
||||
|
||||
RefPtr<TaskQueue> ioTaskQueue =
|
||||
TaskQueue::Create(do_AddRef(streamTransportService), taskQueueName.get());
|
||||
TaskQueue::Create(streamTransportService.forget(), taskQueueName.get());
|
||||
|
||||
auto dataManager = MakeRefPtr<FileSystemDataManager>(
|
||||
aOriginMetadata, WrapMovingNotNull(streamTransportService),
|
||||
WrapMovingNotNull(ioTaskQueue));
|
||||
aOriginMetadata, WrapMovingNotNull(ioTaskQueue));
|
||||
|
||||
AddFileSystemDataManager(aOriginMetadata.mOrigin, dataManager);
|
||||
|
||||
|
@ -328,12 +325,6 @@ bool FileSystemDataManager::IsShutdownCompleted() {
|
|||
return !gDataManagers;
|
||||
}
|
||||
|
||||
void FileSystemDataManager::AssertIsOnIOTarget() const {
|
||||
DebugOnly<bool> current = false;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(mIOTarget->IsOnCurrentThread(¤t)));
|
||||
MOZ_ASSERT(current);
|
||||
}
|
||||
|
||||
void FileSystemDataManager::Register() { mRegCount++; }
|
||||
|
||||
void FileSystemDataManager::Unregister() {
|
||||
|
@ -376,21 +367,6 @@ RefPtr<BoolPromise> FileSystemDataManager::OnClose() {
|
|||
return mClosePromiseHolder.Ensure(__func__);
|
||||
}
|
||||
|
||||
bool FileSystemDataManager::LockExclusive(const EntryId& aEntryId) {
|
||||
if (mExclusiveLocks.Contains(aEntryId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mExclusiveLocks.Insert(aEntryId);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSystemDataManager::UnlockExclusive(const EntryId& aEntryId) {
|
||||
MOZ_ASSERT(mExclusiveLocks.Contains(aEntryId));
|
||||
|
||||
mExclusiveLocks.Remove(aEntryId);
|
||||
}
|
||||
|
||||
bool FileSystemDataManager::IsInactive() const {
|
||||
return !mRegCount && !mBackgroundThreadAccessible.Access()->mActors.Count();
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
#include "mozilla/ThreadBound.h"
|
||||
#include "mozilla/dom/FileSystemHelpers.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/FileSystemHelpers.h"
|
||||
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
|
||||
#include "mozilla/dom/quota/CommonMetadata.h"
|
||||
#include "mozilla/dom/quota/ForwardDecls.h"
|
||||
|
@ -52,7 +52,6 @@ class FileSystemDataManager
|
|||
enum struct State : uint8_t { Initial = 0, Opening, Open, Closing, Closed };
|
||||
|
||||
FileSystemDataManager(const quota::OriginMetadata& aOriginMetadata,
|
||||
MovingNotNull<nsCOMPtr<nsIEventTarget>> aIOTarget,
|
||||
MovingNotNull<RefPtr<TaskQueue>> aIOTaskQueue);
|
||||
|
||||
// IsExclusive is true because we want to allow the move operations. There's
|
||||
|
@ -71,8 +70,6 @@ class FileSystemDataManager
|
|||
|
||||
NS_INLINE_DECL_REFCOUNTING(FileSystemDataManager)
|
||||
|
||||
void AssertIsOnIOTarget() const;
|
||||
|
||||
nsISerialEventTarget* MutableBackgroundTargetPtr() const {
|
||||
return mBackgroundTarget.get();
|
||||
}
|
||||
|
@ -105,10 +102,6 @@ class FileSystemDataManager
|
|||
|
||||
RefPtr<BoolPromise> OnClose();
|
||||
|
||||
bool LockExclusive(const EntryId& aEntryId);
|
||||
|
||||
void UnlockExclusive(const EntryId& aEntryId);
|
||||
|
||||
protected:
|
||||
~FileSystemDataManager();
|
||||
|
||||
|
@ -131,9 +124,7 @@ class FileSystemDataManager
|
|||
ThreadBound<BackgroundThreadAccessible> mBackgroundThreadAccessible;
|
||||
|
||||
const quota::OriginMetadata mOriginMetadata;
|
||||
nsTHashSet<EntryId> mExclusiveLocks;
|
||||
const NotNull<nsCOMPtr<nsISerialEventTarget>> mBackgroundTarget;
|
||||
const NotNull<nsCOMPtr<nsIEventTarget>> mIOTarget;
|
||||
const NotNull<RefPtr<TaskQueue>> mIOTaskQueue;
|
||||
RefPtr<quota::DirectoryLock> mDirectoryLock;
|
||||
UniquePtr<FileSystemDatabaseManager> mDatabaseManager;
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
#ifndef DOM_FS_PARENT_DATAMODEL_FILESYSTEMDATABASEMANAGER_H_
|
||||
#define DOM_FS_PARENT_DATAMODEL_FILESYSTEMDATABASEMANAGER_H_
|
||||
|
||||
#include "ResultConnection.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/quota/ForwardDecls.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "ResultConnection.h"
|
||||
|
||||
template <class T>
|
||||
class nsCOMPtr;
|
||||
|
@ -25,7 +25,6 @@ class Result;
|
|||
namespace dom::fs {
|
||||
|
||||
class FileSystemChildMetadata;
|
||||
class FileSystemEntryMetadata;
|
||||
class FileSystemDirectoryListing;
|
||||
class FileSystemEntryPair;
|
||||
|
||||
|
@ -42,16 +41,6 @@ class FileSystemDatabaseManager {
|
|||
*/
|
||||
virtual Result<int64_t, QMResult> GetUsage() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns directory identifier for the parent of
|
||||
* a given entry, or error.
|
||||
*
|
||||
* @param aEntry EntryId of an existing file or directory
|
||||
* @return Result<EntryId, QMResult> Directory identifier or error
|
||||
*/
|
||||
virtual Result<EntryId, QMResult> GetParentEntryId(
|
||||
const EntryId& aEntry) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns directory identifier, optionally creating it if it doesn't
|
||||
* exist
|
||||
|
@ -101,18 +90,6 @@ class FileSystemDatabaseManager {
|
|||
virtual Result<bool, QMResult> RemoveFile(
|
||||
const FileSystemChildMetadata& aHandle) = 0;
|
||||
|
||||
/**
|
||||
* @brief Move/Rename a file/directory
|
||||
*
|
||||
* @param aHandle Source directory or file
|
||||
* @param aNewDesignation Destination directory and filename
|
||||
* @return Result<bool, QMResult> False if file didn't exist, otherwise true
|
||||
* or error
|
||||
*/
|
||||
virtual Result<bool, QMResult> MoveEntry(
|
||||
const FileSystemChildMetadata& aHandle,
|
||||
const FileSystemChildMetadata& aNewDesignation) = 0;
|
||||
|
||||
/**
|
||||
* @brief Tries to connect a parent directory to a file system item with a
|
||||
* path, excluding the parent directory
|
||||
|
|
|
@ -7,14 +7,13 @@
|
|||
#include "FileSystemDatabaseManagerVersion001.h"
|
||||
|
||||
#include "FileSystemFileManager.h"
|
||||
#include "ResultStatement.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "mozilla/dom/FileSystemDataManager.h"
|
||||
#include "mozilla/dom/FileSystemHandle.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "ResultStatement.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -26,11 +25,10 @@ namespace {
|
|||
|
||||
Result<bool, QMResult> ApplyEntryExistsQuery(
|
||||
const FileSystemConnection& aConnection, const nsACString& aQuery,
|
||||
const FileSystemChildMetadata& aHandle) {
|
||||
const EntryId& aEntryId) {
|
||||
QM_TRY_UNWRAP(ResultStatement stmt,
|
||||
ResultStatement::Create(aConnection, aQuery));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("parent"_ns, aHandle.parentId())));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindNameByName("name"_ns, aHandle.childName())));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("handle"_ns, aEntryId)));
|
||||
|
||||
return stmt.YesOrNoQuery();
|
||||
}
|
||||
|
@ -83,18 +81,17 @@ nsresult AggregateUsages(FileSystemConnection& mConnection) {
|
|||
}
|
||||
|
||||
Result<bool, QMResult> DoesDirectoryExist(
|
||||
const FileSystemConnection& mConnection,
|
||||
const FileSystemChildMetadata& aHandle) {
|
||||
MOZ_ASSERT(!aHandle.parentId().IsEmpty());
|
||||
const FileSystemConnection& mConnection, const EntryId& aEntryId) {
|
||||
MOZ_ASSERT(!aEntryId.IsEmpty());
|
||||
|
||||
const nsCString existsQuery =
|
||||
"SELECT EXISTS "
|
||||
"(SELECT 1 FROM Directories JOIN Entries USING (handle) "
|
||||
"WHERE Directories.name = :name AND Entries.parent = :parent )"
|
||||
"(SELECT 1 FROM Directories "
|
||||
"WHERE handle = :handle )"
|
||||
";"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(bool exists,
|
||||
ApplyEntryExistsQuery(mConnection, existsQuery, aHandle));
|
||||
ApplyEntryExistsQuery(mConnection, existsQuery, aEntryId));
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
@ -138,17 +135,17 @@ Result<Path, QMResult> ResolveReversedPath(
|
|||
}
|
||||
|
||||
Result<bool, QMResult> DoesFileExist(const FileSystemConnection& mConnection,
|
||||
const FileSystemChildMetadata& aHandle) {
|
||||
MOZ_ASSERT(!aHandle.parentId().IsEmpty());
|
||||
const EntryId& aEntryId) {
|
||||
MOZ_ASSERT(!aEntryId.IsEmpty());
|
||||
|
||||
const nsCString existsQuery =
|
||||
"SELECT EXISTS "
|
||||
"(SELECT 1 FROM Files JOIN Entries USING (handle) "
|
||||
"WHERE Files.name = :name AND Entries.parent = :parent )"
|
||||
"(SELECT 1 FROM Files "
|
||||
"WHERE handle = :handle ) "
|
||||
";"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(bool exists,
|
||||
ApplyEntryExistsQuery(mConnection, existsQuery, aHandle));
|
||||
ApplyEntryExistsQuery(mConnection, existsQuery, aEntryId));
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
@ -212,66 +209,6 @@ nsresult GetEntries(const FileSystemConnection& aConnection,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
Result<EntryId, QMResult> GetUniqueEntryId(
|
||||
const FileSystemConnection& aConnection,
|
||||
const FileSystemChildMetadata& aHandle) {
|
||||
const nsCString existsQuery =
|
||||
"SELECT EXISTS "
|
||||
"(SELECT 1 FROM Entries "
|
||||
"WHERE handle = :handle )"
|
||||
";"_ns;
|
||||
|
||||
FileSystemChildMetadata generatorInput = aHandle;
|
||||
|
||||
const size_t maxRounds = 1024u;
|
||||
|
||||
for (size_t hangGuard = 0u; hangGuard < maxRounds; ++hangGuard) {
|
||||
QM_TRY_UNWRAP(EntryId entryId, fs::data::GetEntryHandle(generatorInput));
|
||||
QM_TRY_UNWRAP(ResultStatement stmt,
|
||||
ResultStatement::Create(aConnection, existsQuery));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("handle"_ns, entryId)));
|
||||
|
||||
QM_TRY_UNWRAP(bool alreadyInUse, stmt.YesOrNoQuery());
|
||||
|
||||
if (!alreadyInUse) {
|
||||
return entryId;
|
||||
}
|
||||
|
||||
generatorInput.parentId() = entryId;
|
||||
}
|
||||
|
||||
return Err(QMResult(NS_ERROR_UNEXPECTED));
|
||||
}
|
||||
|
||||
Result<EntryId, QMResult> FindEntryId(const FileSystemConnection& aConnection,
|
||||
const FileSystemChildMetadata& aHandle,
|
||||
bool isFile) {
|
||||
const nsCString aDirectoryQuery =
|
||||
"SELECT Entries.handle FROM Directories JOIN Entries USING (handle) "
|
||||
"WHERE Directories.name = :name AND Entries.parent = :parent "
|
||||
";"_ns;
|
||||
|
||||
const nsCString aFileQuery =
|
||||
"SELECT Entries.handle FROM Files JOIN Entries USING (handle) "
|
||||
"WHERE Files.name = :name AND Entries.parent = :parent "
|
||||
";"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(ResultStatement stmt,
|
||||
ResultStatement::Create(aConnection,
|
||||
isFile ? aFileQuery : aDirectoryQuery));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("parent"_ns, aHandle.parentId())));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindNameByName("name"_ns, aHandle.childName())));
|
||||
QM_TRY_UNWRAP(bool moreResults, stmt.ExecuteStep());
|
||||
|
||||
if (!moreResults) {
|
||||
return Err(QMResult(NS_ERROR_DOM_NOT_FOUND_ERR));
|
||||
}
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, stmt.GetEntryIdByColumn(/* Column */ 0u));
|
||||
|
||||
return entryId;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Result<Usage, QMResult> FileSystemDatabaseManagerVersion001::GetUsage() const {
|
||||
|
@ -306,40 +243,19 @@ nsresult FileSystemDatabaseManagerVersion001::UpdateUsage(int64_t aDelta) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
Result<EntryId, QMResult> FileSystemDatabaseManagerVersion001::GetParentEntryId(
|
||||
const EntryId& aEntry) const {
|
||||
MOZ_ASSERT(!aEntry.IsEmpty());
|
||||
|
||||
const nsCString parentQuery =
|
||||
"SELECT parent FROM Entries "
|
||||
"WHERE handle = :entryId;"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(ResultStatement stmt,
|
||||
ResultStatement::Create(mConnection, parentQuery));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("entryId"_ns, aEntry)));
|
||||
QM_TRY_UNWRAP(bool moreResults, stmt.ExecuteStep());
|
||||
if (!moreResults) {
|
||||
return Err(QMResult(NS_ERROR_DOM_NOT_FOUND_ERR));
|
||||
}
|
||||
QM_TRY_UNWRAP(EntryId parentId, stmt.GetEntryIdByColumn(/* Column */ 0u));
|
||||
|
||||
return parentId;
|
||||
}
|
||||
|
||||
Result<EntryId, QMResult>
|
||||
FileSystemDatabaseManagerVersion001::GetOrCreateDirectory(
|
||||
const FileSystemChildMetadata& aHandle, bool aCreate) {
|
||||
MOZ_ASSERT(!aHandle.parentId().IsEmpty());
|
||||
|
||||
const auto& name = aHandle.childName();
|
||||
// Belt and suspenders: check here as well as in child.
|
||||
if (!IsValidName(name)) {
|
||||
return Err(QMResult(NS_ERROR_DOM_TYPE_MISMATCH_ERR));
|
||||
}
|
||||
MOZ_ASSERT(!name.IsVoid() && !name.IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, fs::data::GetEntryHandle(aHandle));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
bool exists = true;
|
||||
QM_TRY_UNWRAP(exists, DoesFileExist(mConnection, aHandle));
|
||||
QM_TRY_UNWRAP(exists, DoesFileExist(mConnection, entryId));
|
||||
|
||||
// By spec, we don't allow a file and a directory
|
||||
// to have the same name and parent
|
||||
|
@ -347,11 +263,11 @@ FileSystemDatabaseManagerVersion001::GetOrCreateDirectory(
|
|||
return Err(QMResult(NS_ERROR_DOM_TYPE_MISMATCH_ERR));
|
||||
}
|
||||
|
||||
QM_TRY_UNWRAP(exists, DoesDirectoryExist(mConnection, aHandle));
|
||||
QM_TRY_UNWRAP(exists, DoesDirectoryExist(mConnection, entryId));
|
||||
|
||||
// exists as directory
|
||||
if (exists) {
|
||||
return FindEntryId(mConnection, aHandle, false);
|
||||
return entryId;
|
||||
}
|
||||
|
||||
if (!aCreate) {
|
||||
|
@ -372,9 +288,6 @@ FileSystemDatabaseManagerVersion001::GetOrCreateDirectory(
|
|||
"( :handle, :name ) "
|
||||
";"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, GetUniqueEntryId(mConnection, aHandle));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
mozStorageTransaction transaction(
|
||||
mConnection.get(), false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
{
|
||||
|
@ -399,7 +312,7 @@ FileSystemDatabaseManagerVersion001::GetOrCreateDirectory(
|
|||
QM_TRY(QM_TO_RESULT(transaction.Commit()));
|
||||
|
||||
QM_TRY_UNWRAP(DebugOnly<bool> doesItExistNow,
|
||||
DoesDirectoryExist(mConnection, aHandle));
|
||||
DoesDirectoryExist(mConnection, entryId));
|
||||
MOZ_ASSERT(doesItExistNow);
|
||||
|
||||
return entryId;
|
||||
|
@ -410,13 +323,12 @@ Result<EntryId, QMResult> FileSystemDatabaseManagerVersion001::GetOrCreateFile(
|
|||
MOZ_ASSERT(!aHandle.parentId().IsEmpty());
|
||||
|
||||
const auto& name = aHandle.childName();
|
||||
// Belt and suspenders: check here as well as in child.
|
||||
if (!IsValidName(name)) {
|
||||
return Err(QMResult(NS_ERROR_DOM_TYPE_MISMATCH_ERR));
|
||||
}
|
||||
MOZ_ASSERT(!name.IsVoid() && !name.IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(bool exists, DoesDirectoryExist(mConnection, aHandle));
|
||||
QM_TRY_UNWRAP(EntryId entryId, fs::data::GetEntryHandle(aHandle));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(bool exists, DoesDirectoryExist(mConnection, entryId));
|
||||
|
||||
// By spec, we don't allow a file and a directory
|
||||
// to have the same name and parent
|
||||
|
@ -424,10 +336,10 @@ Result<EntryId, QMResult> FileSystemDatabaseManagerVersion001::GetOrCreateFile(
|
|||
return Err(QMResult(NS_ERROR_DOM_TYPE_MISMATCH_ERR));
|
||||
}
|
||||
|
||||
QM_TRY_UNWRAP(exists, DoesFileExist(mConnection, aHandle));
|
||||
QM_TRY_UNWRAP(exists, DoesFileExist(mConnection, entryId));
|
||||
|
||||
if (exists) {
|
||||
return FindEntryId(mConnection, aHandle, true);
|
||||
return entryId;
|
||||
}
|
||||
|
||||
if (!aCreate) {
|
||||
|
@ -448,9 +360,7 @@ Result<EntryId, QMResult> FileSystemDatabaseManagerVersion001::GetOrCreateFile(
|
|||
"( :handle, :name ) "
|
||||
";"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, GetUniqueEntryId(mConnection, aHandle));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
// TODO: This needs a scope quard
|
||||
mozStorageTransaction transaction(
|
||||
mConnection.get(), false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
{
|
||||
|
@ -546,15 +456,15 @@ Result<bool, QMResult> FileSystemDatabaseManagerVersion001::RemoveDirectory(
|
|||
DebugOnly<Name> name = aHandle.childName();
|
||||
MOZ_ASSERT(!name.inspect().IsVoid() && !name.inspect().IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(bool exists, DoesDirectoryExist(mConnection, aHandle));
|
||||
QM_TRY_UNWRAP(EntryId entryId, fs::data::GetEntryHandle(aHandle));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(bool exists, DoesDirectoryExist(mConnection, entryId));
|
||||
|
||||
if (!exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this point, entry exists and is a directory.
|
||||
QM_TRY_UNWRAP(EntryId entryId, FindEntryId(mConnection, aHandle, false));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(bool isEmpty, IsDirectoryEmpty(mConnection, entryId));
|
||||
|
||||
|
@ -628,8 +538,11 @@ Result<bool, QMResult> FileSystemDatabaseManagerVersion001::RemoveFile(
|
|||
DebugOnly<Name> name = aHandle.childName();
|
||||
MOZ_ASSERT(!name.inspect().IsVoid() && !name.inspect().IsEmpty());
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, fs::data::GetEntryHandle(aHandle));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
// Make it more evident that we won't remove directories
|
||||
QM_TRY_UNWRAP(bool exists, DoesFileExist(mConnection, aHandle));
|
||||
QM_TRY_UNWRAP(bool exists, DoesFileExist(mConnection, entryId));
|
||||
|
||||
if (!exists) {
|
||||
return false;
|
||||
|
@ -641,9 +554,6 @@ Result<bool, QMResult> FileSystemDatabaseManagerVersion001::RemoveFile(
|
|||
"WHERE handle = :handle "
|
||||
";"_ns;
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, FindEntryId(mConnection, aHandle, true));
|
||||
MOZ_ASSERT(!entryId.IsEmpty());
|
||||
|
||||
mozStorageTransaction transaction(
|
||||
mConnection.get(), false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
|
@ -664,97 +574,6 @@ Result<bool, QMResult> FileSystemDatabaseManagerVersion001::RemoveFile(
|
|||
return true;
|
||||
}
|
||||
|
||||
Result<bool, QMResult> FileSystemDatabaseManagerVersion001::MoveEntry(
|
||||
const FileSystemChildMetadata& aHandle,
|
||||
const FileSystemChildMetadata& aNewDesignation) {
|
||||
MOZ_ASSERT(!aHandle.parentId().IsEmpty());
|
||||
|
||||
if (aHandle.childName().IsEmpty() || aNewDesignation.childName().IsEmpty()) {
|
||||
return Err(QMResult(NS_ERROR_DOM_NOT_FOUND_ERR));
|
||||
}
|
||||
|
||||
DebugOnly<Name> name = aHandle.childName();
|
||||
MOZ_ASSERT(!name.inspect().IsVoid());
|
||||
|
||||
// Verify the source exists
|
||||
bool isFile = false;
|
||||
QM_TRY_UNWRAP(bool exists, DoesFileExist(mConnection, aHandle));
|
||||
if (!exists) {
|
||||
QM_TRY_UNWRAP(exists, DoesDirectoryExist(mConnection, aHandle));
|
||||
if (!exists) {
|
||||
return Err(QMResult(NS_ERROR_DOM_NOT_FOUND_ERR));
|
||||
}
|
||||
} else {
|
||||
isFile = true;
|
||||
}
|
||||
|
||||
QM_TRY_UNWRAP(EntryId entryId, FindEntryId(mConnection, aHandle, isFile));
|
||||
#if 0
|
||||
// Enable once file lock code lands with the SyncAccessHandle patch
|
||||
// At this point, entry exists
|
||||
if (isFile && !CanUseFile(entryId, AccessMode::EXCLUSIVE)) {
|
||||
LOG(("Trying to move in-use file"));
|
||||
return Err(QMResult(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR));
|
||||
}
|
||||
#endif
|
||||
|
||||
const nsLiteralCString updateEntryParentQuery =
|
||||
"UPDATE Entries "
|
||||
"SET parent = :parent "
|
||||
"WHERE handle = :handle "
|
||||
";"_ns;
|
||||
|
||||
const nsLiteralCString updateFileNameQuery =
|
||||
"UPDATE Files "
|
||||
"SET name = :name "
|
||||
"WHERE handle = :handle "
|
||||
";"_ns;
|
||||
|
||||
const nsLiteralCString updateDirectoryNameQuery =
|
||||
"UPDATE Directories "
|
||||
"SET name = :name "
|
||||
"WHERE handle = :handle "
|
||||
";"_ns;
|
||||
|
||||
mozStorageTransaction transaction(
|
||||
mConnection.get(), false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
{
|
||||
QM_TRY_UNWRAP(ResultStatement stmt,
|
||||
ResultStatement::Create(mConnection, updateEntryParentQuery));
|
||||
QM_TRY(QM_TO_RESULT(
|
||||
stmt.BindEntryIdByName("parent"_ns, aNewDesignation.parentId())));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("handle"_ns, entryId)));
|
||||
QM_TRY(QM_TO_RESULT(stmt.Execute()));
|
||||
}
|
||||
|
||||
if (isFile) {
|
||||
QM_TRY_UNWRAP(ResultStatement stmt,
|
||||
ResultStatement::Create(mConnection, updateFileNameQuery));
|
||||
QM_TRY(QM_TO_RESULT(
|
||||
stmt.BindNameByName("name"_ns, aNewDesignation.childName())));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("handle"_ns, entryId)));
|
||||
QM_TRY(QM_TO_RESULT(stmt.Execute()));
|
||||
} else {
|
||||
QM_TRY_UNWRAP(
|
||||
ResultStatement stmt,
|
||||
ResultStatement::Create(mConnection, updateDirectoryNameQuery));
|
||||
QM_TRY(QM_TO_RESULT(
|
||||
stmt.BindNameByName("name"_ns, aNewDesignation.childName())));
|
||||
QM_TRY(QM_TO_RESULT(stmt.BindEntryIdByName("handle"_ns, entryId)));
|
||||
QM_TRY(QM_TO_RESULT(stmt.Execute()));
|
||||
}
|
||||
|
||||
const auto usageDelta =
|
||||
static_cast<int64_t>(aNewDesignation.childName().Length()) -
|
||||
static_cast<int64_t>(aHandle.childName().Length());
|
||||
QM_TRY(QM_TO_RESULT(UpdateUsage(usageDelta)));
|
||||
|
||||
QM_TRY(QM_TO_RESULT(transaction.Commit()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Result<Path, QMResult> FileSystemDatabaseManagerVersion001::Resolve(
|
||||
const FileSystemEntryPair& aEndpoints) const {
|
||||
QM_TRY_UNWRAP(Path path, ResolveReversedPath(mConnection, aEndpoints));
|
||||
|
|
|
@ -40,9 +40,6 @@ class FileSystemDatabaseManagerVersion001 : public FileSystemDatabaseManager {
|
|||
|
||||
virtual Result<int64_t, QMResult> GetUsage() const override;
|
||||
|
||||
virtual Result<EntryId, QMResult> GetParentEntryId(
|
||||
const EntryId& aEntry) const override;
|
||||
|
||||
virtual Result<EntryId, QMResult> GetOrCreateDirectory(
|
||||
const FileSystemChildMetadata& aHandle, bool aCreate) override;
|
||||
|
||||
|
@ -57,10 +54,6 @@ class FileSystemDatabaseManagerVersion001 : public FileSystemDatabaseManager {
|
|||
virtual Result<FileSystemDirectoryListing, QMResult> GetDirectoryEntries(
|
||||
const EntryId& aParent, PageNumber aPage) const override;
|
||||
|
||||
virtual Result<bool, QMResult> MoveEntry(
|
||||
const FileSystemChildMetadata& aHandle,
|
||||
const FileSystemChildMetadata& aNewDesignation) override;
|
||||
|
||||
virtual Result<bool, QMResult> RemoveDirectory(
|
||||
const FileSystemChildMetadata& aHandle, bool aRecursive) override;
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ Result<nsCOMPtr<nsIFile>, QMResult> GetFileDestination(
|
|||
MOZ_ALWAYS_TRUE(IsAscii(encoded));
|
||||
|
||||
nsString relativePath;
|
||||
relativePath.Append(Substring(encoded, 0, 2));
|
||||
relativePath.Append(encoded.CharAt(0u));
|
||||
relativePath.Append(encoded.CharAt(1u));
|
||||
|
||||
QM_TRY(QM_TO_RESULT(destination->AppendRelativePath(relativePath)));
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
#include "SchemaVersion001.h"
|
||||
|
||||
#include "FileSystemHashSource.h"
|
||||
#include "ResultStatement.h"
|
||||
#include "fs/FileSystemConstants.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "ResultStatement.h"
|
||||
|
||||
namespace mozilla::dom::fs {
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#ifndef DOM_FS_PARENT_DATAMODEL_SCHEMAVERSION001_H_
|
||||
#define DOM_FS_PARENT_DATAMODEL_SCHEMAVERSION001_H_
|
||||
|
||||
#include "ResultConnection.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/quota/ForwardDecls.h"
|
||||
#include "ResultConnection.h"
|
||||
|
||||
namespace mozilla::dom::fs {
|
||||
|
||||
|
|
|
@ -9,14 +9,12 @@ DIRS += [
|
|||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
"FileSystemAccessHandleParent.h",
|
||||
"FileSystemManagerParent.h",
|
||||
"FileSystemManagerParentFactory.h",
|
||||
"FileSystemQuotaClient.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"FileSystemAccessHandleParent.cpp",
|
||||
"FileSystemHashSource.cpp",
|
||||
"FileSystemManagerParent.cpp",
|
||||
"FileSystemManagerParentFactory.cpp",
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "FileSystemHelpers.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla::dom::fs {
|
||||
|
||||
bool IsValidName(const mozilla::dom::fs::Name& aName) {
|
||||
return !(aName.IsVoid() || aName.Length() == 0 ||
|
||||
#ifdef XP_WIN
|
||||
aName.FindChar('\\') != kNotFound ||
|
||||
#endif
|
||||
aName.FindChar('/') != kNotFound || aName.EqualsLiteral(".") ||
|
||||
aName.EqualsLiteral(".."));
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom::fs
|
|
@ -7,9 +7,6 @@
|
|||
#ifndef DOM_FS_SHARED_FILESYSTEMHELPERS_H_
|
||||
#define DOM_FS_SHARED_FILESYSTEMHELPERS_H_
|
||||
|
||||
#include "FileSystemTypes.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla::dom::fs {
|
||||
|
||||
// XXX Consider moving this class template to MFBT.
|
||||
|
@ -74,13 +71,13 @@ class Registered {
|
|||
}
|
||||
}
|
||||
|
||||
Registered() = default;
|
||||
Registered() {}
|
||||
|
||||
Registered(const Registered& aOther) : mObject(aOther.mObject) {
|
||||
mObject->Register();
|
||||
}
|
||||
|
||||
Registered(Registered&& aOther) noexcept = default;
|
||||
Registered(Registered&& aOther) = default;
|
||||
|
||||
MOZ_IMPLICIT Registered(RefPtr<T> aObject) : mObject(std::move(aObject)) {
|
||||
if (mObject) {
|
||||
|
@ -109,7 +106,7 @@ class Registered {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Registered<T>& operator=(Registered<T>&& aRhs) noexcept {
|
||||
Registered<T>& operator=(Registered<T>&& aRhs) {
|
||||
RefPtr<T> oldObject = std::move(mObject);
|
||||
mObject = std::move(aRhs.mObject);
|
||||
aRhs.mObject = nullptr;
|
||||
|
@ -137,11 +134,6 @@ class Registered {
|
|||
T* operator->() const { return get(); }
|
||||
};
|
||||
|
||||
// Spec says valid names don't include (os-dependent) path separators,
|
||||
// and is not equal to a dot . or two dots ..
|
||||
// We want to use the same validator from both child and parent.
|
||||
bool IsValidName(const fs::Name& aName);
|
||||
|
||||
} // namespace mozilla::dom::fs
|
||||
|
||||
#endif // DOM_FS_SHARED_FILESYSTEMHELPERS_H_
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
include protocol PFileSystemManager;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
async protocol PFileSystemAccessHandle
|
||||
{
|
||||
manager PFileSystemManager;
|
||||
|
||||
parent:
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -2,8 +2,6 @@
|
|||
* 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/. */
|
||||
|
||||
include protocol PFileSystemAccessHandle;
|
||||
|
||||
include IPCBlob;
|
||||
|
||||
using mozilla::dom::fs::ContentType from "mozilla/dom/FileSystemTypes.h";
|
||||
|
@ -118,18 +116,15 @@ union FileSystemGetFileResponse
|
|||
FileSystemFileProperties;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains entry handle information.
|
||||
*/
|
||||
struct FileSystemGetAccessHandleRequest
|
||||
struct FileSystemGetAccessHandleData
|
||||
{
|
||||
EntryId entryId;
|
||||
FileDescriptor file;
|
||||
};
|
||||
|
||||
union FileSystemGetAccessHandleResponse
|
||||
{
|
||||
FileSystemGetAccessHandleData;
|
||||
nsresult;
|
||||
PFileSystemAccessHandle;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -186,34 +181,6 @@ union FileSystemRemoveEntryResponse
|
|||
void_t;
|
||||
};
|
||||
|
||||
/**
|
||||
* Identifies a file/directory to be moved and the new name, and the
|
||||
* destination directory
|
||||
*/
|
||||
struct FileSystemMoveEntryRequest
|
||||
{
|
||||
FileSystemEntryMetadata handle;
|
||||
FileSystemChildMetadata destHandle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Identifies a file/directory to be renamed and the new name
|
||||
*/
|
||||
struct FileSystemRenameEntryRequest
|
||||
{
|
||||
FileSystemEntryMetadata handle;
|
||||
Name name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains an error or the new entryId
|
||||
*/
|
||||
union FileSystemMoveEntryResponse
|
||||
{
|
||||
nsresult;
|
||||
void_t;
|
||||
};
|
||||
|
||||
struct FileSystemQuotaRequest
|
||||
{
|
||||
FileSystemChildMetadata handle;
|
||||
|
@ -224,14 +191,11 @@ struct FileSystemQuotaRequest
|
|||
|
||||
async protocol PFileSystemManager
|
||||
{
|
||||
manages PFileSystemAccessHandle;
|
||||
|
||||
parent:
|
||||
/**
|
||||
* TODO: documentation
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async GetRootHandle()
|
||||
async GetRootHandleMsg()
|
||||
returns(FileSystemGetHandleResponse response);
|
||||
|
||||
/**
|
||||
|
@ -250,8 +214,7 @@ async protocol PFileSystemManager
|
|||
*
|
||||
* @returns error or entry handle
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async GetDirectoryHandle(FileSystemGetHandleRequest request)
|
||||
async GetDirectoryHandleMsg(FileSystemGetHandleRequest request)
|
||||
returns(FileSystemGetHandleResponse handle);
|
||||
|
||||
/**
|
||||
|
@ -270,8 +233,7 @@ async protocol PFileSystemManager
|
|||
*
|
||||
* @returns error or entry handle
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async GetFileHandle(FileSystemGetHandleRequest request)
|
||||
async GetFileHandleMsg(FileSystemGetHandleRequest request)
|
||||
returns(FileSystemGetHandleResponse handle);
|
||||
|
||||
/**
|
||||
|
@ -289,16 +251,14 @@ async protocol PFileSystemManager
|
|||
*
|
||||
* @returns error or file object
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async GetFile(FileSystemGetFileRequest request)
|
||||
async GetFileMsg(FileSystemGetFileRequest request)
|
||||
returns(FileSystemGetFileResponse response);
|
||||
|
||||
/**
|
||||
* TODO: documentation
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async GetAccessHandle(FileSystemGetAccessHandleRequest request)
|
||||
returns(FileSystemGetAccessHandleResponse response);
|
||||
async GetAccessHandle(FileSystemGetFileRequest request)
|
||||
returns(FileSystemGetAccessHandleResponse fileData);
|
||||
|
||||
/**
|
||||
* TODO: documentation
|
||||
|
@ -314,8 +274,7 @@ async protocol PFileSystemManager
|
|||
*
|
||||
* @returns error or file system path
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async Resolve(FileSystemResolveRequest request)
|
||||
async ResolveMsg(FileSystemResolveRequest request)
|
||||
returns(FileSystemResolveResponse response);
|
||||
|
||||
/**
|
||||
|
@ -334,8 +293,7 @@ async protocol PFileSystemManager
|
|||
*
|
||||
* @returns error or iterator
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async GetEntries(FileSystemGetEntriesRequest request)
|
||||
async GetEntriesMsg(FileSystemGetEntriesRequest request)
|
||||
returns(FileSystemGetEntriesResponse entries);
|
||||
|
||||
/**
|
||||
|
@ -352,26 +310,14 @@ async protocol PFileSystemManager
|
|||
*
|
||||
* @returns error information
|
||||
*/
|
||||
[VirtualSendImpl]
|
||||
async RemoveEntry(FileSystemRemoveEntryRequest request)
|
||||
async RemoveEntryMsg(FileSystemRemoveEntryRequest request)
|
||||
returns(FileSystemRemoveEntryResponse response);
|
||||
|
||||
/**
|
||||
* Initiates an asynchronous request to move a directory or file with a
|
||||
* given name to a given destination and new name.
|
||||
*
|
||||
* @returns error information
|
||||
* TODO: documentation
|
||||
* So we can implement exclusive access
|
||||
*/
|
||||
async MoveEntry(FileSystemMoveEntryRequest request)
|
||||
returns(FileSystemMoveEntryResponse response);
|
||||
|
||||
/**
|
||||
* Initiates an asynchronous request to rename a directory or file
|
||||
*
|
||||
* @returns error information
|
||||
*/
|
||||
async RenameEntry(FileSystemRenameEntryRequest request)
|
||||
returns(FileSystemMoveEntryResponse response);
|
||||
async CloseFile(FileSystemGetFileRequest request);
|
||||
|
||||
/**
|
||||
* Request for quota needed to finish a write, beyond the amount preallocated
|
||||
|
@ -380,12 +326,6 @@ async protocol PFileSystemManager
|
|||
*/
|
||||
async NeedQuota(FileSystemQuotaRequest aRequest)
|
||||
returns (uint64_t aQuotaGranted);
|
||||
|
||||
child:
|
||||
async PFileSystemAccessHandle(FileDescriptor fileDescriptor);
|
||||
|
||||
async CloseAll()
|
||||
returns(nsresult rv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -9,14 +9,9 @@ EXPORTS.mozilla.dom += [
|
|||
"FileSystemTypes.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"FileSystemHelpers.cpp",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
||||
IPDL_SOURCES += [
|
||||
"PFileSystemAccessHandle.ipdl",
|
||||
"PFileSystemManager.ipdl",
|
||||
]
|
||||
|
||||
|
|
|
@ -15,5 +15,4 @@ XPCSHELL_TESTS_MANIFESTS += [
|
|||
TESTING_JS_MODULES.dom.fs.test.common += [
|
||||
"nsresult.js",
|
||||
"test_basics.js",
|
||||
"test_syncAccessHandle.js",
|
||||
]
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const allowCreate = { create: true };
|
||||
|
||||
exported_symbols.test0 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(root, "Can we access the root directory?");
|
||||
|
||||
try {
|
||||
await root.getFileHandle("test.txt");
|
||||
Assert.ok(false, "Opened file that shouldn't exist");
|
||||
} catch (e) {
|
||||
dump("caught exception when we tried to open a non-existant file\n");
|
||||
}
|
||||
};
|
||||
|
||||
exported_symbols.test1 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(root, "Can we access the root directory?");
|
||||
|
||||
const testFile = await root.getFileHandle("test.txt", allowCreate);
|
||||
Assert.ok(!!testFile, "Can't create file");
|
||||
let handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create SyncAccessHandle");
|
||||
await handle.close();
|
||||
handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create second SyncAccessHandle to same file");
|
||||
await handle.close();
|
||||
};
|
||||
|
||||
exported_symbols.test2 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(root, "Can we access the root directory?");
|
||||
|
||||
const testFile = await root.getFileHandle("test.txt");
|
||||
Assert.ok(!!testFile, "Can't open file");
|
||||
let handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create SyncAccessHandle");
|
||||
await handle.close();
|
||||
|
||||
await root.removeEntry("test.txt");
|
||||
try {
|
||||
handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Didn't remove file!");
|
||||
if (handle) {
|
||||
await handle.close();
|
||||
}
|
||||
} catch (e) {
|
||||
dump("Caught exception trying to create accesshandle to deleted file\n");
|
||||
}
|
||||
};
|
||||
|
||||
exported_symbols.test3 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(!!root, "Can we access the root directory?");
|
||||
|
||||
let dir = await root.getDirectoryHandle("dir", allowCreate);
|
||||
Assert.ok(!!dir, "Can we create a directory?");
|
||||
|
||||
// XXX not implemented yet
|
||||
//const path = await root.resolve(dir);
|
||||
//Assert.ok(path == ["dir"], "Wrong path: " + path);
|
||||
|
||||
let dir2 = await dir.getDirectoryHandle("dir", allowCreate);
|
||||
Assert.ok(!!dir, "Can we create dir/dir?");
|
||||
|
||||
// XXX not implemented yet
|
||||
//const path = await root.resolve(dir2);
|
||||
//Assert.ok(path == ["dir", "dir"], "Wrong path: " + path);
|
||||
|
||||
let dir3 = await dir.getDirectoryHandle("bar", allowCreate);
|
||||
Assert.ok(!!dir3, "Can we create dir/bar?");
|
||||
|
||||
// This should fail
|
||||
try {
|
||||
await root.getDirectoryHandle("bar");
|
||||
Assert.ok(!dir, "we shouldn't be able to get bar unless we create it");
|
||||
} catch (e) {
|
||||
dump("caught exception when we tried to get a non-existant dir\n");
|
||||
}
|
||||
|
||||
const testFile = await dir2.getFileHandle("test.txt", allowCreate);
|
||||
Assert.ok(!!testFile, "Can't create file in dir2");
|
||||
let handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create SyncAccessHandle in dir2");
|
||||
await handle.close();
|
||||
};
|
||||
|
||||
exported_symbols.test4 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(!!root, "Can we access the root directory?");
|
||||
|
||||
const testFile = await root.getFileHandle("test.txt", allowCreate);
|
||||
Assert.ok(!!testFile, "Can't access existing file");
|
||||
let handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create SyncAccessHandle to existing file");
|
||||
|
||||
// Write a sentence to the end of the file.
|
||||
const encoder = new TextEncoder();
|
||||
const writeBuffer = encoder.encode("Thank you for reading this.");
|
||||
const writeSize = handle.write(writeBuffer);
|
||||
Assert.ok(!!writeSize);
|
||||
|
||||
// Read it back
|
||||
// Get size of the file.
|
||||
let fileSize = await handle.getSize();
|
||||
Assert.ok(fileSize == writeBuffer.byteLength);
|
||||
// Read file content to a buffer.
|
||||
const readBuffer = new ArrayBuffer(fileSize);
|
||||
const readSize = handle.read(readBuffer, { at: 0 });
|
||||
Assert.ok(!!readSize);
|
||||
//Assert.ok(readBuffer == writeBuffer);
|
||||
|
||||
await handle.truncate(5);
|
||||
fileSize = await handle.getSize();
|
||||
Assert.ok(fileSize == 5);
|
||||
|
||||
await handle.flush();
|
||||
await handle.close();
|
||||
};
|
||||
|
||||
exported_symbols.test5 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(!!root, "Can we access the root directory?");
|
||||
|
||||
const testFile = await root.getFileHandle("test.txt");
|
||||
Assert.ok(!!testFile, "Can't create file");
|
||||
let handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create SyncAccessHandle");
|
||||
|
||||
try {
|
||||
const testFile2 = await root.getFileHandle("test2.txt", allowCreate);
|
||||
let handle2 = await testFile2.createSyncAccessHandle();
|
||||
Assert.ok(!!handle2, "can't create SyncAccessHandle to second file!");
|
||||
if (handle2) {
|
||||
await handle2.close();
|
||||
}
|
||||
} catch (e) {
|
||||
Assert.ok(false, "Failed to create second file");
|
||||
}
|
||||
|
||||
await handle.close();
|
||||
};
|
||||
|
||||
exported_symbols.test6 = async function() {
|
||||
let root = await navigator.storage.getDirectory();
|
||||
Assert.ok(root, "Can we access the root directory?");
|
||||
|
||||
const testFile = await root.getFileHandle("test.txt");
|
||||
Assert.ok(!!testFile, "Can't get file");
|
||||
let handle = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!!handle, "Can't create SyncAccessHandle");
|
||||
|
||||
try {
|
||||
let handle2 = await testFile.createSyncAccessHandle();
|
||||
Assert.ok(!handle2, "Shouldn't create SyncAccessHandle!");
|
||||
if (handle2) {
|
||||
await handle2.close();
|
||||
}
|
||||
} catch (e) {
|
||||
// should always happen
|
||||
dump("caught exception when we tried to get 2 SyncAccessHandles\n");
|
||||
}
|
||||
|
||||
// test that locks work across multiple connections for an origin
|
||||
try {
|
||||
let root2 = await navigator.storage.getDirectory();
|
||||
Assert.ok(root2, "Can we access the root2 directory?");
|
||||
|
||||
const testFile2 = await root2.getFileHandle("test.txt");
|
||||
Assert.ok(!!testFile2, "Can't get file");
|
||||
let handle2 = await testFile2.createSyncAccessHandle();
|
||||
Assert.ok(!handle2, "Shouldn't create SyncAccessHandle (2)!");
|
||||
if (handle2) {
|
||||
await handle2.close();
|
||||
}
|
||||
} catch (e) {
|
||||
// should always happen
|
||||
dump("caught exception when we tried to get 2 SyncAccessHandles\n");
|
||||
}
|
||||
|
||||
if (handle) {
|
||||
await handle.close();
|
||||
}
|
||||
};
|
||||
|
||||
for (const [key, value] of Object.entries(exported_symbols)) {
|
||||
Object.defineProperty(value, "name", {
|
||||
value: key,
|
||||
writable: false,
|
||||
});
|
||||
}
|
|
@ -6,16 +6,16 @@
|
|||
|
||||
#include "FileSystemMocks.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ErrorList.h"
|
||||
#include "gtest/gtest-assertion-result.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "jsapi.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace testing::internal {
|
||||
|
||||
GTEST_API_ ::testing::AssertionResult CmpHelperSTREQ(const char* s1_expression,
|
||||
|
|
|
@ -7,19 +7,13 @@
|
|||
#ifndef DOM_FS_TEST_GTEST_FILESYSTEMMOCKS_H_
|
||||
#define DOM_FS_TEST_GTEST_FILESYSTEMMOCKS_H_
|
||||
|
||||
#include <memory> // We don't have a mozilla shared pointer for pod types
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "TestHelpers.h"
|
||||
#include "fs/FileSystemChildFactory.h"
|
||||
|
||||
#include "fs/FileSystemRequestHandler.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "js/Promise.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "fs/FileSystemChildFactory.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
|
@ -29,11 +23,20 @@
|
|||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "js/Promise.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
#include <memory> // We don't have a mozilla shared pointer for pod types
|
||||
|
||||
namespace testing::internal {
|
||||
|
||||
GTEST_API_ ::testing::AssertionResult CmpHelperSTREQ(const char* s1_expression,
|
||||
|
@ -46,7 +49,7 @@ GTEST_API_ ::testing::AssertionResult CmpHelperSTREQ(const char* s1_expression,
|
|||
namespace mozilla::dom::fs {
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& aOut,
|
||||
const FileSystemEntryMetadata& aMetadata) {
|
||||
const FileSystemEntryMetadata aMetadata) {
|
||||
return aOut;
|
||||
}
|
||||
|
||||
|
@ -93,19 +96,6 @@ class MockFileSystemRequestHandler : public FileSystemRequestHandler {
|
|||
RefPtr<Promise> aPromise),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, MoveEntry,
|
||||
(RefPtr<FileSystemManager> & aManager, FileSystemHandle* aHandle,
|
||||
const FileSystemEntryMetadata& aEntry,
|
||||
const FileSystemChildMetadata& aNewEntry,
|
||||
RefPtr<Promise> aPromise),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, RenameEntry,
|
||||
(RefPtr<FileSystemManager> & aManager, FileSystemHandle* aHandle,
|
||||
const FileSystemEntryMetadata& aEntry, const Name& aName,
|
||||
RefPtr<Promise> aPromise),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void, Resolve,
|
||||
(RefPtr<FileSystemManager> & aManager,
|
||||
const FileSystemEntryPair& aEndpoints, RefPtr<Promise> aPromise),
|
||||
|
@ -246,14 +236,6 @@ class TestFileSystemManagerChild : public FileSystemManagerChild {
|
|||
mozilla::ipc::RejectCallback&& aReject),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(
|
||||
void, SendGetAccessHandle,
|
||||
(const FileSystemGetAccessHandleRequest& request,
|
||||
mozilla::ipc::ResolveCallback<FileSystemGetAccessHandleResponse>&&
|
||||
aResolve,
|
||||
mozilla::ipc::RejectCallback&& aReject),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(
|
||||
void, SendGetFile,
|
||||
(const FileSystemGetFileRequest& request,
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#ifndef DOM_FS_TEST_GTEST_TESTHELPERS_H_
|
||||
#define DOM_FS_TEST_GTEST_TESTHELPERS_H_
|
||||
|
||||
#include "ErrorList.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/ErrorNames.h"
|
||||
|
||||
#include "ErrorList.h"
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
#include "mozilla/ErrorNames.h"
|
||||
|
||||
#define ASSERT_NSEQ(lhs, rhs) \
|
||||
ASSERT_STREQ(GetStaticErrorName((lhs)), GetStaticErrorName((rhs)))
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
* 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/. */
|
||||
|
||||
#include "FileSystemMocks.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "FileSystemMocks.h"
|
||||
|
||||
#include "mozilla/dom/FileSystemDirectoryHandle.h"
|
||||
#include "mozilla/dom/FileSystemDirectoryHandleBinding.h"
|
||||
#include "mozilla/dom/FileSystemDirectoryIterator.h"
|
||||
|
@ -14,6 +15,8 @@
|
|||
#include "mozilla/dom/FileSystemHandleBinding.h"
|
||||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "mozilla/dom/StorageManager.h"
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
|
||||
using ::testing::_;
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
* 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/. */
|
||||
|
||||
#include "FileSystemMocks.h"
|
||||
#include "fs/FileSystemChildFactory.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "FileSystemMocks.h"
|
||||
|
||||
#include "fs/FileSystemChildFactory.h"
|
||||
|
||||
#include "mozilla/dom/FileSystemFileHandle.h"
|
||||
#include "mozilla/dom/FileSystemFileHandleBinding.h"
|
||||
#include "mozilla/dom/FileSystemHandle.h"
|
||||
|
@ -15,6 +17,7 @@
|
|||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/StorageManager.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
|
||||
namespace mozilla::dom::fs::test {
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
* 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/. */
|
||||
|
||||
#include "FileSystemMocks.h"
|
||||
#include "fs/FileSystemChildFactory.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "FileSystemMocks.h"
|
||||
|
||||
#include "fs/FileSystemChildFactory.h"
|
||||
|
||||
#include "mozilla/dom/FileSystemHandle.h"
|
||||
#include "mozilla/dom/FileSystemDirectoryHandle.h"
|
||||
#include "mozilla/dom/FileSystemFileHandle.h"
|
||||
#include "mozilla/dom/FileSystemHandle.h"
|
||||
|
@ -92,11 +96,11 @@ TEST_F(TestFileSystemHandle, isDifferentEntry) {
|
|||
RefPtr<Promise> promise = dirHandle->IsSameEntry(*fileHandle, rv);
|
||||
ASSERT_TRUE(rv.ErrorCodeIs(NS_OK));
|
||||
ASSERT_TRUE(promise);
|
||||
ASSERT_EQ(Promise::PromiseState::Resolved, promise->State());
|
||||
ASSERT_EQ(Promise::PromiseState::Rejected, promise->State());
|
||||
|
||||
nsString result;
|
||||
ASSERT_NSEQ(NS_OK, GetAsString(promise, result));
|
||||
ASSERT_STREQ(u"false"_ns, result);
|
||||
ASSERT_STREQ(u"NS_ERROR_NOT_IMPLEMENTED"_ns, result);
|
||||
}
|
||||
|
||||
TEST_F(TestFileSystemHandle, isSameEntry) {
|
||||
|
@ -107,11 +111,11 @@ TEST_F(TestFileSystemHandle, isSameEntry) {
|
|||
RefPtr<Promise> promise = fileHandle->IsSameEntry(*fileHandle, rv);
|
||||
ASSERT_TRUE(rv.ErrorCodeIs(NS_OK));
|
||||
ASSERT_TRUE(promise);
|
||||
ASSERT_EQ(Promise::PromiseState::Resolved, promise->State());
|
||||
ASSERT_EQ(Promise::PromiseState::Rejected, promise->State());
|
||||
|
||||
nsString result;
|
||||
ASSERT_NSEQ(NS_OK, GetAsString(promise, result));
|
||||
ASSERT_STREQ(u"true"_ns, result);
|
||||
ASSERT_STREQ(u"NS_ERROR_NOT_IMPLEMENTED"_ns, result);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom::fs::test
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
* 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/. */
|
||||
|
||||
#include "FileSystemBackgroundRequestHandler.h"
|
||||
#include "FileSystemEntryMetadataArray.h"
|
||||
#include "FileSystemBackgroundRequestHandler.h"
|
||||
#include "FileSystemMocks.h"
|
||||
#include "fs/FileSystemRequestHandler.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/IPCBlob.h"
|
||||
#include "mozilla/dom/FileSystemManager.h"
|
||||
#include "mozilla/dom/FileSystemManagerChild.h"
|
||||
#include "mozilla/dom/IPCBlob.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "mozilla/dom/StorageManager.h"
|
||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||
#include "mozilla/ipc/IPCCore.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::ByRef;
|
||||
|
|
|
@ -4,15 +4,17 @@
|
|||
* 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/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "FileSystemHashSource.h"
|
||||
#include "TestHelpers.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/Array.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsString.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTHashSet.h"
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
#include "FileSystemDataManager.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/dom/quota/QuotaManagerService.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIQuotaCallbacks.h"
|
||||
|
|
|
@ -9,28 +9,28 @@
|
|||
#include "FileSystemDatabaseManagerVersion001.h"
|
||||
#include "FileSystemFileManager.h"
|
||||
#include "FileSystemHashSource.h"
|
||||
#include "ResultStatement.h"
|
||||
#include "SchemaVersion001.h"
|
||||
#include "TestHelpers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "mozilla/Array.h"
|
||||
#include "mozilla/ErrorNames.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/dom/FileSystemTypes.h"
|
||||
#include "mozilla/dom/PFileSystemManager.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTHashSet.h"
|
||||
#include "ResultStatement.h"
|
||||
#include "SchemaVersion001.h"
|
||||
#include "TestHelpers.h"
|
||||
|
||||
namespace mozilla::dom::fs::test {
|
||||
|
||||
|
@ -265,6 +265,53 @@ TEST(TestFileSystemDatabaseManagerVersion001, smokeTestCreateRemoveFiles)
|
|||
<< fileItemRef.entryName();
|
||||
ASSERT_EQ(firstChild, fileItemRef.entryId());
|
||||
|
||||
// Non-empty root directory also may not be removed except recursively
|
||||
FileSystemChildMetadata rootChildMeta(getTestOrigin(), u"root"_ns);
|
||||
TEST_TRY_UNWRAP_ERR(
|
||||
rv, dm->RemoveDirectory(rootChildMeta, /* recursive */ false));
|
||||
ASSERT_NSEQ(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR,
|
||||
rv); // Is this a good error?
|
||||
|
||||
TEST_TRY_UNWRAP(isDeleted,
|
||||
dm->RemoveDirectory(rootChildMeta, /* recursive */ true));
|
||||
ASSERT_TRUE(isDeleted);
|
||||
|
||||
// Directory listing of root directory works after it has been cleared
|
||||
TEST_TRY_UNWRAP(FileSystemDirectoryListing rEntries,
|
||||
dm->GetDirectoryEntries(rootId, 0));
|
||||
ASSERT_EQ(0u, rEntries.directories().Length());
|
||||
ASSERT_EQ(0u, rEntries.files().Length());
|
||||
|
||||
// Creating a file under the removed root directory fails
|
||||
TEST_TRY_UNWRAP_ERR(rv,
|
||||
dm->GetOrCreateFile(firstChildMeta, /* create */ true));
|
||||
ASSERT_NSEQ(NS_ERROR_STORAGE_CONSTRAINT, rv); // Root doesn't exist
|
||||
|
||||
// Creating a non-child file still fails
|
||||
TEST_TRY_UNWRAP_ERR(rv,
|
||||
dm->GetOrCreateFile(notAChildMeta, /* create */ true));
|
||||
ASSERT_NSEQ(NS_ERROR_STORAGE_CONSTRAINT, rv); // Is this a good error?
|
||||
|
||||
// Creating a directory under the removed root directory fails
|
||||
TEST_TRY_UNWRAP_ERR(
|
||||
rv, dm->GetOrCreateDirectory(firstChildMeta, /* create */ true));
|
||||
ASSERT_NSEQ(NS_ERROR_STORAGE_CONSTRAINT, rv); // Root doesn't exist
|
||||
|
||||
// Creating a non-child directory still fails
|
||||
TEST_TRY_UNWRAP_ERR(
|
||||
rv, dm->GetOrCreateDirectory(notAChildMeta, /* create */ true));
|
||||
ASSERT_NSEQ(NS_ERROR_STORAGE_CONSTRAINT, rv); // Is this a good error?
|
||||
|
||||
// Creating a root file fails
|
||||
TEST_TRY_UNWRAP_ERR(rv,
|
||||
dm->GetOrCreateFile(rootChildMeta, /* create */ true));
|
||||
ASSERT_NSEQ(NS_ERROR_STORAGE_CONSTRAINT, rv); // Is this a good error?
|
||||
|
||||
// Creating a root directory via GetOrCreateDirectory fails
|
||||
TEST_TRY_UNWRAP_ERR(
|
||||
rv, dm->GetOrCreateDirectory(rootChildMeta, /* create */ true));
|
||||
ASSERT_NSEQ(NS_ERROR_STORAGE_CONSTRAINT, rv); // Is this a good error?
|
||||
|
||||
dm->Close();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
add_task(async function worker() {
|
||||
await run_test_in_worker("worker/test_syncAccessHandle_worker.js");
|
||||
});
|
|
@ -8,5 +8,4 @@ TESTING_JS_MODULES.dom.fs.test.xpcshell.worker += [
|
|||
"head.js",
|
||||
"test_basics_worker.js",
|
||||
"test_fileSystemDirectoryHandle_worker.js",
|
||||
"test_syncAccessHandle_worker.js",
|
||||
]
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
add_task(async function init() {
|
||||
const testCases = await require_module(
|
||||
"dom/fs/test/common/test_syncAccessHandle.js"
|
||||
);
|
||||
Object.values(testCases).forEach(async testItem => {
|
||||
add_task(testItem);
|
||||
});
|
||||
});
|
|
@ -9,4 +9,3 @@ head = head.js
|
|||
[test_basics_worker.js]
|
||||
[test_fileSystemDirectoryHandle.js]
|
||||
[test_fileSystemDirectoryHandle_worker.js]
|
||||
[test_syncAccessHandle_worker.js]
|
||||
|
|
|
@ -13,14 +13,6 @@ interface FileSystemHandle {
|
|||
readonly attribute FileSystemHandleKind kind;
|
||||
readonly attribute USVString name;
|
||||
|
||||
/* https://whatpr.org/fs/10.html#api-filesystemhandle */
|
||||
[NewObject]
|
||||
Promise<void> move(USVString name);
|
||||
[NewObject]
|
||||
Promise<void> move(FileSystemDirectoryHandle parent);
|
||||
[NewObject]
|
||||
Promise<void> move(FileSystemDirectoryHandle parent, USVString name);
|
||||
|
||||
[NewObject]
|
||||
Promise<boolean> isSameEntry(FileSystemHandle other);
|
||||
};
|
||||
|
|
|
@ -10,8 +10,8 @@ dictionary FileSystemReadWriteOptions {
|
|||
[Exposed=(DedicatedWorker), SecureContext, Pref="dom.fs.enabled"]
|
||||
interface FileSystemSyncAccessHandle {
|
||||
// TODO: Use `[AllowShared] BufferSource data` once it works (bug 1696216)
|
||||
[Throws] unsigned long long read(([AllowShared] ArrayBufferView or [AllowShared] ArrayBuffer) buffer, optional FileSystemReadWriteOptions options = {});
|
||||
[Throws] unsigned long long write(([AllowShared] ArrayBufferView or [AllowShared] ArrayBuffer) buffer, optional FileSystemReadWriteOptions options = {});
|
||||
unsigned long long read(([AllowShared] ArrayBufferView or [AllowShared] ArrayBuffer) buffer, optional FileSystemReadWriteOptions options = {});
|
||||
unsigned long long write(([AllowShared] ArrayBufferView or [AllowShared] ArrayBuffer) buffer, optional FileSystemReadWriteOptions options = {});
|
||||
|
||||
[NewObject]
|
||||
Promise<void> truncate([EnforceRange] unsigned long long size);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
[removeEntry() with a path separator should fail.]
|
||||
expected: FAIL
|
||||
|
||||
[removeEntry() while the file has an open writable fails]
|
||||
[removeEntry() while the file has an open writable succeeds]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
[opaque-origin.https.window.html]
|
||||
[FileSystemDirectoryHandle must be defined for data URI iframes.]
|
||||
expected: FAIL
|
||||
|
||||
[navigator.storage.getDirectory() must reject in a sandboxed iframe.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ function add_iframe(test, src, sandbox) {
|
|||
// Creates a data URI iframe that uses postMessage() to provide its parent
|
||||
// with the test result. The iframe checks for the existence of
|
||||
// |property_name| on the window.
|
||||
async function verify_does_exist_in_data_uri_iframe(
|
||||
async function verify_does_not_exist_in_data_uri_iframe(
|
||||
test, property_name) {
|
||||
const iframe_content =
|
||||
'<script>' +
|
||||
|
@ -32,8 +32,8 @@ async function verify_does_exist_in_data_uri_iframe(
|
|||
const event_watcher = new EventWatcher(test, self, 'message');
|
||||
const message_event = await event_watcher.wait_for('message')
|
||||
|
||||
assert_true(message_event.data.is_property_name_defined,
|
||||
`Data URI iframes must define '${property_name}'.`);
|
||||
assert_false(message_event.data.is_property_name_defined,
|
||||
`Data URI iframes must not define '${property_name}'.`);
|
||||
}
|
||||
|
||||
// |kSandboxWindowUrl| sends the result of navigator.storage.getDirectory() to
|
||||
|
@ -48,9 +48,9 @@ async function verify_results_from_sandboxed_child_window(test) {
|
|||
}
|
||||
|
||||
promise_test(async test => {
|
||||
await verify_does_exist_in_data_uri_iframe(
|
||||
await verify_does_not_exist_in_data_uri_iframe(
|
||||
test, 'FileSystemDirectoryHandle');
|
||||
}, 'FileSystemDirectoryHandle must be defined for data URI iframes.');
|
||||
}, 'FileSystemDirectoryHandle must be undefined for data URI iframes.');
|
||||
|
||||
promise_test(
|
||||
async test => {
|
||||
|
|
|
@ -30,17 +30,12 @@ async function serialize_handle(handle) {
|
|||
// serialized properties shared by both FileSystemFileHandle and
|
||||
// FileSystemDirectoryHandle.
|
||||
async function serialize_file_system_handle(handle) {
|
||||
let read_permission = "granted";
|
||||
let write_permission = "granted";
|
||||
// query-permission is part of the File System Acecss API
|
||||
// https://wicg.github.io/file-system-access, which may not be supported
|
||||
if ("queryPermission" in FileSystemHandle.prototype) {
|
||||
read_permission =
|
||||
await handle.queryPermission({ mode: 'read' });
|
||||
const read_permission =
|
||||
await handle.queryPermission({ mode: 'read' });
|
||||
|
||||
const write_permission =
|
||||
await handle.queryPermission({ mode: 'readwrite' })
|
||||
|
||||
write_permission =
|
||||
await handle.queryPermission({ mode: 'readwrite' })
|
||||
}
|
||||
return {
|
||||
kind: handle.kind,
|
||||
name: handle.name,
|
||||
|
|
|
@ -34,11 +34,10 @@ async function getDirectoryEntryCount(handle) {
|
|||
async function getSortedDirectoryEntries(handle) {
|
||||
let result = [];
|
||||
for await (let entry of handle.values()) {
|
||||
if (entry.kind === 'directory') {
|
||||
if (entry.kind === 'directory')
|
||||
result.push(entry.name + '/');
|
||||
} else {
|
||||
else
|
||||
result.push(entry.name);
|
||||
}
|
||||
}
|
||||
result.sort();
|
||||
return result;
|
||||
|
@ -86,21 +85,3 @@ function garbageCollect() {
|
|||
if (self.gc)
|
||||
self.gc();
|
||||
};
|
||||
|
||||
async function cleanup(test, value, cleanup_func) {
|
||||
test.add_cleanup(async () => {
|
||||
try {
|
||||
await cleanup_func();
|
||||
} catch (e) {
|
||||
// Ignore any errors when removing files, as tests might already remove
|
||||
// the file.
|
||||
}
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
async function cleanup_writable(test, value) {
|
||||
return cleanup(test, value, async () => {
|
||||
value.close();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ directory_test(async (t, root_dir) => {
|
|||
const db = await createDatabase(t, db => {
|
||||
const store = db.createObjectStore('store');
|
||||
});
|
||||
t.add_cleanup(() => deleteAllDatabases(t));
|
||||
|
||||
const value = handles;
|
||||
|
||||
|
@ -27,6 +28,7 @@ directory_test(async (t, root_dir) => {
|
|||
const db = await createDatabase(t, db => {
|
||||
const store = db.createObjectStore('store');
|
||||
});
|
||||
t.add_cleanup(() => deleteAllDatabases(t));
|
||||
|
||||
const value = handles;
|
||||
|
||||
|
@ -51,6 +53,7 @@ directory_test(async (t, root_dir) => {
|
|||
const db = await createDatabase(t, db => {
|
||||
const store = db.createObjectStore('store');
|
||||
});
|
||||
t.add_cleanup(() => deleteAllDatabases(t));
|
||||
|
||||
const value = {handles, blob: new Blob(["foobar"])};
|
||||
|
||||
|
@ -77,6 +80,7 @@ directory_test(async (t, root_dir) => {
|
|||
const db = await createDatabase(t, db => {
|
||||
const store = db.createObjectStore('store');
|
||||
});
|
||||
t.add_cleanup(() => deleteAllDatabases(t));
|
||||
|
||||
const value = handles;
|
||||
|
||||
|
@ -103,6 +107,7 @@ directory_test(async (t, root_dir) => {
|
|||
const db = await createDatabase(t, db => {
|
||||
const store = db.createObjectStore('store', {keyPath: 'key'});
|
||||
});
|
||||
t.add_cleanup(() => deleteAllDatabases(t));
|
||||
|
||||
const value = handles;
|
||||
let tx = db.transaction('store', 'readwrite');
|
||||
|
|
|
@ -23,6 +23,7 @@ directory_test(async (t, root) => {
|
|||
await root.removeEntry('dir-to-remove');
|
||||
|
||||
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
|
||||
await promise_rejects_dom(t, 'NotFoundError', getSortedDirectoryEntries(dir));
|
||||
}, 'removeEntry() to remove an empty directory');
|
||||
|
||||
directory_test(async (t, root) => {
|
||||
|
@ -92,13 +93,11 @@ directory_test(async (t, root) => {
|
|||
await createFileWithContents(t, 'file-to-keep', 'abc', root);
|
||||
|
||||
const writable = await handle.createWritable();
|
||||
await promise_rejects_dom(
|
||||
t, 'InvalidModificationError', root.removeEntry('file-to-remove'));
|
||||
await root.removeEntry('file-to-remove');
|
||||
await promise_rejects_dom(t, 'NotFoundError', getFileContents(handle));
|
||||
|
||||
await writable.close();
|
||||
await root.removeEntry('file-to-remove');
|
||||
|
||||
assert_array_equals(
|
||||
await getSortedDirectoryEntries(root),
|
||||
['file-to-keep']);
|
||||
}, 'removeEntry() while the file has an open writable fails');
|
||||
['file-to-keep', 'file-to-remove']);
|
||||
}, 'removeEntry() while the file has an open writable succeeds');
|
||||
|
|
|
@ -11,14 +11,6 @@ directory_test(async (t, root) => {
|
|||
assert_equals(await getFileSize(handle), 3);
|
||||
}, 'move(name) to rename a file');
|
||||
|
||||
directory_test(async (t, root) => {
|
||||
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
|
||||
await handle.move('file-after');
|
||||
const newhandle = await root.getFileHandle('file-after');
|
||||
assert_equals(await getFileContents(newhandle), 'foo');
|
||||
assert_equals(await getFileSize(newhandle), 3);
|
||||
}, 'get a handle to a moved file');
|
||||
|
||||
directory_test(async (t, root) => {
|
||||
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
|
||||
await handle.move('file-before');
|
||||
|
@ -63,7 +55,7 @@ directory_test(async (t, root) => {
|
|||
|
||||
directory_test(async (t, root) => {
|
||||
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
|
||||
await promise_rejects_js(t, TypeError, handle.move('test/test'));
|
||||
await promise_rejects_js(t, TypeError, handle.move('#$23423@352^*3243'));
|
||||
|
||||
assert_array_equals(await getSortedDirectoryEntries(root), ['file-before']);
|
||||
assert_equals(await getFileContents(handle), 'foo');
|
||||
|
@ -74,7 +66,7 @@ directory_test(async (t, root) => {
|
|||
const handle = await createFileWithContents(t, 'file-before', 'abc', root);
|
||||
|
||||
// Cannot rename handle with an active writable.
|
||||
const stream = await cleanup_writable(t, await handle.createWritable());
|
||||
const stream = await handle.createWritable();
|
||||
await promise_rejects_dom(
|
||||
t, 'NoModificationAllowedError', handle.move('file-after'));
|
||||
|
||||
|
@ -90,7 +82,7 @@ directory_test(async (t, root) => {
|
|||
await createFileWithContents(t, 'file-after', '123', root);
|
||||
|
||||
// Cannot overwrite a handle with an active writable.
|
||||
const stream = await cleanup_writable(t, await handle_dest.createWritable());
|
||||
const stream = await handle_dest.createWritable();
|
||||
await promise_rejects_dom(
|
||||
t, 'NoModificationAllowedError', handle.move('file-after'));
|
||||
|
||||
|
@ -246,7 +238,8 @@ directory_test(async (t, root) => {
|
|||
|
||||
directory_test(async (t, root) => {
|
||||
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
|
||||
await promise_rejects_js(t, TypeError, handle.move(root, '..'));
|
||||
await promise_rejects_js(
|
||||
t, TypeError, handle.move(root, '#$23423@352^*3243'));
|
||||
|
||||
assert_array_equals(await getSortedDirectoryEntries(root), ['file-before']);
|
||||
assert_equals(await getFileContents(handle), 'foo');
|
||||
|
@ -259,7 +252,7 @@ directory_test(async (t, root) => {
|
|||
const file = await createFileWithContents(t, 'file', 'abc', dir_src);
|
||||
|
||||
// Cannot move handle with an active writable.
|
||||
const stream = await cleanup_writable(t, await file.createWritable());
|
||||
const stream = await file.createWritable();
|
||||
await promise_rejects_dom(t, 'NoModificationAllowedError', file.move(dir_dest));
|
||||
|
||||
assert_array_equals(
|
||||
|
@ -282,7 +275,7 @@ directory_test(async (t, root) => {
|
|||
const file = await createFileWithContents(t, 'file-before', 'abc', dir_src);
|
||||
|
||||
// Cannot move handle with an active writable.
|
||||
const stream = await cleanup_writable(t, await file.createWritable());
|
||||
const stream = await file.createWritable();
|
||||
await promise_rejects_dom(t, 'NoModificationAllowedError', file.move(dir_dest));
|
||||
|
||||
assert_array_equals(
|
||||
|
@ -307,7 +300,7 @@ directory_test(async (t, root) => {
|
|||
const file_dest = await createFileWithContents(t, 'file', '123', dir_dest);
|
||||
|
||||
// Cannot overwrite handle with an active writable.
|
||||
const stream = await cleanup_writable(t, await file_dest.createWritable());
|
||||
const stream = await file_dest.createWritable();
|
||||
await promise_rejects_dom(t, 'NoModificationAllowedError', file.move(dir_dest));
|
||||
|
||||
assert_array_equals(
|
||||
|
@ -334,7 +327,7 @@ directory_test(async (t, root) => {
|
|||
await createFileWithContents(t, 'file-dest', '123', dir_dest);
|
||||
|
||||
// Cannot overwrite handle with an active writable.
|
||||
const stream = await cleanup_writable(t, await file_dest.createWritable());
|
||||
const stream = await file_dest.createWritable();
|
||||
await promise_rejects_dom(
|
||||
t, 'NoModificationAllowedError', file.move(dir_dest, 'file-dest'));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче