зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1370519 - Part 3: Remove unused files; r=btseng
This commit is contained in:
Родитель
4cc459c1a1
Коммит
d0c12b86b4
|
@ -1,742 +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 "ActorsChild.h"
|
||||
|
||||
#include "BackgroundChildImpl.h"
|
||||
#include "FileHandleBase.h"
|
||||
#include "FileRequestBase.h"
|
||||
#include "js/Date.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/ipc/PendingIPCBlobChild.h"
|
||||
#include "MutableFileBase.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*******************************************************************************
|
||||
* Helpers
|
||||
******************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
class MOZ_STACK_CLASS AutoSetCurrentFileHandle final
|
||||
{
|
||||
typedef mozilla::ipc::BackgroundChildImpl BackgroundChildImpl;
|
||||
|
||||
FileHandleBase* const mFileHandle;
|
||||
FileHandleBase* mPreviousFileHandle;
|
||||
FileHandleBase** mThreadLocalSlot;
|
||||
|
||||
public:
|
||||
explicit AutoSetCurrentFileHandle(FileHandleBase* aFileHandle)
|
||||
: mFileHandle(aFileHandle)
|
||||
, mPreviousFileHandle(nullptr)
|
||||
, mThreadLocalSlot(nullptr)
|
||||
{
|
||||
if (aFileHandle) {
|
||||
BackgroundChildImpl::ThreadLocal* threadLocal =
|
||||
BackgroundChildImpl::GetThreadLocalForCurrentThread();
|
||||
MOZ_ASSERT(threadLocal);
|
||||
|
||||
// Hang onto this location for resetting later.
|
||||
mThreadLocalSlot = &threadLocal->mCurrentFileHandle;
|
||||
|
||||
// Save the current value.
|
||||
mPreviousFileHandle = *mThreadLocalSlot;
|
||||
|
||||
// Set the new value.
|
||||
*mThreadLocalSlot = aFileHandle;
|
||||
}
|
||||
}
|
||||
|
||||
~AutoSetCurrentFileHandle()
|
||||
{
|
||||
MOZ_ASSERT_IF(mThreadLocalSlot, mFileHandle);
|
||||
MOZ_ASSERT_IF(mThreadLocalSlot, *mThreadLocalSlot == mFileHandle);
|
||||
|
||||
if (mThreadLocalSlot) {
|
||||
// Reset old value.
|
||||
*mThreadLocalSlot = mPreviousFileHandle;
|
||||
}
|
||||
}
|
||||
|
||||
FileHandleBase*
|
||||
FileHandle() const
|
||||
{
|
||||
return mFileHandle;
|
||||
}
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS ResultHelper final
|
||||
: public FileRequestBase::ResultCallback
|
||||
{
|
||||
FileRequestBase* mFileRequest;
|
||||
AutoSetCurrentFileHandle mAutoFileHandle;
|
||||
|
||||
union
|
||||
{
|
||||
File* mFile;
|
||||
const nsCString* mString;
|
||||
const FileRequestMetadata* mMetadata;
|
||||
const JS::Handle<JS::Value>* mJSValHandle;
|
||||
} mResult;
|
||||
|
||||
enum
|
||||
{
|
||||
ResultTypeFile,
|
||||
ResultTypeString,
|
||||
ResultTypeMetadata,
|
||||
ResultTypeJSValHandle,
|
||||
} mResultType;
|
||||
|
||||
public:
|
||||
ResultHelper(FileRequestBase* aFileRequest,
|
||||
FileHandleBase* aFileHandle,
|
||||
File* aResult)
|
||||
: mFileRequest(aFileRequest)
|
||||
, mAutoFileHandle(aFileHandle)
|
||||
, mResultType(ResultTypeFile)
|
||||
{
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
MOZ_ASSERT(aFileHandle);
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
mResult.mFile = aResult;
|
||||
}
|
||||
|
||||
ResultHelper(FileRequestBase* aFileRequest,
|
||||
FileHandleBase* aFileHandle,
|
||||
const nsCString* aResult)
|
||||
: mFileRequest(aFileRequest)
|
||||
, mAutoFileHandle(aFileHandle)
|
||||
, mResultType(ResultTypeString)
|
||||
{
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
MOZ_ASSERT(aFileHandle);
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
mResult.mString = aResult;
|
||||
}
|
||||
|
||||
ResultHelper(FileRequestBase* aFileRequest,
|
||||
FileHandleBase* aFileHandle,
|
||||
const FileRequestMetadata* aResult)
|
||||
: mFileRequest(aFileRequest)
|
||||
, mAutoFileHandle(aFileHandle)
|
||||
, mResultType(ResultTypeMetadata)
|
||||
{
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
MOZ_ASSERT(aFileHandle);
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
mResult.mMetadata = aResult;
|
||||
}
|
||||
|
||||
|
||||
ResultHelper(FileRequestBase* aFileRequest,
|
||||
FileHandleBase* aFileHandle,
|
||||
const JS::Handle<JS::Value>* aResult)
|
||||
: mFileRequest(aFileRequest)
|
||||
, mAutoFileHandle(aFileHandle)
|
||||
, mResultType(ResultTypeJSValHandle)
|
||||
{
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
MOZ_ASSERT(aFileHandle);
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
mResult.mJSValHandle = aResult;
|
||||
}
|
||||
|
||||
FileRequestBase*
|
||||
FileRequest() const
|
||||
{
|
||||
return mFileRequest;
|
||||
}
|
||||
|
||||
FileHandleBase*
|
||||
FileHandle() const
|
||||
{
|
||||
return mAutoFileHandle.FileHandle();
|
||||
}
|
||||
|
||||
virtual nsresult
|
||||
GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) override
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(mFileRequest);
|
||||
|
||||
switch (mResultType) {
|
||||
case ResultTypeFile:
|
||||
return GetResult(aCx, mResult.mFile, aResult);
|
||||
|
||||
case ResultTypeString:
|
||||
return GetResult(aCx, mResult.mString, aResult);
|
||||
|
||||
case ResultTypeMetadata:
|
||||
return GetResult(aCx, mResult.mMetadata, aResult);
|
||||
|
||||
case ResultTypeJSValHandle:
|
||||
aResult.set(*mResult.mJSValHandle);
|
||||
return NS_OK;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown result type!");
|
||||
}
|
||||
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
private:
|
||||
nsresult
|
||||
GetResult(JSContext* aCx,
|
||||
File* aFile,
|
||||
JS::MutableHandle<JS::Value> aResult)
|
||||
{
|
||||
bool ok = GetOrCreateDOMReflector(aCx, aFile, aResult);
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetResult(JSContext* aCx,
|
||||
const nsCString* aString,
|
||||
JS::MutableHandle<JS::Value> aResult)
|
||||
{
|
||||
const nsCString& data = *aString;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (!mFileRequest->HasEncoding()) {
|
||||
JS::Rooted<JSObject*> arrayBuffer(aCx);
|
||||
rv = nsContentUtils::CreateArrayBuffer(aCx, data, arrayBuffer.address());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
aResult.setObject(*arrayBuffer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString encoding;
|
||||
// The BOM sniffing is baked into the "decode" part of the Encoding
|
||||
// Standard, which the File API references.
|
||||
if (!nsContentUtils::CheckForBOM(
|
||||
reinterpret_cast<const unsigned char *>(data.get()),
|
||||
data.Length(),
|
||||
encoding)) {
|
||||
// BOM sniffing failed. Try the API argument.
|
||||
if (!EncodingUtils::FindEncodingForLabel(mFileRequest->GetEncoding(),
|
||||
encoding)) {
|
||||
// API argument failed. Since we are dealing with a file system file,
|
||||
// we don't have a meaningful type attribute for the blob available,
|
||||
// so proceeding to the next step, which is defaulting to UTF-8.
|
||||
encoding.AssignLiteral("UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
nsString tmpString;
|
||||
rv = nsContentUtils::ConvertStringFromEncoding(encoding, data, tmpString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!xpc::StringToJsval(aCx, tmpString, aResult))) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetResult(JSContext* aCx,
|
||||
const FileRequestMetadata* aMetadata,
|
||||
JS::MutableHandle<JS::Value> aResult)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
|
||||
if (NS_WARN_IF(!obj)) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
const FileRequestSize& size = aMetadata->size();
|
||||
if (size.type() != FileRequestSize::Tvoid_t) {
|
||||
MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t);
|
||||
|
||||
JS::Rooted<JS::Value> number(aCx, JS_NumberValue(size.get_uint64_t()));
|
||||
|
||||
if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "size", number, 0))) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
const FileRequestLastModified& lastModified = aMetadata->lastModified();
|
||||
if (lastModified.type() != FileRequestLastModified::Tvoid_t) {
|
||||
MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t);
|
||||
|
||||
JS::Rooted<JSObject*> date(aCx,
|
||||
JS::NewDateObject(aCx, JS::TimeClip(lastModified.get_int64_t())));
|
||||
if (NS_WARN_IF(!date)) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "lastModified", date, 0))) {
|
||||
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
aResult.setObject(*obj);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<File>
|
||||
ConvertActorToFile(FileHandleBase* aFileHandle,
|
||||
const FileRequestGetFileResponse& aResponse)
|
||||
{
|
||||
auto* actor = static_cast<PendingIPCBlobChild*>(aResponse.fileChild());
|
||||
|
||||
MutableFileBase* mutableFile = aFileHandle->MutableFile();
|
||||
MOZ_ASSERT(mutableFile);
|
||||
|
||||
const FileRequestMetadata& metadata = aResponse.metadata();
|
||||
|
||||
const FileRequestSize& size = metadata.size();
|
||||
MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t);
|
||||
|
||||
const FileRequestLastModified& lastModified = metadata.lastModified();
|
||||
MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t);
|
||||
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
actor->SetPendingInfoAndDeleteActor(mutableFile->Name(),
|
||||
mutableFile->Type(),
|
||||
size.get_uint64_t(),
|
||||
lastModified.get_int64_t());
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<File> file = mutableFile->CreateFileFor(blobImpl, aFileHandle);
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
void
|
||||
HandleSuccess(ResultHelper* aResultHelper)
|
||||
{
|
||||
MOZ_ASSERT(aResultHelper);
|
||||
|
||||
RefPtr<FileRequestBase> fileRequest = aResultHelper->FileRequest();
|
||||
MOZ_ASSERT(fileRequest);
|
||||
fileRequest->AssertIsOnOwningThread();
|
||||
|
||||
RefPtr<FileHandleBase> fileHandle = aResultHelper->FileHandle();
|
||||
MOZ_ASSERT(fileHandle);
|
||||
|
||||
if (fileHandle->IsAborted()) {
|
||||
fileRequest->SetError(NS_ERROR_DOM_FILEHANDLE_ABORT_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(fileHandle->IsOpen());
|
||||
|
||||
fileRequest->SetResultCallback(aResultHelper);
|
||||
|
||||
MOZ_ASSERT(fileHandle->IsOpen() || fileHandle->IsAborted());
|
||||
}
|
||||
|
||||
void
|
||||
HandleError(FileRequestBase* aFileRequest,
|
||||
nsresult aErrorCode,
|
||||
FileHandleBase* aFileHandle)
|
||||
{
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
aFileRequest->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_FAILED(aErrorCode));
|
||||
MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_FILEHANDLE);
|
||||
MOZ_ASSERT(aFileHandle);
|
||||
|
||||
RefPtr<FileRequestBase> fileRequest = aFileRequest;
|
||||
RefPtr<FileHandleBase> fileHandle = aFileHandle;
|
||||
|
||||
AutoSetCurrentFileHandle ascfh(aFileHandle);
|
||||
|
||||
fileRequest->SetError(aErrorCode);
|
||||
|
||||
MOZ_ASSERT(fileHandle->IsOpen() || fileHandle->IsAborted());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/*******************************************************************************
|
||||
* BackgroundMutableFileChildBase
|
||||
******************************************************************************/
|
||||
|
||||
BackgroundMutableFileChildBase::BackgroundMutableFileChildBase(
|
||||
DEBUGONLY(PRThread* aOwningThread))
|
||||
: ThreadObject(DEBUGONLY(aOwningThread))
|
||||
, mMutableFile(nullptr)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
MOZ_COUNT_CTOR(BackgroundMutableFileChildBase);
|
||||
}
|
||||
|
||||
BackgroundMutableFileChildBase::~BackgroundMutableFileChildBase()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
MOZ_COUNT_DTOR(BackgroundMutableFileChildBase);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundMutableFileChildBase::EnsureDOMObject()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mTemporaryStrongMutableFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTemporaryStrongMutableFile = CreateMutableFile();
|
||||
|
||||
MOZ_ASSERT(mTemporaryStrongMutableFile);
|
||||
mTemporaryStrongMutableFile->AssertIsOnOwningThread();
|
||||
|
||||
mMutableFile = mTemporaryStrongMutableFile;
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundMutableFileChildBase::ReleaseDOMObject()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mTemporaryStrongMutableFile);
|
||||
mTemporaryStrongMutableFile->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mMutableFile == mTemporaryStrongMutableFile);
|
||||
|
||||
mTemporaryStrongMutableFile = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundMutableFileChildBase::SendDeleteMeInternal()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mTemporaryStrongMutableFile);
|
||||
|
||||
if (mMutableFile) {
|
||||
mMutableFile->ClearBackgroundActor();
|
||||
mMutableFile = nullptr;
|
||||
|
||||
MOZ_ALWAYS_TRUE(PBackgroundMutableFileChild::SendDeleteMe());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundMutableFileChildBase::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mMutableFile) {
|
||||
mMutableFile->ClearBackgroundActor();
|
||||
DEBUGONLY(mMutableFile = nullptr;)
|
||||
}
|
||||
}
|
||||
|
||||
PBackgroundFileHandleChild*
|
||||
BackgroundMutableFileChildBase::AllocPBackgroundFileHandleChild(
|
||||
const FileMode& aMode)
|
||||
{
|
||||
MOZ_CRASH("PBackgroundFileHandleChild actors should be manually "
|
||||
"constructed!");
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundMutableFileChildBase::DeallocPBackgroundFileHandleChild(
|
||||
PBackgroundFileHandleChild* aActor)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
delete static_cast<BackgroundFileHandleChild*>(aActor);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* BackgroundFileHandleChild
|
||||
******************************************************************************/
|
||||
|
||||
BackgroundFileHandleChild::BackgroundFileHandleChild(
|
||||
DEBUGONLY(PRThread* aOwningThread,)
|
||||
FileHandleBase* aFileHandle)
|
||||
: ThreadObject(DEBUGONLY(aOwningThread))
|
||||
, mTemporaryStrongFileHandle(aFileHandle)
|
||||
, mFileHandle(aFileHandle)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFileHandle);
|
||||
aFileHandle->AssertIsOnOwningThread();
|
||||
|
||||
MOZ_COUNT_CTOR(BackgroundFileHandleChild);
|
||||
}
|
||||
|
||||
BackgroundFileHandleChild::~BackgroundFileHandleChild()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
MOZ_COUNT_DTOR(BackgroundFileHandleChild);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileHandleChild::SendDeleteMeInternal()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mFileHandle) {
|
||||
NoteActorDestroyed();
|
||||
|
||||
MOZ_ALWAYS_TRUE(PBackgroundFileHandleChild::SendDeleteMe());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileHandleChild::NoteActorDestroyed()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT_IF(mTemporaryStrongFileHandle, mFileHandle);
|
||||
|
||||
if (mFileHandle) {
|
||||
mFileHandle->ClearBackgroundActor();
|
||||
|
||||
// Normally this would be DEBUG-only but NoteActorDestroyed is also called
|
||||
// from SendDeleteMeInternal. In that case we're going to receive an actual
|
||||
// ActorDestroy call later and we don't want to touch a dead object.
|
||||
mTemporaryStrongFileHandle = nullptr;
|
||||
mFileHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileHandleChild::NoteComplete()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT_IF(mFileHandle, mTemporaryStrongFileHandle);
|
||||
|
||||
mTemporaryStrongFileHandle = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileHandleChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
NoteActorDestroyed();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
BackgroundFileHandleChild::RecvComplete(const bool& aAborted)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFileHandle);
|
||||
|
||||
mFileHandle->HandleCompleteOrAbort(aAborted);
|
||||
|
||||
NoteComplete();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
PBackgroundFileRequestChild*
|
||||
BackgroundFileHandleChild::AllocPBackgroundFileRequestChild(
|
||||
const FileRequestParams& aParams)
|
||||
{
|
||||
MOZ_CRASH("PBackgroundFileRequestChild actors should be manually "
|
||||
"constructed!");
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundFileHandleChild::DeallocPBackgroundFileRequestChild(
|
||||
PBackgroundFileRequestChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
delete static_cast<BackgroundFileRequestChild*>(aActor);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* BackgroundFileRequestChild
|
||||
******************************************************************************/
|
||||
|
||||
BackgroundFileRequestChild::BackgroundFileRequestChild(
|
||||
DEBUGONLY(PRThread* aOwningThread,)
|
||||
FileRequestBase* aFileRequest)
|
||||
: ThreadObject(DEBUGONLY(aOwningThread))
|
||||
, mFileRequest(aFileRequest)
|
||||
, mFileHandle(aFileRequest->FileHandle())
|
||||
, mActorDestroyed(false)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
aFileRequest->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFileHandle);
|
||||
mFileHandle->AssertIsOnOwningThread();
|
||||
|
||||
MOZ_COUNT_CTOR(BackgroundFileRequestChild);
|
||||
}
|
||||
|
||||
BackgroundFileRequestChild::~BackgroundFileRequestChild()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mFileHandle);
|
||||
|
||||
MOZ_COUNT_DTOR(BackgroundFileRequestChild);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileRequestChild::HandleResponse(nsresult aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_FAILED(aResponse));
|
||||
MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_FILEHANDLE);
|
||||
MOZ_ASSERT(mFileHandle);
|
||||
|
||||
HandleError(mFileRequest, aResponse, mFileHandle);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileRequestChild::HandleResponse(
|
||||
const FileRequestGetFileResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
RefPtr<File> file = ConvertActorToFile(mFileHandle, aResponse);
|
||||
|
||||
ResultHelper helper(mFileRequest, mFileHandle, file);
|
||||
|
||||
HandleSuccess(&helper);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileRequestChild::HandleResponse(const nsCString& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
ResultHelper helper(mFileRequest, mFileHandle, &aResponse);
|
||||
|
||||
HandleSuccess(&helper);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileRequestChild::HandleResponse(const FileRequestMetadata& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
ResultHelper helper(mFileRequest, mFileHandle, &aResponse);
|
||||
|
||||
HandleSuccess(&helper);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileRequestChild::HandleResponse(JS::Handle<JS::Value> aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
ResultHelper helper(mFileRequest, mFileHandle, &aResponse);
|
||||
|
||||
HandleSuccess(&helper);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundFileRequestChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
mActorDestroyed = true;
|
||||
|
||||
if (mFileHandle) {
|
||||
mFileHandle->AssertIsOnOwningThread();
|
||||
|
||||
mFileHandle->OnRequestFinished(/* aActorDestroyedNormally */
|
||||
aWhy == Deletion);
|
||||
|
||||
DEBUGONLY(mFileHandle = nullptr;)
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
BackgroundFileRequestChild::Recv__delete__(const FileRequestResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFileRequest);
|
||||
MOZ_ASSERT(mFileHandle);
|
||||
|
||||
if (mFileHandle->IsAborted()) {
|
||||
// Always handle an "error" with ABORT_ERR if the file handle was aborted,
|
||||
// even if the request succeeded or failed with another error.
|
||||
HandleResponse(NS_ERROR_DOM_FILEHANDLE_ABORT_ERR);
|
||||
} else {
|
||||
switch (aResponse.type()) {
|
||||
case FileRequestResponse::Tnsresult:
|
||||
HandleResponse(aResponse.get_nsresult());
|
||||
break;
|
||||
|
||||
case FileRequestResponse::TFileRequestGetFileResponse:
|
||||
HandleResponse(aResponse.get_FileRequestGetFileResponse());
|
||||
break;
|
||||
|
||||
case FileRequestResponse::TFileRequestReadResponse:
|
||||
HandleResponse(aResponse.get_FileRequestReadResponse().data());
|
||||
break;
|
||||
|
||||
case FileRequestResponse::TFileRequestWriteResponse:
|
||||
HandleResponse(JS::UndefinedHandleValue);
|
||||
break;
|
||||
|
||||
case FileRequestResponse::TFileRequestTruncateResponse:
|
||||
HandleResponse(JS::UndefinedHandleValue);
|
||||
break;
|
||||
|
||||
case FileRequestResponse::TFileRequestFlushResponse:
|
||||
HandleResponse(JS::UndefinedHandleValue);
|
||||
break;
|
||||
|
||||
case FileRequestResponse::TFileRequestGetMetadataResponse:
|
||||
HandleResponse(aResponse.get_FileRequestGetMetadataResponse()
|
||||
.metadata());
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown response type!");
|
||||
}
|
||||
}
|
||||
|
||||
mFileHandle->OnRequestFinished(/* aActorDestroyedNormally */ true);
|
||||
|
||||
// Null this out so that we don't try to call OnRequestFinished() again in
|
||||
// ActorDestroy.
|
||||
mFileHandle = nullptr;
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
BackgroundFileRequestChild::RecvProgress(const uint64_t& aProgress,
|
||||
const uint64_t& aProgressMax)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFileRequest);
|
||||
|
||||
mFileRequest->OnProgress(aProgress, aProgressMax);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -1,174 +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/. */
|
||||
|
||||
#ifndef mozilla_dom_filehandle_ActorsChild_h
|
||||
#define mozilla_dom_filehandle_ActorsChild_h
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/FileHandleCommon.h"
|
||||
#include "mozilla/dom/PBackgroundFileHandleChild.h"
|
||||
#include "mozilla/dom/PBackgroundFileRequestChild.h"
|
||||
#include "mozilla/dom/PBackgroundMutableFileChild.h"
|
||||
|
||||
class nsCString;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class FileHandleBase;
|
||||
class FileRequestBase;
|
||||
class MutableFileBase;
|
||||
|
||||
class BackgroundMutableFileChildBase
|
||||
: public ThreadObject
|
||||
, public PBackgroundMutableFileChild
|
||||
{
|
||||
protected:
|
||||
friend class MutableFileBase;
|
||||
|
||||
RefPtr<MutableFileBase> mTemporaryStrongMutableFile;
|
||||
MutableFileBase* mMutableFile;
|
||||
|
||||
public:
|
||||
void
|
||||
EnsureDOMObject();
|
||||
|
||||
MutableFileBase*
|
||||
GetDOMObject() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
return mMutableFile;
|
||||
}
|
||||
|
||||
void
|
||||
ReleaseDOMObject();
|
||||
|
||||
protected:
|
||||
BackgroundMutableFileChildBase(DEBUGONLY(PRThread* aOwningThread));
|
||||
|
||||
~BackgroundMutableFileChildBase();
|
||||
|
||||
void
|
||||
SendDeleteMeInternal();
|
||||
|
||||
virtual already_AddRefed<MutableFileBase>
|
||||
CreateMutableFile() = 0;
|
||||
|
||||
// IPDL methods are only called by IPDL.
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual PBackgroundFileHandleChild*
|
||||
AllocPBackgroundFileHandleChild(const FileMode& aMode) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPBackgroundFileHandleChild(PBackgroundFileHandleChild* aActor)
|
||||
override;
|
||||
|
||||
bool
|
||||
SendDeleteMe() = delete;
|
||||
};
|
||||
|
||||
class BackgroundFileHandleChild
|
||||
: public ThreadObject
|
||||
, public PBackgroundFileHandleChild
|
||||
{
|
||||
friend class BackgroundMutableFileChildBase;
|
||||
friend class MutableFileBase;
|
||||
|
||||
// mTemporaryStrongFileHandle is strong and is only valid until the end of
|
||||
// NoteComplete() member function or until the NoteActorDestroyed() member
|
||||
// function is called.
|
||||
RefPtr<FileHandleBase> mTemporaryStrongFileHandle;
|
||||
|
||||
// mFileHandle is weak and is valid until the NoteActorDestroyed() member
|
||||
// function is called.
|
||||
FileHandleBase* mFileHandle;
|
||||
|
||||
public:
|
||||
explicit BackgroundFileHandleChild(DEBUGONLY(PRThread* aOwningThread,)
|
||||
FileHandleBase* aFileHandle);
|
||||
|
||||
void
|
||||
SendDeleteMeInternal();
|
||||
|
||||
private:
|
||||
~BackgroundFileHandleChild();
|
||||
|
||||
void
|
||||
NoteActorDestroyed();
|
||||
|
||||
void
|
||||
NoteComplete();
|
||||
|
||||
// IPDL methods are only called by IPDL.
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvComplete(const bool& aAborted) override;
|
||||
|
||||
virtual PBackgroundFileRequestChild*
|
||||
AllocPBackgroundFileRequestChild(const FileRequestParams& aParams)
|
||||
override;
|
||||
|
||||
virtual bool
|
||||
DeallocPBackgroundFileRequestChild(PBackgroundFileRequestChild* aActor)
|
||||
override;
|
||||
|
||||
bool
|
||||
SendDeleteMe() = delete;
|
||||
};
|
||||
|
||||
class BackgroundFileRequestChild final
|
||||
: public ThreadObject
|
||||
, public PBackgroundFileRequestChild
|
||||
{
|
||||
friend class BackgroundFileHandleChild;
|
||||
friend class FileHandleBase;
|
||||
|
||||
RefPtr<FileRequestBase> mFileRequest;
|
||||
RefPtr<FileHandleBase> mFileHandle;
|
||||
bool mActorDestroyed;
|
||||
|
||||
private:
|
||||
// Only created by FileHandleBase.
|
||||
explicit BackgroundFileRequestChild(DEBUGONLY(PRThread* aOwningThread,)
|
||||
FileRequestBase* aFileRequest);
|
||||
|
||||
// Only destroyed by BackgroundFileHandleChild.
|
||||
~BackgroundFileRequestChild();
|
||||
|
||||
void
|
||||
HandleResponse(nsresult aResponse);
|
||||
|
||||
void
|
||||
HandleResponse(const FileRequestGetFileResponse& aResponse);
|
||||
|
||||
void
|
||||
HandleResponse(const nsCString& aResponse);
|
||||
|
||||
void
|
||||
HandleResponse(const FileRequestMetadata& aResponse);
|
||||
|
||||
void
|
||||
HandleResponse(JS::Handle<JS::Value> aResponse);
|
||||
|
||||
// IPDL methods are only called by IPDL.
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
Recv__delete__(const FileRequestResponse& aResponse) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvProgress(const uint64_t& aProgress,
|
||||
const uint64_t& aProgressMax) override;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_filehandle_ActorsChild_h
|
|
@ -1,638 +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 "FileHandleBase.h"
|
||||
|
||||
#include "ActorsChild.h"
|
||||
#include "BackgroundChildImpl.h"
|
||||
#include "FileRequestBase.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/PBackgroundFileHandle.h"
|
||||
#include "mozilla/dom/UnionConversions.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "MutableFileBase.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
FileHandleBase::FileHandleBase(DEBUGONLY(PRThread* aOwningThread,)
|
||||
FileMode aMode)
|
||||
: RefCountedThreadObject(DEBUGONLY(aOwningThread))
|
||||
, mBackgroundActor(nullptr)
|
||||
, mLocation(0)
|
||||
, mPendingRequestCount(0)
|
||||
, mReadyState(INITIAL)
|
||||
, mMode(aMode)
|
||||
, mAborted(false)
|
||||
, mCreating(false)
|
||||
DEBUGONLY(, mSentFinishOrAbort(false))
|
||||
DEBUGONLY(, mFiredCompleteOrAbort(false))
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
FileHandleBase::~FileHandleBase()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mPendingRequestCount);
|
||||
MOZ_ASSERT(!mCreating);
|
||||
MOZ_ASSERT(mSentFinishOrAbort);
|
||||
MOZ_ASSERT_IF(mBackgroundActor, mFiredCompleteOrAbort);
|
||||
|
||||
if (mBackgroundActor) {
|
||||
mBackgroundActor->SendDeleteMeInternal();
|
||||
|
||||
MOZ_ASSERT(!mBackgroundActor, "SendDeleteMeInternal should have cleared!");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
FileHandleBase*
|
||||
FileHandleBase::GetCurrent()
|
||||
{
|
||||
MOZ_ASSERT(BackgroundChild::GetForCurrentThread());
|
||||
|
||||
BackgroundChildImpl::ThreadLocal* threadLocal =
|
||||
BackgroundChildImpl::GetThreadLocalForCurrentThread();
|
||||
MOZ_ASSERT(threadLocal);
|
||||
|
||||
return threadLocal->mCurrentFileHandle;
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::SetBackgroundActor(BackgroundFileHandleChild* aActor)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(!mBackgroundActor);
|
||||
|
||||
mBackgroundActor = aActor;
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::StartRequest(FileRequestBase* aFileRequest,
|
||||
const FileRequestParams& aParams)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFileRequest);
|
||||
MOZ_ASSERT(aParams.type() != FileRequestParams::T__None);
|
||||
|
||||
BackgroundFileRequestChild* actor =
|
||||
new BackgroundFileRequestChild(DEBUGONLY(mBackgroundActor->OwningThread(),)
|
||||
aFileRequest);
|
||||
|
||||
mBackgroundActor->SendPBackgroundFileRequestConstructor(actor, aParams);
|
||||
|
||||
// Balanced in BackgroundFileRequestChild::Recv__delete__().
|
||||
OnNewRequest();
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::OnNewRequest()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (!mPendingRequestCount) {
|
||||
MOZ_ASSERT(mReadyState == INITIAL);
|
||||
mReadyState = LOADING;
|
||||
}
|
||||
|
||||
++mPendingRequestCount;
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::OnRequestFinished(bool aActorDestroyedNormally)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mPendingRequestCount);
|
||||
|
||||
--mPendingRequestCount;
|
||||
|
||||
if (!mPendingRequestCount && !MutableFile()->IsInvalidated()) {
|
||||
mReadyState = FINISHING;
|
||||
|
||||
if (aActorDestroyedNormally) {
|
||||
if (!mAborted) {
|
||||
SendFinish();
|
||||
} else {
|
||||
SendAbort();
|
||||
}
|
||||
} else {
|
||||
// Don't try to send any more messages to the parent if the request actor
|
||||
// was killed.
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!mSentFinishOrAbort);
|
||||
mSentFinishOrAbort = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FileHandleBase::IsOpen() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// If we haven't started anything then we're open.
|
||||
if (mReadyState == INITIAL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we've already started then we need to check to see if we still have the
|
||||
// mCreating flag set. If we do (i.e. we haven't returned to the event loop
|
||||
// from the time we were created) then we are open. Otherwise check the
|
||||
// currently running file handles to see if it's the same. We only allow other
|
||||
// requests to be made if this file handle is currently running.
|
||||
if (mReadyState == LOADING && (mCreating || GetCurrent() == this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::Abort()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (IsFinishingOrDone()) {
|
||||
// Already started (and maybe finished) the finish or abort so there is
|
||||
// nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isInvalidated = MutableFile()->IsInvalidated();
|
||||
bool needToSendAbort = mReadyState == INITIAL && !isInvalidated;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (isInvalidated) {
|
||||
mSentFinishOrAbort = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
mAborted = true;
|
||||
mReadyState = DONE;
|
||||
|
||||
// Fire the abort event if there are no outstanding requests. Otherwise the
|
||||
// abort event will be fired when all outstanding requests finish.
|
||||
if (needToSendAbort) {
|
||||
SendAbort();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::Read(uint64_t aSize, bool aHasEncoding,
|
||||
const nsAString& aEncoding, ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State and argument checking for read
|
||||
if (!CheckStateAndArgumentsForRead(aSize, aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileRequestReadParams params;
|
||||
params.offset() = mLocation;
|
||||
params.size() = aSize;
|
||||
|
||||
RefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
|
||||
if (aHasEncoding) {
|
||||
fileRequest->SetEncoding(aEncoding);
|
||||
}
|
||||
|
||||
StartRequest(fileRequest, params);
|
||||
|
||||
mLocation += aSize;
|
||||
|
||||
return fileRequest.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State checking for write
|
||||
if (!CheckStateForWrite(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Getting location and additional state checking for truncate
|
||||
uint64_t location;
|
||||
if (aSize.WasPassed()) {
|
||||
// Just in case someone calls us from C++
|
||||
MOZ_ASSERT(aSize.Value() != UINT64_MAX, "Passed wrong size!");
|
||||
location = aSize.Value();
|
||||
} else {
|
||||
if (mLocation == UINT64_MAX) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
location = mLocation;
|
||||
}
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileRequestTruncateParams params;
|
||||
params.offset() = location;
|
||||
|
||||
RefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
|
||||
|
||||
StartRequest(fileRequest, params);
|
||||
|
||||
if (aSize.WasPassed()) {
|
||||
mLocation = aSize.Value();
|
||||
}
|
||||
|
||||
return fileRequest.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::Flush(ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State checking for write
|
||||
if (!CheckStateForWrite(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileRequestFlushParams params;
|
||||
|
||||
RefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
|
||||
|
||||
StartRequest(fileRequest, params);
|
||||
|
||||
return fileRequest.forget();
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::Abort(ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// This method is special enough for not using generic state checking methods.
|
||||
|
||||
if (IsFinishingOrDone()) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
Abort();
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::HandleCompleteOrAbort(bool aAborted)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mFiredCompleteOrAbort);
|
||||
|
||||
mReadyState = DONE;
|
||||
|
||||
DEBUGONLY(mFiredCompleteOrAbort = true;)
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::OnReturnToEventLoop()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// We're back at the event loop, no longer newborn.
|
||||
mCreating = false;
|
||||
|
||||
// Maybe finish if there were no requests generated.
|
||||
if (mReadyState == INITIAL) {
|
||||
mReadyState = DONE;
|
||||
|
||||
SendFinish();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FileHandleBase::CheckState(ErrorResult& aRv)
|
||||
{
|
||||
if (!IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_INACTIVE_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FileHandleBase::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv)
|
||||
{
|
||||
// Common state checking
|
||||
if (!CheckState(aRv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Additional state checking for read
|
||||
if (mLocation == UINT64_MAX) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Argument checking for read
|
||||
if (!aSize) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_READ_SIZE>();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FileHandleBase::CheckStateForWrite(ErrorResult& aRv)
|
||||
{
|
||||
// Common state checking
|
||||
if (!CheckState(aRv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Additional state checking for write
|
||||
if (mMode != FileMode::Readwrite) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_READ_ONLY_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FileHandleBase::CheckStateForWriteOrAppend(bool aAppend, ErrorResult& aRv)
|
||||
{
|
||||
// State checking for write
|
||||
if (!CheckStateForWrite(aRv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Additional state checking for write
|
||||
if (!aAppend && mLocation == UINT64_MAX) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::WriteOrAppend(
|
||||
const StringOrArrayBufferOrArrayBufferViewOrBlob& aValue,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (aValue.IsString()) {
|
||||
return WriteOrAppend(aValue.GetAsString(), aAppend, aRv);
|
||||
}
|
||||
|
||||
if (aValue.IsArrayBuffer()) {
|
||||
return WriteOrAppend(aValue.GetAsArrayBuffer(), aAppend, aRv);
|
||||
}
|
||||
|
||||
if (aValue.IsArrayBufferView()) {
|
||||
return WriteOrAppend(aValue.GetAsArrayBufferView(), aAppend, aRv);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aValue.IsBlob());
|
||||
return WriteOrAppend(aValue.GetAsBlob(), aAppend, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::WriteOrAppend(const nsAString& aValue,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State checking for write or append
|
||||
if (!CheckStateForWriteOrAppend(aAppend, aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 cstr(aValue);
|
||||
|
||||
uint64_t dataLength = cstr.Length();;
|
||||
if (!dataLength) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileRequestStringData stringData(cstr);
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return WriteInternal(stringData, dataLength, aAppend, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::WriteOrAppend(const ArrayBuffer& aValue,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State checking for write or append
|
||||
if (!CheckStateForWriteOrAppend(aAppend, aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
aValue.ComputeLengthAndData();
|
||||
|
||||
uint64_t dataLength = aValue.Length();;
|
||||
if (!dataLength) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* data = reinterpret_cast<const char*>(aValue.Data());
|
||||
|
||||
FileRequestStringData stringData;
|
||||
if (NS_WARN_IF(!stringData.string().Assign(data, aValue.Length(),
|
||||
fallible_t()))) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return WriteInternal(stringData, dataLength, aAppend, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::WriteOrAppend(const ArrayBufferView& aValue,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State checking for write or append
|
||||
if (!CheckStateForWriteOrAppend(aAppend, aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
aValue.ComputeLengthAndData();
|
||||
|
||||
uint64_t dataLength = aValue.Length();;
|
||||
if (!dataLength) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* data = reinterpret_cast<const char*>(aValue.Data());
|
||||
|
||||
FileRequestStringData stringData;
|
||||
if (NS_WARN_IF(!stringData.string().Assign(data, aValue.Length(),
|
||||
fallible_t()))) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return WriteInternal(stringData, dataLength, aAppend, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::WriteOrAppend(Blob& aValue,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// State checking for write or append
|
||||
if (!CheckStateForWriteOrAppend(aAppend, aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ErrorResult error;
|
||||
uint64_t dataLength = aValue.GetSize(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!dataLength) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PBackgroundChild* backgroundActor = BackgroundChild::GetForCurrentThread();
|
||||
MOZ_ASSERT(backgroundActor);
|
||||
|
||||
IPCBlob ipcBlob;
|
||||
nsresult rv =
|
||||
IPCBlobUtils::Serialize(aValue.Impl(), backgroundActor, ipcBlob);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileRequestBlobData blobData;
|
||||
blobData.blob() = ipcBlob;
|
||||
|
||||
// Do nothing if the window is closed
|
||||
if (!CheckWindow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return WriteInternal(blobData, dataLength, aAppend, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
FileHandleBase::WriteInternal(const FileRequestData& aData,
|
||||
uint64_t aDataLength,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
DebugOnly<ErrorResult> error;
|
||||
MOZ_ASSERT(CheckStateForWrite(error));
|
||||
MOZ_ASSERT_IF(!aAppend, mLocation != UINT64_MAX);
|
||||
MOZ_ASSERT(aDataLength);
|
||||
MOZ_ASSERT(CheckWindow());
|
||||
|
||||
FileRequestWriteParams params;
|
||||
params.offset() = aAppend ? UINT64_MAX : mLocation;
|
||||
params.data() = aData;
|
||||
params.dataLength() = aDataLength;
|
||||
|
||||
RefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
|
||||
MOZ_ASSERT(fileRequest);
|
||||
|
||||
StartRequest(fileRequest, params);
|
||||
|
||||
if (aAppend) {
|
||||
mLocation = UINT64_MAX;
|
||||
}
|
||||
else {
|
||||
mLocation += aDataLength;
|
||||
}
|
||||
|
||||
return fileRequest.forget();
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::SendFinish()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mAborted);
|
||||
MOZ_ASSERT(IsFinishingOrDone());
|
||||
MOZ_ASSERT(!mSentFinishOrAbort);
|
||||
MOZ_ASSERT(!mPendingRequestCount);
|
||||
|
||||
MOZ_ASSERT(mBackgroundActor);
|
||||
mBackgroundActor->SendFinish();
|
||||
|
||||
DEBUGONLY(mSentFinishOrAbort = true;)
|
||||
}
|
||||
|
||||
void
|
||||
FileHandleBase::SendAbort()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mAborted);
|
||||
MOZ_ASSERT(IsFinishingOrDone());
|
||||
MOZ_ASSERT(!mSentFinishOrAbort);
|
||||
|
||||
MOZ_ASSERT(mBackgroundActor);
|
||||
mBackgroundActor->SendAbort();
|
||||
|
||||
DEBUGONLY(mSentFinishOrAbort = true;)
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -1,246 +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 mozilla_dom_FileHandle_h
|
||||
#define mozilla_dom_FileHandle_h
|
||||
|
||||
#include "FileHandleCommon.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/FileModeBinding.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
|
||||
template <class> struct already_AddRefed;
|
||||
class nsAString;
|
||||
struct PRThread;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class BackgroundFileHandleChild;
|
||||
class Blob;
|
||||
class FileRequestBase;
|
||||
class FileRequestData;
|
||||
class FileRequestParams;
|
||||
class MutableFileBase;
|
||||
class StringOrArrayBufferOrArrayBufferViewOrBlob;
|
||||
|
||||
/**
|
||||
* This class provides a base for FileHandle implementations.
|
||||
*/
|
||||
class FileHandleBase
|
||||
: public RefCountedThreadObject
|
||||
{
|
||||
public:
|
||||
enum ReadyState
|
||||
{
|
||||
INITIAL = 0,
|
||||
LOADING,
|
||||
FINISHING,
|
||||
DONE
|
||||
};
|
||||
|
||||
private:
|
||||
BackgroundFileHandleChild* mBackgroundActor;
|
||||
|
||||
uint64_t mLocation;
|
||||
|
||||
uint32_t mPendingRequestCount;
|
||||
|
||||
ReadyState mReadyState;
|
||||
FileMode mMode;
|
||||
|
||||
bool mAborted;
|
||||
bool mCreating;
|
||||
|
||||
DEBUGONLY(bool mSentFinishOrAbort;)
|
||||
DEBUGONLY(bool mFiredCompleteOrAbort;)
|
||||
|
||||
public:
|
||||
static FileHandleBase*
|
||||
GetCurrent();
|
||||
|
||||
void
|
||||
SetBackgroundActor(BackgroundFileHandleChild* aActor);
|
||||
|
||||
void
|
||||
ClearBackgroundActor()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
mBackgroundActor = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
StartRequest(FileRequestBase* aFileRequest, const FileRequestParams& aParams);
|
||||
|
||||
void
|
||||
OnNewRequest();
|
||||
|
||||
void
|
||||
OnRequestFinished(bool aActorDestroyedNormally);
|
||||
|
||||
bool
|
||||
IsOpen() const;
|
||||
|
||||
bool
|
||||
IsFinishingOrDone() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mReadyState == FINISHING || mReadyState == DONE;
|
||||
}
|
||||
|
||||
bool
|
||||
IsDone() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mReadyState == DONE;
|
||||
}
|
||||
|
||||
bool
|
||||
IsAborted() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
return mAborted;
|
||||
}
|
||||
|
||||
void
|
||||
SetCreating()
|
||||
{
|
||||
mCreating = true;
|
||||
}
|
||||
|
||||
void
|
||||
Abort();
|
||||
|
||||
// Shared WebIDL (IndexedDB FileHandle and FileSystem FileHandle)
|
||||
FileMode
|
||||
Mode() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
return mMode;
|
||||
}
|
||||
|
||||
bool
|
||||
Active() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
return IsOpen();
|
||||
}
|
||||
|
||||
Nullable<uint64_t>
|
||||
GetLocation() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mLocation == UINT64_MAX) {
|
||||
return Nullable<uint64_t>();
|
||||
}
|
||||
|
||||
return Nullable<uint64_t>(mLocation);
|
||||
}
|
||||
|
||||
void
|
||||
SetLocation(const Nullable<uint64_t>& aLocation)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// Null means the end-of-file.
|
||||
if (aLocation.IsNull()) {
|
||||
mLocation = UINT64_MAX;
|
||||
} else {
|
||||
mLocation = aLocation.Value();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
Read(uint64_t aSize, bool aHasEncoding, const nsAString& aEncoding,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
Flush(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
Abort(ErrorResult& aRv);
|
||||
|
||||
// Must be overridden in subclasses.
|
||||
virtual MutableFileBase*
|
||||
MutableFile() const = 0;
|
||||
|
||||
// May be overridden in subclasses.
|
||||
virtual void
|
||||
HandleCompleteOrAbort(bool aAborted);
|
||||
|
||||
protected:
|
||||
FileHandleBase(DEBUGONLY(PRThread* aOwningThread,)
|
||||
FileMode aMode);
|
||||
|
||||
~FileHandleBase();
|
||||
|
||||
void
|
||||
OnReturnToEventLoop();
|
||||
|
||||
bool
|
||||
CheckState(ErrorResult& aRv);
|
||||
|
||||
bool
|
||||
CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv);
|
||||
|
||||
bool
|
||||
CheckStateForWrite(ErrorResult& aRv);
|
||||
|
||||
bool
|
||||
CheckStateForWriteOrAppend(bool aAppend, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
WriteOrAppend(const StringOrArrayBufferOrArrayBufferViewOrBlob& aValue,
|
||||
bool aAppend,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// Must be overridden in subclasses.
|
||||
virtual bool
|
||||
CheckWindow() = 0;
|
||||
|
||||
// Must be overridden in subclasses.
|
||||
virtual already_AddRefed<FileRequestBase>
|
||||
GenerateFileRequest() = 0;
|
||||
|
||||
private:
|
||||
already_AddRefed<FileRequestBase>
|
||||
WriteOrAppend(const nsAString& aValue, bool aAppend, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
WriteOrAppend(const ArrayBuffer& aValue, bool aAppend, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
WriteOrAppend(const ArrayBufferView& aValue, bool aAppend, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
WriteOrAppend(Blob& aValue, bool aAppend, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileRequestBase>
|
||||
WriteInternal(const FileRequestData& aData, uint64_t aDataLength,
|
||||
bool aAppend, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
SendFinish();
|
||||
|
||||
void
|
||||
SendAbort();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FileHandle_h
|
|
@ -1,93 +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 mozilla_dom_FileRequest_h
|
||||
#define mozilla_dom_FileRequest_h
|
||||
|
||||
#include "FileHandleCommon.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "nsString.h"
|
||||
|
||||
struct PRThread;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class FileHandleBase;
|
||||
|
||||
/**
|
||||
* This class provides a base for FileRequest implementations.
|
||||
*/
|
||||
class FileRequestBase
|
||||
: public RefCountedThreadObject
|
||||
{
|
||||
nsString mEncoding;
|
||||
|
||||
bool mHasEncoding;
|
||||
|
||||
public:
|
||||
class ResultCallback;
|
||||
|
||||
void
|
||||
SetEncoding(const nsAString& aEncoding)
|
||||
{
|
||||
mEncoding = aEncoding;
|
||||
mHasEncoding = true;
|
||||
}
|
||||
|
||||
const nsAString&
|
||||
GetEncoding() const
|
||||
{
|
||||
return mEncoding;
|
||||
}
|
||||
|
||||
bool
|
||||
HasEncoding() const
|
||||
{
|
||||
return mHasEncoding;
|
||||
}
|
||||
|
||||
virtual FileHandleBase*
|
||||
FileHandle() const = 0;
|
||||
|
||||
virtual void
|
||||
OnProgress(uint64_t aProgress, uint64_t aProgressMax) = 0;
|
||||
|
||||
virtual void
|
||||
SetResultCallback(ResultCallback* aCallback) = 0;
|
||||
|
||||
virtual void
|
||||
SetError(nsresult aError) = 0;
|
||||
|
||||
protected:
|
||||
FileRequestBase(DEBUGONLY(PRThread* aOwningThread))
|
||||
: RefCountedThreadObject(DEBUGONLY(aOwningThread))
|
||||
, mHasEncoding(false)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
virtual ~FileRequestBase()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
}
|
||||
};
|
||||
|
||||
class NS_NO_VTABLE FileRequestBase::ResultCallback
|
||||
{
|
||||
public:
|
||||
virtual nsresult
|
||||
GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) = 0;
|
||||
|
||||
protected:
|
||||
ResultCallback()
|
||||
{ }
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_FileRequest_h
|
|
@ -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/. */
|
||||
|
||||
#include "MutableFileBase.h"
|
||||
|
||||
#include "ActorsChild.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "prthread.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
MutableFileBase::MutableFileBase(DEBUGONLY(PRThread* aOwningThread,)
|
||||
BackgroundMutableFileChildBase* aActor)
|
||||
: RefCountedThreadObject(DEBUGONLY(aOwningThread))
|
||||
, mBackgroundActor(aActor)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
}
|
||||
|
||||
MutableFileBase::~MutableFileBase()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mBackgroundActor) {
|
||||
mBackgroundActor->SendDeleteMeInternal();
|
||||
MOZ_ASSERT(!mBackgroundActor, "SendDeleteMeInternal should have cleared!");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -1,76 +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 mozilla_dom_MutableFile_h
|
||||
#define mozilla_dom_MutableFile_h
|
||||
|
||||
#include "mozilla/dom/FileHandleCommon.h"
|
||||
#include "nscore.h"
|
||||
|
||||
template <class> struct already_AddRefed;
|
||||
class nsISupports;
|
||||
class nsString;
|
||||
struct PRThread;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class BackgroundMutableFileChildBase;
|
||||
class BlobImpl;
|
||||
class File;
|
||||
class FileHandleBase;
|
||||
|
||||
/**
|
||||
* This class provides a base for MutableFile implementations.
|
||||
* (for example IDBMutableFile provides IndexedDB specific implementation).
|
||||
*/
|
||||
class MutableFileBase
|
||||
: public RefCountedThreadObject
|
||||
{
|
||||
protected:
|
||||
BackgroundMutableFileChildBase* mBackgroundActor;
|
||||
|
||||
public:
|
||||
BackgroundMutableFileChildBase*
|
||||
GetBackgroundActor() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mBackgroundActor;
|
||||
}
|
||||
|
||||
void
|
||||
ClearBackgroundActor()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
mBackgroundActor = nullptr;
|
||||
}
|
||||
|
||||
virtual const nsString&
|
||||
Name() const = 0;
|
||||
|
||||
virtual const nsString&
|
||||
Type() const = 0;
|
||||
|
||||
virtual bool
|
||||
IsInvalidated() = 0;
|
||||
|
||||
virtual already_AddRefed<File>
|
||||
CreateFileFor(BlobImpl* aBlobImpl,
|
||||
FileHandleBase* aFileHandle) = 0;
|
||||
|
||||
protected:
|
||||
MutableFileBase(DEBUGONLY(PRThread* aOwningThread,)
|
||||
BackgroundMutableFileChildBase* aActor);
|
||||
|
||||
virtual ~MutableFileBase();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_MutableFile_h
|
Загрузка…
Ссылка в новой задаче