diff options
Diffstat (limited to 'dom/indexedDB/IDBFileHandle.cpp')
-rw-r--r-- | dom/indexedDB/IDBFileHandle.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/dom/indexedDB/IDBFileHandle.cpp b/dom/indexedDB/IDBFileHandle.cpp new file mode 100644 index 000000000..8b88e1722 --- /dev/null +++ b/dom/indexedDB/IDBFileHandle.cpp @@ -0,0 +1,199 @@ +/* -*- 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 "IDBFileHandle.h" + +#include "IDBEvents.h" +#include "IDBMutableFile.h" +#include "mozilla/Assertions.h" +#include "mozilla/dom/IDBFileHandleBinding.h" +#include "mozilla/dom/filehandle/ActorsChild.h" +#include "mozilla/EventDispatcher.h" +#include "nsServiceManagerUtils.h" +#include "nsWidgetsCID.h" + +namespace mozilla { +namespace dom { + +using namespace mozilla::dom::indexedDB; + +IDBFileHandle::IDBFileHandle(FileMode aMode, + IDBMutableFile* aMutableFile) + : FileHandleBase(DEBUGONLY(aMutableFile->OwningThread(),) + aMode) + , mMutableFile(aMutableFile) +{ + AssertIsOnOwningThread(); +} + +IDBFileHandle::~IDBFileHandle() +{ + AssertIsOnOwningThread(); + + mMutableFile->UnregisterFileHandle(this); +} + +// static +already_AddRefed<IDBFileHandle> +IDBFileHandle::Create(IDBMutableFile* aMutableFile, + FileMode aMode) +{ + MOZ_ASSERT(aMutableFile); + aMutableFile->AssertIsOnOwningThread(); + MOZ_ASSERT(aMode == FileMode::Readonly || aMode == FileMode::Readwrite); + + RefPtr<IDBFileHandle> fileHandle = + new IDBFileHandle(aMode, aMutableFile); + + fileHandle->BindToOwner(aMutableFile); + + // XXX Fix! + MOZ_ASSERT(NS_IsMainThread(), "This won't work on non-main threads!"); + + nsCOMPtr<nsIRunnable> runnable = do_QueryObject(fileHandle); + nsContentUtils::RunInMetastableState(runnable.forget()); + + fileHandle->SetCreating(); + + aMutableFile->RegisterFileHandle(fileHandle); + + return fileHandle.forget(); +} + +already_AddRefed<IDBFileRequest> +IDBFileHandle::GetMetadata(const IDBFileMetadataParameters& aParameters, + ErrorResult& aRv) +{ + AssertIsOnOwningThread(); + + // Common state checking + if (!CheckState(aRv)) { + return nullptr; + } + + // Argument checking for get metadata. + if (!aParameters.mSize && !aParameters.mLastModified) { + aRv.ThrowTypeError<MSG_METADATA_NOT_CONFIGURED>(); + return nullptr; + } + + // Do nothing if the window is closed + if (!CheckWindow()) { + return nullptr; + } + + FileRequestGetMetadataParams params; + params.size() = aParameters.mSize; + params.lastModified() = aParameters.mLastModified; + + RefPtr<FileRequestBase> fileRequest = GenerateFileRequest(); + + StartRequest(fileRequest, params); + + return fileRequest.forget().downcast<IDBFileRequest>(); +} + +NS_IMPL_ADDREF_INHERITED(IDBFileHandle, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(IDBFileHandle, DOMEventTargetHelper) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBFileHandle) + NS_INTERFACE_MAP_ENTRY(nsIRunnable) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +NS_IMPL_CYCLE_COLLECTION_CLASS(IDBFileHandle) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBFileHandle, + DOMEventTargetHelper) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMutableFile) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBFileHandle, + DOMEventTargetHelper) + // Don't unlink mMutableFile! +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMETHODIMP +IDBFileHandle::Run() +{ + AssertIsOnOwningThread(); + + OnReturnToEventLoop(); + + return NS_OK; +} + +nsresult +IDBFileHandle::PreHandleEvent(EventChainPreVisitor& aVisitor) +{ + AssertIsOnOwningThread(); + + aVisitor.mCanHandle = true; + aVisitor.mParentTarget = mMutableFile; + return NS_OK; +} + +// virtual +JSObject* +IDBFileHandle::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) +{ + AssertIsOnOwningThread(); + + return IDBFileHandleBinding::Wrap(aCx, this, aGivenProto); +} + +mozilla::dom::MutableFileBase* +IDBFileHandle::MutableFile() const +{ + AssertIsOnOwningThread(); + + return mMutableFile; +} + +void +IDBFileHandle::HandleCompleteOrAbort(bool aAborted) +{ + AssertIsOnOwningThread(); + + FileHandleBase::HandleCompleteOrAbort(aAborted); + + nsCOMPtr<nsIDOMEvent> event; + if (aAborted) { + event = CreateGenericEvent(this, nsDependentString(kAbortEventType), + eDoesBubble, eNotCancelable); + } else { + event = CreateGenericEvent(this, nsDependentString(kCompleteEventType), + eDoesNotBubble, eNotCancelable); + } + if (NS_WARN_IF(!event)) { + return; + } + + bool dummy; + if (NS_FAILED(DispatchEvent(event, &dummy))) { + NS_WARNING("DispatchEvent failed!"); + } +} + +bool +IDBFileHandle::CheckWindow() +{ + AssertIsOnOwningThread(); + + return GetOwner(); +} + +already_AddRefed<mozilla::dom::FileRequestBase> +IDBFileHandle::GenerateFileRequest() +{ + AssertIsOnOwningThread(); + + return IDBFileRequest::Create(GetOwner(), this, + /* aWrapAsDOMRequest */ false); +} + +} // namespace dom +} // namespace mozilla |