/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=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 "FileHandle.h" #include "nsContentUtils.h" #include "nsDOMClassInfoID.h" #include "nsIDOMFile.h" #include "nsIFileStorage.h" #include "FileRequest.h" #include "FileService.h" #include "LockedFile.h" #include "MetadataHelper.h" USING_FILE_NAMESPACE namespace { class GetFileHelper : public MetadataHelper { public: GetFileHelper(LockedFile* aLockedFile, FileRequest* aFileRequest, MetadataParameters* aParams, FileHandle* aFileHandle) : MetadataHelper(aLockedFile, aFileRequest, aParams), mFileHandle(aFileHandle) { } nsresult GetSuccessResult(JSContext* aCx, jsval* aVal); void ReleaseObjects() { mFileHandle = nullptr; MetadataHelper::ReleaseObjects(); } private: nsRefPtr mFileHandle; }; } // anonymous namespace NS_IMPL_CYCLE_COLLECTION_CLASS(FileHandle) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileHandle, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileStorage) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileHandle, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileStorage) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileHandle) NS_INTERFACE_MAP_ENTRY(nsIDOMFileHandle) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(FileHandle, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(FileHandle, nsDOMEventTargetHelper) NS_IMPL_EVENT_HANDLER(FileHandle, abort) NS_IMPL_EVENT_HANDLER(FileHandle, error) NS_IMETHODIMP FileHandle::GetName(nsAString& aName) { aName = mName; return NS_OK; } NS_IMETHODIMP FileHandle::GetType(nsAString& aType) { aType = mType; return NS_OK; } NS_IMETHODIMP FileHandle::Open(const nsAString& aMode, uint8_t aOptionalArgCount, nsIDOMLockedFile** _retval) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); if (FileService::IsShuttingDown() || mFileStorage->IsStorageShuttingDown()) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } LockedFile::Mode mode; if (aOptionalArgCount) { if (aMode.EqualsLiteral("readwrite")) { mode = LockedFile::READ_WRITE; } else if (aMode.EqualsLiteral("readonly")) { mode = LockedFile::READ_ONLY; } else { return NS_ERROR_TYPE_ERR; } } else { mode = LockedFile::READ_ONLY; } nsRefPtr lockedFile = LockedFile::Create(this, mode); NS_ENSURE_TRUE(lockedFile, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR); lockedFile.forget(_retval); return NS_OK; } NS_IMETHODIMP FileHandle::GetFile(nsIDOMDOMRequest** _retval) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); // Do nothing if the window is closed if (!GetOwner()) { return NS_OK; } nsRefPtr lockedFile = LockedFile::Create(this, LockedFile::READ_ONLY, LockedFile::PARALLEL); NS_ENSURE_TRUE(lockedFile, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR); nsRefPtr request = FileRequest::Create(GetOwner(), lockedFile, false); nsRefPtr params = new MetadataParameters(); params->Init(true, false); nsRefPtr helper = new GetFileHelper(lockedFile, request, params, this); nsresult rv = helper->Enqueue(); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR); nsCOMPtr result = static_cast(request); result.forget(_retval); return NS_OK; } NS_IMETHODIMP_(int64_t) FileHandle::GetFileId() { return -1; } NS_IMETHODIMP_(mozilla::dom::indexedDB::FileInfo*) FileHandle::GetFileInfo() { return nullptr; } nsresult GetFileHelper::GetSuccessResult(JSContext* aCx, jsval* aVal) { nsCOMPtr domFile = mFileHandle->CreateFileObject(mLockedFile, mParams->Size()); nsresult rv = nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domFile, &NS_GET_IID(nsIDOMFile), aVal); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR); return NS_OK; }