Bug 1029209 - Extract IndexedDB FileHandle from core FileHandle implementation (WebIDL changes: merge MutableFile into IDBMutableFile, rename FileHandle to IDBFileHandle, DOMFileMetadataParameters to IDBFileMetadataParameters and FileRequest to IDBFileRequest); r=bent

--HG--
rename : dom/filehandle/File.cpp => dom/indexedDB/FileSnapshot.cpp
rename : dom/filehandle/File.h => dom/indexedDB/FileSnapshot.h
rename : dom/filehandle/test/dummy_worker.js => dom/indexedDB/test/dummy_worker.js
rename : dom/filehandle/test/test_append_read_data.html => dom/indexedDB/test/test_filehandle_append_read_data.html
rename : dom/filehandle/test/test_compat.html => dom/indexedDB/test/test_filehandle_compat.html
rename : dom/filehandle/test/test_getFile.html => dom/indexedDB/test/test_filehandle_getFile.html
rename : dom/filehandle/test/test_filehandle_lifetimes.html => dom/indexedDB/test/test_filehandle_lifetimes.html
rename : dom/filehandle/test/test_filehandle_lifetimes_nested.html => dom/indexedDB/test/test_filehandle_lifetimes_nested.html
rename : dom/filehandle/test/test_location.html => dom/indexedDB/test/test_filehandle_location.html
rename : dom/filehandle/test/test_filehandle_ordering.html => dom/indexedDB/test/test_filehandle_ordering.html
rename : dom/filehandle/test/test_overlapping_filehandles.html => dom/indexedDB/test/test_filehandle_overlapping.html
rename : dom/filehandle/test/test_progress_events.html => dom/indexedDB/test/test_filehandle_progress_events.html
rename : dom/filehandle/test/test_readonly_filehandles.html => dom/indexedDB/test/test_filehandle_readonly_exceptions.html
rename : dom/filehandle/test/test_request_readyState.html => dom/indexedDB/test/test_filehandle_request_readyState.html
rename : dom/filehandle/test/test_stream_tracking.html => dom/indexedDB/test/test_filehandle_stream_tracking.html
rename : dom/filehandle/test/test_success_events_after_abort.html => dom/indexedDB/test/test_filehandle_success_events_after_abort.html
rename : dom/filehandle/test/test_truncate.html => dom/indexedDB/test/test_filehandle_truncate.html
rename : dom/filehandle/test/test_workers.html => dom/indexedDB/test/test_filehandle_workers.html
rename : dom/filehandle/test/test_write_read_data.html => dom/indexedDB/test/test_filehandle_write_read_data.html
rename : dom/filehandle/test/test_getFileId.html => dom/indexedDB/test/test_getFileId.html
rename : dom/webidl/FileHandle.webidl => dom/webidl/IDBFileHandle.webidl
rename : dom/webidl/FileRequest.webidl => dom/webidl/IDBFileRequest.webidl
This commit is contained in:
Jan Varga 2014-07-17 12:40:54 -04:00
parent 54f17f2e41
commit 8f28eb1deb
71 changed files with 2589 additions and 2501 deletions

View File

@ -68,9 +68,9 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/IDBFactoryBinding.h"
#include "mozilla/dom/IDBMutableFileBinding.h"
#include "mozilla/dom/indexedDB/IDBMutableFile.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/MutableFile.h"
#include "mozilla/dom/MutableFileBinding.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/dom/quota/QuotaManager.h"
@ -3030,8 +3030,8 @@ nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
if (!aFile.isPrimitive()) {
JSObject* obj = aFile.toObjectOrNull();
MutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(MutableFile, obj, mutableFile))) {
indexedDB::IDBMutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
*aResult = mutableFile->GetFileId();
return NS_OK;
}

View File

@ -446,10 +446,6 @@ DOMInterfaces = {
},
},
'FileHandle': {
'nativeType': 'mozilla::dom::FileHandle',
},
'FileList': {
'nativeType': 'nsDOMFileList',
'headerFile': 'nsDOMFile.h',
@ -466,10 +462,6 @@ DOMInterfaces = {
'wrapperCache': False,
},
'FileRequest': {
'nativeType': 'mozilla::dom::FileRequest',
},
'FormData': [
{
'nativeType': 'nsFormData'
@ -656,6 +648,14 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::indexedDB::IDBFactory',
},
'IDBFileHandle': {
'nativeType': 'mozilla::dom::indexedDB::IDBFileHandle',
},
'IDBFileRequest': {
'nativeType': 'mozilla::dom::indexedDB::IDBFileRequest',
},
'IDBIndex': {
'nativeType': 'mozilla::dom::indexedDB::IDBIndex',
'binaryNames': {
@ -889,10 +889,6 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::Voicemail',
},
'MutableFile': {
'nativeType': 'mozilla::dom::MutableFile'
},
'MutationObserver': {
'nativeType': 'nsDOMMutationObserver',
},

View File

@ -1,119 +0,0 @@
/* -*- 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 "File.h"
#include "FileHandle.h"
#include "mozilla/Assertions.h"
#include "nsDebug.h"
namespace mozilla {
namespace dom {
using indexedDB::IndexedDatabaseManager;
NS_IMPL_ISUPPORTS_INHERITED0(FileImpl, DOMFileImpl)
// Create as a file
FileImpl::FileImpl(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle)
: DOMFileImplBase(aName, aContentType, aLength),
mFile(aFile), mFileHandle(aFileHandle), mWholeFile(true), mStoredFile(false)
{
MOZ_ASSERT(mFile, "Null file!");
MOZ_ASSERT(mFileHandle, "Null file handle!");
}
// Create as a stored file
FileImpl::FileImpl(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle,
indexedDB::FileInfo* aFileInfo)
: DOMFileImplBase(aName, aContentType, aLength),
mFile(aFile), mFileHandle(aFileHandle), mWholeFile(true), mStoredFile(true)
{
MOZ_ASSERT(mFile, "Null file!");
MOZ_ASSERT(mFileHandle, "Null file handle!");
mFileInfos.AppendElement(aFileInfo);
}
// Create slice
FileImpl::FileImpl(const FileImpl* aOther, uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
: DOMFileImplBase(aContentType, aOther->mStart + aStart, aLength),
mFile(aOther->mFile), mFileHandle(aOther->mFileHandle),
mWholeFile(false), mStoredFile(aOther->mStoredFile)
{
MOZ_ASSERT(mFile, "Null file!");
MOZ_ASSERT(mFileHandle, "Null file handle!");
if (mStoredFile) {
indexedDB::FileInfo* fileInfo;
if (IndexedDatabaseManager::IsClosed()) {
fileInfo = aOther->GetFileInfo();
}
else {
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
fileInfo = aOther->GetFileInfo();
}
mFileInfos.AppendElement(fileInfo);
}
}
FileImpl::~FileImpl()
{
}
void
FileImpl::Unlink()
{
FileImpl* tmp = this;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileHandle);
}
void
FileImpl::Traverse(nsCycleCollectionTraversalCallback &cb)
{
FileImpl* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileHandle);
}
nsresult
FileImpl::GetInternalStream(nsIInputStream** aStream)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = mFileHandle->OpenInputStream(mWholeFile, mStart, mLength,
aStream);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
already_AddRefed<nsIDOMBlob>
FileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIDOMBlob> t =
new DOMFile(new FileImpl(this, aStart, aLength, aContentType));
return t.forget();
}
nsresult
FileImpl::GetMozFullPathInternal(nsAString& aFilename)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(mIsFile, "Should only be called on files");
return mFile->GetPath(aFilename);
}
} // namespace dom
} // namespace mozilla

View File

@ -12,25 +12,19 @@
#include "FileService.h"
#include "FileStreamWrappers.h"
#include "MemoryStreams.h"
#include "MetadataHelper.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/FileHandleBinding.h"
#include "mozilla/EventDispatcher.h"
#include "MutableFile.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsIAppShell.h"
#include "nsIDOMEvent.h"
#include "nsIDOMFile.h"
#include "nsIEventTarget.h"
#include "nsISeekableStream.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsStringStream.h"
#include "nsThreadUtils.h"
#include "nsWidgetsCID.h"
#include "xpcpublic.h"
#define STREAM_COPY_BLOCK_SIZE 32768
@ -39,13 +33,11 @@ namespace dom {
namespace {
NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
class ReadHelper : public FileHelper
{
public:
ReadHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest,
ReadHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest,
uint64_t aLocation,
uint64_t aSize)
: FileHelper(aFileHandle, aFileRequest),
@ -74,8 +66,8 @@ protected:
class ReadTextHelper : public ReadHelper
{
public:
ReadTextHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest,
ReadTextHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest,
uint64_t aLocation,
uint64_t aSize,
const nsAString& aEncoding)
@ -94,8 +86,8 @@ private:
class WriteHelper : public FileHelper
{
public:
WriteHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest,
WriteHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest,
uint64_t aLocation,
nsIInputStream* aStream,
uint64_t aLength)
@ -117,8 +109,8 @@ private:
class TruncateHelper : public FileHelper
{
public:
TruncateHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest,
TruncateHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest,
uint64_t aOffset)
: FileHelper(aFileHandle, aFileRequest),
mOffset(aOffset)
@ -148,8 +140,8 @@ private:
class FlushHelper : public FileHelper
{
public:
FlushHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest)
FlushHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest)
: FileHelper(aFileHandle, aFileRequest)
{ }
@ -172,7 +164,7 @@ private:
class OpenStreamHelper : public FileHelper
{
public:
OpenStreamHelper(FileHandle* aFileHandle,
OpenStreamHelper(FileHandleBase* aFileHandle,
bool aWholeFile,
uint64_t aStart,
uint64_t aLength)
@ -197,95 +189,28 @@ private:
nsCOMPtr<nsIInputStream> mStream;
};
already_AddRefed<nsIDOMEvent>
CreateGenericEvent(EventTarget* aEventOwner,
const nsAString& aType, bool aBubbles, bool aCancelable)
{
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMEvent(getter_AddRefs(event), aEventOwner, nullptr, nullptr);
nsresult rv = event->InitEvent(aType, aBubbles, aCancelable);
NS_ENSURE_SUCCESS(rv, nullptr);
event->SetTrusted(true);
return event.forget();
}
} // anonymous namespace
// static
already_AddRefed<FileHandle>
FileHandle::Create(MutableFile* aMutableFile,
FileMode aMode,
RequestMode aRequestMode)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
nsRefPtr<FileHandle> fileHandle = new FileHandle();
fileHandle->BindToOwner(aMutableFile);
fileHandle->mMutableFile = aMutableFile;
fileHandle->mMode = aMode;
fileHandle->mRequestMode = aRequestMode;
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
NS_ENSURE_TRUE(appShell, nullptr);
nsresult rv = appShell->RunBeforeNextEvent(fileHandle);
NS_ENSURE_SUCCESS(rv, nullptr);
fileHandle->mCreating = true;
FileService* service = FileService::GetOrCreate();
NS_ENSURE_TRUE(service, nullptr);
rv = service->Enqueue(fileHandle, nullptr);
NS_ENSURE_SUCCESS(rv, nullptr);
return fileHandle.forget();
}
FileHandle::FileHandle()
FileHandleBase::FileHandleBase(FileMode aMode,
RequestMode aRequestMode)
: mReadyState(INITIAL),
mMode(FileMode::Readonly),
mRequestMode(NORMAL),
mMode(aMode),
mRequestMode(aRequestMode),
mLocation(0),
mPendingRequests(0),
mAborted(false),
mCreating(false)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
SetIsDOMBinding();
}
FileHandle::~FileHandle()
FileHandleBase::~FileHandleBase()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(FileHandle, DOMEventTargetHelper,
mMutableFile)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileHandle)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(FileHandle, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(FileHandle, DOMEventTargetHelper)
nsresult
FileHandle::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
aVisitor.mCanHandle = true;
aVisitor.mParentTarget = mMutableFile;
return NS_OK;
}
void
FileHandle::OnNewRequest()
FileHandleBase::OnNewRequest()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
if (!mPendingRequests) {
@ -296,30 +221,31 @@ FileHandle::OnNewRequest()
}
void
FileHandle::OnRequestFinished()
FileHandleBase::OnRequestFinished()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(mPendingRequests, "Mismatched calls!");
--mPendingRequests;
if (!mPendingRequests) {
MOZ_ASSERT(mAborted || mReadyState == LOADING, "Bad state!");
mReadyState = FileHandle::FINISHING;
mReadyState = FileHandleBase::FINISHING;
Finish();
}
}
nsresult
FileHandle::CreateParallelStream(nsISupports** aStream)
FileHandleBase::CreateParallelStream(nsISupports** aStream)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
if (mMutableFile->IsInvalid()) {
MutableFileBase* mutableFile = MutableFile();
if (mutableFile->IsInvalid()) {
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsISupports> stream =
mMutableFile->CreateStream(mMutableFile->mFile,
mMode == FileMode::Readonly);
mutableFile->CreateStream(mMode == FileMode::Readonly);
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
mParallelStreams.AppendElement(stream);
@ -329,18 +255,19 @@ FileHandle::CreateParallelStream(nsISupports** aStream)
}
nsresult
FileHandle::GetOrCreateStream(nsISupports** aStream)
FileHandleBase::GetOrCreateStream(nsISupports** aStream)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
if (mMutableFile->IsInvalid()) {
MutableFileBase* mutableFile = MutableFile();
if (mutableFile->IsInvalid()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (!mStream) {
nsCOMPtr<nsISupports> stream =
mMutableFile->CreateStream(mMutableFile->mFile,
mMode == FileMode::Readonly);
mutableFile->CreateStream(mMode == FileMode::Readonly);
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
stream.swap(mStream);
@ -352,15 +279,8 @@ FileHandle::GetOrCreateStream(nsISupports** aStream)
return NS_OK;
}
already_AddRefed<FileRequest>
FileHandle::GenerateFileRequest()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return FileRequest::Create(GetOwner(), this, /* aWrapAsDOMRequest */ false);
}
bool
FileHandle::IsOpen() const
FileHandleBase::IsOpen() const
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -389,51 +309,9 @@ FileHandle::IsOpen() const
return false;
}
// virtual
JSObject*
FileHandle::WrapObject(JSContext* aCx)
{
return FileHandleBinding::Wrap(aCx, this);
}
already_AddRefed<FileRequest>
FileHandle::GetMetadata(const DOMFileMetadataParameters& aParameters,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
// Common state checking
if (!CheckState(aRv)) {
return nullptr;
}
// Do nothing if the window is closed
if (!GetOwner()) {
return nullptr;
}
nsRefPtr<MetadataParameters> params =
new MetadataParameters(aParameters.mSize, aParameters.mLastModified);
if (!params->IsConfigured()) {
aRv.ThrowTypeError(MSG_METADATA_NOT_CONFIGURED);
return nullptr;
}
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
nsRefPtr<MetadataHelper> helper =
new MetadataHelper(this, fileRequest, params);
if (NS_WARN_IF(NS_FAILED(helper->Enqueue()))) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
return fileRequest.forget();
}
already_AddRefed<FileRequest>
FileHandle::ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
already_AddRefed<FileRequestBase>
FileHandleBase::Read(uint64_t aSize, bool aHasEncoding,
const nsAString& aEncoding, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -443,14 +321,18 @@ FileHandle::ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
}
// Do nothing if the window is closed
if (!GetOwner()) {
if (!CheckWindow()) {
return nullptr;
}
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<ReadHelper> helper =
new ReadHelper(this, fileRequest, mLocation, aSize);
nsRefPtr<ReadHelper> helper;
if (aHasEncoding) {
helper = new ReadTextHelper(this, fileRequest, mLocation, aSize, aEncoding);
} else {
helper = new ReadHelper(this, fileRequest, mLocation, aSize);
}
if (NS_WARN_IF(NS_FAILED(helper->Init())) ||
NS_WARN_IF(NS_FAILED(helper->Enqueue()))) {
@ -463,40 +345,8 @@ FileHandle::ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
return fileRequest.forget();
}
already_AddRefed<FileRequest>
FileHandle::ReadAsText(uint64_t aSize, const nsAString& aEncoding,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
// State and argument checking for read
if (!CheckStateAndArgumentsForRead(aSize, aRv)) {
return nullptr;
}
// Do nothing if the window is closed
if (!GetOwner()) {
return nullptr;
}
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
nsRefPtr<ReadTextHelper> helper =
new ReadTextHelper(this, fileRequest, mLocation, aSize, aEncoding);
if (NS_WARN_IF(NS_FAILED(helper->Init())) ||
NS_WARN_IF(NS_FAILED(helper->Enqueue()))) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
mLocation += aSize;
return fileRequest.forget();
}
already_AddRefed<FileRequest>
FileHandle::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
already_AddRefed<FileRequestBase>
FileHandleBase::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -520,11 +370,11 @@ FileHandle::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
}
// Do nothing if the window is closed
if (!GetOwner()) {
if (!CheckWindow()) {
return nullptr;
}
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<TruncateHelper> helper =
new TruncateHelper(this, fileRequest, location);
@ -541,8 +391,8 @@ FileHandle::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
return fileRequest.forget();
}
already_AddRefed<FileRequest>
FileHandle::Flush(ErrorResult& aRv)
already_AddRefed<FileRequestBase>
FileHandleBase::Flush(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -552,11 +402,11 @@ FileHandle::Flush(ErrorResult& aRv)
}
// Do nothing if the window is closed
if (!GetOwner()) {
if (!CheckWindow()) {
return nullptr;
}
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<FlushHelper> helper = new FlushHelper(this, fileRequest);
@ -569,7 +419,7 @@ FileHandle::Flush(ErrorResult& aRv)
}
void
FileHandle::Abort(ErrorResult& aRv)
FileHandleBase::Abort(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -577,8 +427,8 @@ FileHandle::Abort(ErrorResult& aRv)
// We can't use IsOpen here since we need it to be possible to call Abort()
// even from outside of transaction callbacks.
if (mReadyState != FileHandle::INITIAL &&
mReadyState != FileHandle::LOADING) {
if (mReadyState != FileHandleBase::INITIAL &&
mReadyState != FileHandleBase::LOADING) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
return;
}
@ -595,8 +445,8 @@ FileHandle::Abort(ErrorResult& aRv)
}
}
NS_IMETHODIMP
FileHandle::Run()
void
FileHandleBase::OnReturnToEventLoop()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -611,13 +461,11 @@ FileHandle::Run()
NS_WARNING("Failed to finish!");
}
}
return NS_OK;
}
nsresult
FileHandle::OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength,
nsIInputStream** aResult)
FileHandleBase::OpenInputStream(bool aWholeFile, uint64_t aStart,
uint64_t aLength, nsIInputStream** aResult)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(mRequestMode == PARALLEL,
@ -630,7 +478,7 @@ FileHandle::OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength,
}
// Do nothing if the window is closed
if (!GetOwner()) {
if (!CheckWindow()) {
return NS_OK;
}
@ -648,7 +496,7 @@ FileHandle::OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength,
}
bool
FileHandle::CheckState(ErrorResult& aRv)
FileHandleBase::CheckState(ErrorResult& aRv)
{
if (!IsOpen()) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_INACTIVE_ERR);
@ -659,7 +507,7 @@ FileHandle::CheckState(ErrorResult& aRv)
}
bool
FileHandle::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv)
FileHandleBase::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv)
{
// Common state checking
if (!CheckState(aRv)) {
@ -682,7 +530,7 @@ FileHandle::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv)
}
bool
FileHandle::CheckStateForWrite(ErrorResult& aRv)
FileHandleBase::CheckStateForWrite(ErrorResult& aRv)
{
// Common state checking
if (!CheckState(aRv)) {
@ -698,9 +546,10 @@ FileHandle::CheckStateForWrite(ErrorResult& aRv)
return true;
}
already_AddRefed<FileRequest>
FileHandle::WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength,
bool aAppend, ErrorResult& aRv)
already_AddRefed<FileRequestBase>
FileHandleBase::WriteInternal(nsIInputStream* aInputStream,
uint64_t aInputLength, bool aAppend,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -709,9 +558,9 @@ FileHandle::WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength,
MOZ_ASSERT_IF(!aAppend, mLocation != UINT64_MAX);
MOZ_ASSERT(aInputStream);
MOZ_ASSERT(aInputLength);
MOZ_ASSERT(GetOwner());
MOZ_ASSERT(CheckWindow());
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
uint64_t location = aAppend ? UINT64_MAX : mLocation;
@ -734,7 +583,7 @@ FileHandle::WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength,
}
nsresult
FileHandle::Finish()
FileHandleBase::Finish()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -753,8 +602,8 @@ FileHandle::Finish()
// static
already_AddRefed<nsIInputStream>
FileHandle::GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength,
ErrorResult& aRv)
FileHandleBase::GetInputStream(const ArrayBuffer& aValue,
uint64_t* aInputLength, ErrorResult& aRv)
{
aValue.ComputeLengthAndData();
const char* data = reinterpret_cast<const char*>(aValue.Data());
@ -773,8 +622,8 @@ FileHandle::GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength,
// static
already_AddRefed<nsIInputStream>
FileHandle::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength,
ErrorResult& aRv)
FileHandleBase::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength,
ErrorResult& aRv)
{
uint64_t length;
aRv = aValue->GetSize(&length);
@ -794,8 +643,8 @@ FileHandle::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength,
// static
already_AddRefed<nsIInputStream>
FileHandle::GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
ErrorResult& aRv)
FileHandleBase::GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
ErrorResult& aRv)
{
NS_ConvertUTF16toUTF8 cstr(aValue);
@ -809,7 +658,7 @@ FileHandle::GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
return stream.forget();
}
FinishHelper::FinishHelper(FileHandle* aFileHandle)
FinishHelper::FinishHelper(FileHandleBase* aFileHandle)
: mFileHandle(aFileHandle),
mAborted(aFileHandle->mAborted)
{
@ -823,27 +672,16 @@ NS_IMETHODIMP
FinishHelper::Run()
{
if (NS_IsMainThread()) {
mFileHandle->mReadyState = FileHandle::DONE;
mFileHandle->mReadyState = FileHandleBase::DONE;
FileService* service = FileService::Get();
if (service) {
service->NotifyFileHandleCompleted(mFileHandle);
}
nsCOMPtr<nsIDOMEvent> event;
if (mAborted) {
event = CreateGenericEvent(mFileHandle, NS_LITERAL_STRING("abort"),
true, false);
}
else {
event = CreateGenericEvent(mFileHandle, NS_LITERAL_STRING("complete"),
false, false);
}
NS_ENSURE_TRUE(event, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
bool dummy;
if (NS_FAILED(mFileHandle->DispatchEvent(event, &dummy))) {
NS_WARNING("Dispatch failed!");
nsresult rv = mFileHandle->OnCompleteOrAbort(mAborted);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mFileHandle = nullptr;
@ -851,7 +689,7 @@ FinishHelper::Run()
return NS_OK;
}
if (mFileHandle->mMutableFile->IsInvalid()) {
if (mFileHandle->MutableFile()->IsInvalid()) {
mAborted = true;
}

View File

@ -7,55 +7,38 @@
#ifndef mozilla_dom_FileHandle_h
#define mozilla_dom_FileHandle_h
#include "js/TypeDecls.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/FileModeBinding.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/ErrorResult.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIInputStream.h"
#include "nsIRunnable.h"
#include "nsTArray.h"
class nsAString;
class nsIDOMBlob;
class nsPIDOMWindow;
namespace mozilla {
class EventChainPreVisitor;
namespace dom {
struct DOMFileMetadataParameters;
class FileHelper;
class FileRequest;
class FileRequestBase;
class FileService;
class FinishHelper;
class MetadataHelper;
class MutableFile;
class MutableFileBase;
class FileHandle : public DOMEventTargetHelper,
public nsIRunnable
/**
* This class provides a base for FileHandle implementations.
*/
class FileHandleBase
{
friend class FileHelper;
friend class FileService;
friend class FinishHelper;
friend class MetadataHelper;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIRUNNABLE
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileHandle, DOMEventTargetHelper)
enum RequestMode
{
NORMAL = 0, // Sequential
@ -70,14 +53,30 @@ public:
DONE
};
static already_AddRefed<FileHandle>
Create(MutableFile* aMutableFile,
FileMode aMode,
RequestMode aRequestMode = NORMAL);
private:
friend class FileHelper;
friend class FileService;
friend class FinishHelper;
friend class MetadataHelper;
// nsIDOMEventTarget
virtual nsresult
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
ReadyState mReadyState;
FileMode mMode;
RequestMode mRequestMode;
uint64_t mLocation;
uint32_t mPendingRequests;
nsTArray<nsCOMPtr<nsISupports>> mParallelStreams;
nsCOMPtr<nsISupports> mStream;
bool mAborted;
bool mCreating;
public:
NS_IMETHOD_(MozExternalRefCountType)
AddRef() = 0;
NS_IMETHOD_(MozExternalRefCountType)
Release() = 0;
nsresult
CreateParallelStream(nsISupports** aStream);
@ -94,41 +93,20 @@ public:
return mAborted;
}
MutableFile*
File() const
void
SetCreating()
{
return mMutableFile;
mCreating = true;
}
virtual MutableFileBase*
MutableFile() const = 0;
nsresult
OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength,
nsIInputStream** aResult);
// WrapperCache
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
nsPIDOMWindow*
GetParentObject() const
{
return GetOwner();
}
MutableFile*
GetMutableFile() const
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return File();
}
MutableFile*
GetFileHandle() const
{
return GetMutableFile();
}
// Shared WebIDL (IndexedDB FileHandle and FileSystem FileHandle)
FileMode
Mode() const
{
@ -170,49 +148,23 @@ public:
}
}
already_AddRefed<FileRequest>
GetMetadata(const DOMFileMetadataParameters& aParameters, ErrorResult& aRv);
already_AddRefed<FileRequestBase>
Read(uint64_t aSize, bool aHasEncoding, const nsAString& aEncoding,
ErrorResult& aRv);
already_AddRefed<FileRequest>
ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv);
already_AddRefed<FileRequest>
ReadAsText(uint64_t aSize, const nsAString& aEncoding, ErrorResult& aRv);
template<class T>
already_AddRefed<FileRequest>
Write(const T& aValue, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return WriteOrAppend(aValue, false, aRv);
}
template<class T>
already_AddRefed<FileRequest>
Append(const T& aValue, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return WriteOrAppend(aValue, true, aRv);
}
already_AddRefed<FileRequest>
already_AddRefed<FileRequestBase>
Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv);
already_AddRefed<FileRequest>
already_AddRefed<FileRequestBase>
Flush(ErrorResult& aRv);
void
Abort(ErrorResult& aRv);
IMPL_EVENT_HANDLER(complete)
IMPL_EVENT_HANDLER(abort)
IMPL_EVENT_HANDLER(error)
private:
FileHandle();
~FileHandle();
protected:
FileHandleBase(FileMode aMode,
RequestMode aRequestMode);
~FileHandleBase();
void
OnNewRequest();
@ -220,6 +172,12 @@ private:
void
OnRequestFinished();
void
OnReturnToEventLoop();
virtual nsresult
OnCompleteOrAbort(bool aAborted) = 0;
bool
CheckState(ErrorResult& aRv);
@ -229,11 +187,14 @@ private:
bool
CheckStateForWrite(ErrorResult& aRv);
already_AddRefed<FileRequest>
GenerateFileRequest();
virtual bool
CheckWindow() = 0;
virtual already_AddRefed<FileRequestBase>
GenerateFileRequest() = 0;
template<class T>
already_AddRefed<FileRequest>
already_AddRefed<FileRequestBase>
WriteOrAppend(const T& aValue, bool aAppend, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -260,14 +221,14 @@ private:
}
// Do nothing if the window is closed
if (!GetOwner()) {
if (!CheckWindow()) {
return nullptr;
}
return WriteInternal(stream, length, aAppend, aRv);
}
already_AddRefed<FileRequest>
already_AddRefed<FileRequestBase>
WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength,
bool aAppend, ErrorResult& aRv);
@ -284,35 +245,22 @@ private:
static already_AddRefed<nsIInputStream>
GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
ErrorResult& aRv);
nsRefPtr<MutableFile> mMutableFile;
ReadyState mReadyState;
FileMode mMode;
RequestMode mRequestMode;
uint64_t mLocation;
uint32_t mPendingRequests;
nsTArray<nsCOMPtr<nsISupports>> mParallelStreams;
nsCOMPtr<nsISupports> mStream;
bool mAborted;
bool mCreating;
};
class FinishHelper MOZ_FINAL : public nsIRunnable
{
friend class FileHandle;
friend class FileHandleBase;
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIRUNNABLE
private:
FinishHelper(FileHandle* aFileHandle);
FinishHelper(FileHandleBase* aFileHandle);
~FinishHelper()
{ }
nsRefPtr<FileHandle> mFileHandle;
nsRefPtr<FileHandleBase> mFileHandle;
nsTArray<nsCOMPtr<nsISupports>> mParallelStreams;
nsCOMPtr<nsISupports> mStream;

View File

@ -22,13 +22,13 @@ namespace dom {
namespace {
FileHandle* gCurrentFileHandle = nullptr;
FileHandleBase* gCurrentFileHandle = nullptr;
} // anonymous namespace
FileHelper::FileHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest)
: mMutableFile(aFileHandle->mMutableFile),
FileHelper::FileHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest)
: mMutableFile(aFileHandle->MutableFile()),
mFileHandle(aFileHandle),
mFileRequest(aFileRequest),
mResultCode(NS_OK),
@ -75,7 +75,7 @@ FileHelper::AsyncRun(FileHelperListener* aListener)
nsresult rv;
nsCOMPtr<nsISupports> stream;
if (mFileHandle->mRequestMode == FileHandle::PARALLEL) {
if (mFileHandle->mRequestMode == FileHandleBase::PARALLEL) {
rv = mFileHandle->CreateParallelStream(getter_AddRefs(stream));
}
else {
@ -146,7 +146,7 @@ FileHelper::OnStreamProgress(uint64_t aProgress, uint64_t aProgressMax)
}
// static
FileHandle*
FileHandleBase*
FileHelper::GetCurrentFileHandle()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -193,7 +193,7 @@ FileHelper::Finish()
mResultCode = NS_ERROR_DOM_FILEHANDLE_ABORT_ERR;
}
FileHandle* oldFileHandle = gCurrentFileHandle;
FileHandleBase* oldFileHandle = gCurrentFileHandle;
gCurrentFileHandle = mFileHandle;
if (mFileRequest) {

View File

@ -15,11 +15,11 @@
namespace mozilla {
namespace dom {
class FileHandle;
class FileHandleBase;
class FileHelper;
class FileRequest;
class FileRequestBase;
class FileOutputStreamWrapper;
class MutableFile;
class MutableFileBase;
class FileHelperListener
{
@ -41,19 +41,27 @@ public:
*/
class FileHelper : public nsIRequestObserver
{
friend class FileRequest;
friend class FileOutputStreamWrapper;
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
nsresult
ResultCode() const
{
return mResultCode;
}
nsresult
Enqueue();
nsresult
AsyncRun(FileHelperListener* aListener);
virtual nsresult
GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal);
void
OnStreamProgress(uint64_t aProgress, uint64_t aProgressMax);
@ -63,29 +71,26 @@ public:
void
OnStreamDestroy();
static FileHandle*
static FileHandleBase*
GetCurrentFileHandle();
protected:
FileHelper(FileHandle* aFileHandle, FileRequest* aRequest);
FileHelper(FileHandleBase* aFileHandle, FileRequestBase* aRequest);
virtual ~FileHelper();
virtual nsresult
DoAsyncRun(nsISupports* aStream) = 0;
virtual nsresult
GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal);
virtual void
ReleaseObjects();
void
Finish();
nsRefPtr<MutableFile> mMutableFile;
nsRefPtr<FileHandle> mFileHandle;
nsRefPtr<FileRequest> mFileRequest;
nsRefPtr<MutableFileBase> mMutableFile;
nsRefPtr<FileHandleBase> mFileHandle;
nsRefPtr<FileRequestBase> mFileRequest;
nsRefPtr<FileHelperListener> mListener;
nsCOMPtr<nsIRequest> mRequest;

View File

@ -6,145 +6,20 @@
#include "FileRequest.h"
#include "FileHandle.h"
#include "FileHelper.h"
#include "js/RootingAPI.h"
#include "jsapi.h"
#include "MainThreadUtils.h"
#include "mozilla/dom/FileRequestBinding.h"
#include "mozilla/EventDispatcher.h"
#include "nsCOMPtr.h"
#include "nsCxPusher.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsIDOMEvent.h"
#include "mozilla/dom/ProgressEvent.h"
#include "nsIScriptContext.h"
#include "nsLiteralString.h"
#include "mozilla/Assertions.h"
namespace mozilla {
namespace dom {
FileRequest::FileRequest(nsPIDOMWindow* aWindow)
: DOMRequest(aWindow), mWrapAsDOMRequest(false)
FileRequestBase::FileRequestBase()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(NS_IsMainThread());
}
FileRequest::~FileRequest()
FileRequestBase::~FileRequestBase()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
// static
already_AddRefed<FileRequest>
FileRequest::Create(nsPIDOMWindow* aOwner, FileHandle* aFileHandle,
bool aWrapAsDOMRequest)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsRefPtr<FileRequest> request = new FileRequest(aOwner);
request->mFileHandle = aFileHandle;
request->mWrapAsDOMRequest = aWrapAsDOMRequest;
return request.forget();
}
nsresult
FileRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
aVisitor.mCanHandle = true;
aVisitor.mParentTarget = mFileHandle;
return NS_OK;
}
nsresult
FileRequest::NotifyHelperCompleted(FileHelper* aFileHelper)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = aFileHelper->mResultCode;
// If the request failed then fire error event and return.
if (NS_FAILED(rv)) {
FireError(rv);
return NS_OK;
}
// Otherwise we need to get the result from the helper.
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_STATE(sc);
AutoJSContext cx;
NS_ASSERTION(cx, "Failed to get a context!");
JS::Rooted<JS::Value> result(cx);
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
NS_ASSERTION(global, "Failed to get global object!");
JSAutoCompartment ac(cx, global);
rv = aFileHelper->GetSuccessResult(cx, &result);
if (NS_FAILED(rv)) {
NS_WARNING("GetSuccessResult failed!");
}
if (NS_SUCCEEDED(rv)) {
FireSuccess(result);
}
else {
FireError(rv);
}
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(FileRequest, DOMRequest,
mFileHandle)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileRequest)
NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
NS_IMPL_ADDREF_INHERITED(FileRequest, DOMRequest)
NS_IMPL_RELEASE_INHERITED(FileRequest, DOMRequest)
// virtual
JSObject*
FileRequest::WrapObject(JSContext* aCx)
{
if (mWrapAsDOMRequest) {
return DOMRequest::WrapObject(aCx);
}
return FileRequestBinding::Wrap(aCx, this);
}
FileHandle*
FileRequest::GetFileHandle() const
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return mFileHandle;
}
void
FileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
{
if (NS_FAILED(CheckInnerWindowCorrectness())) {
return;
}
ProgressEventInit init;
init.mBubbles = false;
init.mCancelable = false;
init.mLengthComputable = false;
init.mLoaded = aLoaded;
init.mTotal = aTotal;
nsRefPtr<ProgressEvent> event =
ProgressEvent::Constructor(this, NS_LITERAL_STRING("progress"), init);
DispatchTrustedEvent(event);
MOZ_ASSERT(NS_IsMainThread());
}
} // namespace dom

View File

@ -7,73 +7,35 @@
#ifndef mozilla_dom_FileRequest_h
#define mozilla_dom_FileRequest_h
#include "DOMRequest.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
class nsPIDOMWindow;
#include "nscore.h"
namespace mozilla {
class EventChainPreVisitor;
namespace dom {
class FileHandle;
class FileHelper;
class FileRequest : public DOMRequest
/**
* This class provides a base for FileRequest implementations.
*/
class FileRequestBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD_(MozExternalRefCountType)
AddRef() = 0;
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileRequest, DOMRequest)
NS_IMETHOD_(MozExternalRefCountType)
Release() = 0;
static already_AddRefed<FileRequest>
Create(nsPIDOMWindow* aOwner, FileHandle* aFileHandle,
bool aWrapAsDOMRequest);
virtual void
OnProgress(uint64_t aProgress, uint64_t aProgressMax) = 0;
// nsIDOMEventTarget
virtual nsresult
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
void
OnProgress(uint64_t aProgress, uint64_t aProgressMax)
{
FireProgressEvent(aProgress, aProgressMax);
}
nsresult
NotifyHelperCompleted(FileHelper* aFileHelper);
// nsWrapperCache
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
FileHandle*
GetFileHandle() const;
FileHandle*
GetLockedFile() const
{
return GetFileHandle();
}
IMPL_EVENT_HANDLER(progress)
NotifyHelperCompleted(FileHelper* aFileHelper) = 0;
protected:
FileRequest(nsPIDOMWindow* aWindow);
~FileRequest();
FileRequestBase();
void
FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
nsRefPtr<FileHandle> mFileHandle;
bool mWrapAsDOMRequest;
virtual ~FileRequestBase();
};
} // namespace dom

View File

@ -146,12 +146,12 @@ FileService::IsShuttingDown()
}
nsresult
FileService::Enqueue(FileHandle* aFileHandle, FileHelper* aFileHelper)
FileService::Enqueue(FileHandleBase* aFileHandle, FileHelper* aFileHelper)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(aFileHandle, "Null pointer!");
MutableFile* mutableFile = aFileHandle->mMutableFile;
MutableFileBase* mutableFile = aFileHandle->MutableFile();
if (mutableFile->IsInvalid()) {
return NS_ERROR_NOT_AVAILABLE;
@ -221,12 +221,12 @@ FileService::Enqueue(FileHandle* aFileHandle, FileHelper* aFileHelper)
}
void
FileService::NotifyFileHandleCompleted(FileHandle* aFileHandle)
FileService::NotifyFileHandleCompleted(FileHandleBase* aFileHandle)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(aFileHandle, "Null pointer!");
MutableFile* mutableFile = aFileHandle->mMutableFile;
MutableFileBase* mutableFile = aFileHandle->MutableFile();
const nsACString& storageId = mutableFile->mStorageId;
StorageInfo* storageInfo;
@ -282,7 +282,7 @@ FileService::AbortFileHandlesForStorage(nsIOfflineStorage* aStorage)
return;
}
nsAutoTArray<nsRefPtr<FileHandle>, 10> fileHandles;
nsAutoTArray<nsRefPtr<FileHandleBase>, 10> fileHandles;
storageInfo->CollectRunningAndDelayedFileHandles(aStorage, fileHandles);
for (uint32_t index = 0; index < fileHandles.Length(); index++) {
@ -334,7 +334,7 @@ FileService::MaybeFireCallback(StoragesCompleteCallback& aCallback)
return true;
}
FileService::FileHandleQueue::FileHandleQueue(FileHandle* aFileHandle)
FileService::FileHandleQueue::FileHandleQueue(FileHandleBase* aFileHandle)
: mFileHandle(aFileHandle)
{
MOZ_ASSERT(aFileHandle, "Null pointer!");
@ -353,7 +353,7 @@ FileService::FileHandleQueue::Enqueue(FileHelper* aFileHelper)
mQueue.AppendElement(aFileHelper);
nsresult rv;
if (mFileHandle->mRequestMode == FileHandle::PARALLEL) {
if (mFileHandle->mRequestMode == FileHandleBase::PARALLEL) {
rv = aFileHelper->AsyncRun(this);
}
else {
@ -368,7 +368,7 @@ void
FileService::
FileHandleQueue::OnFileHelperComplete(FileHelper* aFileHelper)
{
if (mFileHandle->mRequestMode == FileHandle::PARALLEL) {
if (mFileHandle->mRequestMode == FileHandleBase::PARALLEL) {
int32_t index = mQueue.IndexOf(aFileHelper);
NS_ASSERTION(index != -1, "We don't know anything about this helper!");
@ -411,7 +411,7 @@ FileService::DelayedEnqueueInfo::~DelayedEnqueueInfo()
}
FileService::FileHandleQueue*
FileService::StorageInfo::CreateFileHandleQueue(FileHandle* aFileHandle)
FileService::StorageInfo::CreateFileHandleQueue(FileHandleBase* aFileHandle)
{
nsRefPtr<FileHandleQueue>* fileHandleQueue =
mFileHandleQueues.AppendElement();
@ -420,7 +420,7 @@ FileService::StorageInfo::CreateFileHandleQueue(FileHandle* aFileHandle)
}
FileService::FileHandleQueue*
FileService::StorageInfo::GetFileHandleQueue(FileHandle* aFileHandle)
FileService::StorageInfo::GetFileHandleQueue(FileHandleBase* aFileHandle)
{
uint32_t count = mFileHandleQueues.Length();
for (uint32_t index = 0; index < count; index++) {
@ -433,7 +433,7 @@ FileService::StorageInfo::GetFileHandleQueue(FileHandle* aFileHandle)
}
void
FileService::StorageInfo::RemoveFileHandleQueue(FileHandle* aFileHandle)
FileService::StorageInfo::RemoveFileHandleQueue(FileHandleBase* aFileHandle)
{
for (uint32_t index = 0; index < mDelayedEnqueueInfos.Length(); index++) {
if (mDelayedEnqueueInfos[index].mFileHandle == aFileHandle) {
@ -453,7 +453,7 @@ FileService::StorageInfo::RemoveFileHandleQueue(FileHandle* aFileHandle)
mFilesWriting.Clear();
for (uint32_t index = 0, count = fileHandleCount; index < count; index++) {
FileHandle* fileHandle = mFileHandleQueues[index]->mFileHandle;
FileHandleBase* fileHandle = mFileHandleQueues[index]->mFileHandle;
if (fileHandle == aFileHandle) {
MOZ_ASSERT(count == fileHandleCount, "More than one match?!");
@ -464,7 +464,7 @@ FileService::StorageInfo::RemoveFileHandleQueue(FileHandle* aFileHandle)
continue;
}
const nsAString& fileName = fileHandle->mMutableFile->mFileName;
const nsAString& fileName = fileHandle->MutableFile()->mFileName;
if (fileHandle->mMode == FileMode::Readwrite) {
if (!IsFileLockedForWriting(fileName)) {
@ -497,8 +497,8 @@ bool
FileService::StorageInfo::HasRunningFileHandles(nsIOfflineStorage* aStorage)
{
for (uint32_t index = 0; index < mFileHandleQueues.Length(); index++) {
FileHandle* fileHandle = mFileHandleQueues[index]->mFileHandle;
if (fileHandle->mMutableFile->Storage() == aStorage) {
FileHandleBase* fileHandle = mFileHandleQueues[index]->mFileHandle;
if (fileHandle->MutableFile()->Storage() == aStorage) {
return true;
}
}
@ -506,7 +506,7 @@ FileService::StorageInfo::HasRunningFileHandles(nsIOfflineStorage* aStorage)
}
FileService::DelayedEnqueueInfo*
FileService::StorageInfo::CreateDelayedEnqueueInfo(FileHandle* aFileHandle,
FileService::StorageInfo::CreateDelayedEnqueueInfo(FileHandleBase* aFileHandle,
FileHelper* aFileHelper)
{
DelayedEnqueueInfo* info = mDelayedEnqueueInfos.AppendElement();
@ -517,19 +517,19 @@ FileService::StorageInfo::CreateDelayedEnqueueInfo(FileHandle* aFileHandle,
void
FileService::StorageInfo::CollectRunningAndDelayedFileHandles(
nsIOfflineStorage* aStorage,
nsTArray<nsRefPtr<FileHandle>>& aFileHandles)
nsIOfflineStorage* aStorage,
nsTArray<nsRefPtr<FileHandleBase>>& aFileHandles)
{
for (uint32_t index = 0; index < mFileHandleQueues.Length(); index++) {
FileHandle* fileHandle = mFileHandleQueues[index]->mFileHandle;
if (fileHandle->mMutableFile->Storage() == aStorage) {
FileHandleBase* fileHandle = mFileHandleQueues[index]->mFileHandle;
if (fileHandle->MutableFile()->Storage() == aStorage) {
aFileHandles.AppendElement(fileHandle);
}
}
for (uint32_t index = 0; index < mDelayedEnqueueInfos.Length(); index++) {
FileHandle* fileHandle = mDelayedEnqueueInfos[index].mFileHandle;
if (fileHandle->mMutableFile->Storage() == aStorage) {
FileHandleBase* fileHandle = mDelayedEnqueueInfos[index].mFileHandle;
if (fileHandle->MutableFile()->Storage() == aStorage) {
aFileHandles.AppendElement(fileHandle);
}
}

View File

@ -26,7 +26,7 @@ class nsIRunnable;
namespace mozilla {
namespace dom {
class FileHandle;
class FileHandleBase;
class FileService MOZ_FINAL : public nsIObserver
{
@ -50,10 +50,10 @@ public:
IsShuttingDown();
nsresult
Enqueue(FileHandle* aFileHandle, FileHelper* aFileHelper);
Enqueue(FileHandleBase* aFileHandle, FileHelper* aFileHelper);
void
NotifyFileHandleCompleted(FileHandle* aFileHandle);
NotifyFileHandleCompleted(FileHandleBase* aFileHandle);
void
WaitForStoragesToComplete(nsTArray<nsCOMPtr<nsIOfflineStorage> >& aStorages,
@ -92,7 +92,7 @@ private:
private:
inline
FileHandleQueue(FileHandle* aFileHandle);
FileHandleQueue(FileHandleBase* aFileHandle);
~FileHandleQueue();
@ -101,7 +101,7 @@ private:
ThreadSafeAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
nsRefPtr<FileHandle> mFileHandle;
nsRefPtr<FileHandleBase> mFileHandle;
nsTArray<nsRefPtr<FileHelper> > mQueue;
nsRefPtr<FileHelper> mCurrentHelper;
};
@ -111,7 +111,7 @@ private:
DelayedEnqueueInfo();
~DelayedEnqueueInfo();
nsRefPtr<FileHandle> mFileHandle;
nsRefPtr<FileHandleBase> mFileHandle;
nsRefPtr<FileHelper> mFileHelper;
};
@ -121,13 +121,13 @@ private:
public:
inline FileHandleQueue*
CreateFileHandleQueue(FileHandle* aFileHandle);
CreateFileHandleQueue(FileHandleBase* aFileHandle);
inline FileHandleQueue*
GetFileHandleQueue(FileHandle* aFileHandle);
GetFileHandleQueue(FileHandleBase* aFileHandle);
void
RemoveFileHandleQueue(FileHandle* aFileHandle);
RemoveFileHandleQueue(FileHandleBase* aFileHandle);
bool
HasRunningFileHandles()
@ -139,12 +139,13 @@ private:
HasRunningFileHandles(nsIOfflineStorage* aStorage);
inline DelayedEnqueueInfo*
CreateDelayedEnqueueInfo(FileHandle* aFileHandle, FileHelper* aFileHelper);
CreateDelayedEnqueueInfo(FileHandleBase* aFileHandle,
FileHelper* aFileHelper);
inline void
CollectRunningAndDelayedFileHandles(
nsIOfflineStorage* aStorage,
nsTArray<nsRefPtr<FileHandle>>& aFileHandles);
nsIOfflineStorage* aStorage,
nsTArray<nsRefPtr<FileHandleBase>>& aFileHandles);
void
LockFileForReading(const nsAString& aFileName)

View File

@ -7,10 +7,10 @@
#ifndef mozilla_dom_MetadataHelper_h
#define mozilla_dom_MetadataHelper_h
#include "AsyncHelper.h"
#include "FileHelper.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/AsyncHelper.h"
#include "nsAutoPtr.h"
namespace mozilla {
@ -76,8 +76,8 @@ private:
class MetadataHelper : public FileHelper
{
public:
MetadataHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest,
MetadataHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest,
MetadataParameters* aParams)
: FileHelper(aFileHandle, aFileRequest),
mParams(aParams)

View File

@ -6,85 +6,32 @@
#include "MutableFile.h"
#include "File.h"
#include "FileHandle.h"
#include "FileRequest.h"
#include "FileService.h"
#include "MetadataHelper.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/MutableFileBinding.h"
#include "mozilla/ErrorResult.h"
#include "nsAutoPtr.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsIDOMFile.h"
#include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsNetUtil.h"
namespace mozilla {
namespace dom {
namespace {
class GetFileHelper : public MetadataHelper
{
public:
GetFileHelper(FileHandle* aFileHandle,
FileRequest* aFileRequest,
MetadataParameters* aParams,
MutableFile* aMutableFile)
: MetadataHelper(aFileHandle, aFileRequest, aParams),
mMutableFile(aMutableFile)
{ }
virtual nsresult
GetSuccessResult(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
virtual void
ReleaseObjects() MOZ_OVERRIDE
{
mMutableFile = nullptr;
MetadataHelper::ReleaseObjects();
}
private:
nsRefPtr<MutableFile> mMutableFile;
};
} // anonymous namespace
MutableFile::MutableFile(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow)
MutableFileBase::MutableFileBase()
{
}
MutableFile::MutableFile(DOMEventTargetHelper* aOwner)
: DOMEventTargetHelper(aOwner)
MutableFileBase::~MutableFileBase()
{
}
MutableFile::~MutableFile()
{
}
bool
MutableFile::IsShuttingDown()
{
return FileService::IsShuttingDown();
}
// virtual
already_AddRefed<nsISupports>
MutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
MutableFileBase::CreateStream(bool aReadOnly)
{
nsresult rv;
if (aReadOnly) {
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), aFile, -1, -1,
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), mFile, -1, -1,
nsIFileInputStream::DEFER_OPEN);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
@ -93,7 +40,7 @@ MutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
}
nsCOMPtr<nsIFileStream> stream;
rv = NS_NewLocalFileStream(getter_AddRefs(stream), aFile, -1, -1,
rv = NS_NewLocalFileStream(getter_AddRefs(stream), mFile, -1, -1,
nsIFileStream::DEFER_OPEN);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
@ -101,88 +48,5 @@ MutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
return stream.forget();
}
// virtual
already_AddRefed<nsIDOMFile>
MutableFile::CreateFileObject(FileHandle* aFileHandle, uint32_t aFileSize)
{
nsCOMPtr<nsIDOMFile> file =
new DOMFile(new FileImpl(mName, mType, aFileSize, mFile, aFileHandle));
return file.forget();
}
// virtual
JSObject*
MutableFile::WrapObject(JSContext* aCx)
{
return MutableFileBinding::Wrap(aCx, this);
}
already_AddRefed<FileHandle>
MutableFile::Open(FileMode aMode, ErrorResult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
if (IsShuttingDown()) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
nsRefPtr<FileHandle> fileHandle = FileHandle::Create(this, aMode);
if (!fileHandle) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
return fileHandle.forget();
}
already_AddRefed<DOMRequest>
MutableFile::GetFile(ErrorResult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
// Do nothing if the window is closed
if (!GetOwner()) {
return nullptr;
}
nsRefPtr<FileHandle> fileHandle =
FileHandle::Create(this, FileMode::Readonly, FileHandle::PARALLEL);
if (!fileHandle) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
nsRefPtr<FileRequest> request =
FileRequest::Create(GetOwner(), fileHandle, /* aWrapAsDOMRequest */ true);
nsRefPtr<MetadataParameters> params = new MetadataParameters(true, false);
nsRefPtr<GetFileHelper> helper =
new GetFileHelper(fileHandle, request, params, this);
nsresult rv = helper->Enqueue();
if (NS_FAILED(rv)) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
return request.forget();
}
nsresult
GetFileHelper::GetSuccessResult(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal)
{
nsCOMPtr<nsIDOMFile> domFile =
mMutableFile->CreateFileObject(mFileHandle, mParams->Size());
nsresult rv =
nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile), aVal);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return NS_OK;
}
} // namespace dom
} // namespace mozilla

View File

@ -7,75 +7,33 @@
#ifndef mozilla_dom_MutableFile_h
#define mozilla_dom_MutableFile_h
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/FileModeBinding.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCOMPtr.h"
#include "nsString.h"
class nsIDOMFile;
class nsIFile;
class nsIOfflineStorage;
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
namespace dom {
class DOMRequest;
class FileHandle;
class FileService;
class FinishHelper;
class FileHelper;
namespace indexedDB {
class FileInfo;
} // namespace indexedDB
/**
* This class provides a default MutableFile implementation, but it can be also
* subclassed. The subclass can override implementation of GetFileId,
* GetFileInfo, IsShuttingDown, IsInvalid, CreateStream, SetThreadLocals,
* UnsetThreadLocals and CreateFileObject.
* This class provides a base for MutableFile implementations.
* The subclasses can override implementation of IsInvalid, CreateStream,
* SetThreadLocals and UnsetThreadLocals.
* (for example IDBMutableFile provides IndexedDB specific implementation).
*/
class MutableFile : public DOMEventTargetHelper
class MutableFileBase
{
friend class FileHandle;
friend class FileService;
friend class FinishHelper;
friend class FileHelper;
public:
const nsAString&
Name() const
{
return mName;
}
NS_IMETHOD_(MozExternalRefCountType)
AddRef() = 0;
const nsAString&
Type() const
{
return mType;
}
virtual int64_t
GetFileId()
{
return -1;
}
virtual mozilla::dom::indexedDB::FileInfo*
GetFileInfo()
{
return nullptr;
}
virtual bool
IsShuttingDown();
NS_IMETHOD_(MozExternalRefCountType)
Release() = 0;
virtual bool
IsInvalid()
@ -89,7 +47,7 @@ public:
Storage() = 0;
virtual already_AddRefed<nsISupports>
CreateStream(nsIFile* aFile, bool aReadOnly);
CreateStream(bool aReadOnly);
virtual void
SetThreadLocals()
@ -101,50 +59,10 @@ public:
{
}
virtual already_AddRefed<nsIDOMFile>
CreateFileObject(FileHandle* aFileHandle, uint32_t aFileSize);
// nsWrapperCache
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
nsPIDOMWindow*
GetParentObject() const
{
return GetOwner();
}
void
GetName(nsString& aName) const
{
aName = mName;
}
void
GetType(nsString& aType) const
{
aType = mType;
}
already_AddRefed<FileHandle>
Open(FileMode aMode, ErrorResult& aError);
already_AddRefed<DOMRequest>
GetFile(ErrorResult& aError);
IMPL_EVENT_HANDLER(abort)
IMPL_EVENT_HANDLER(error)
protected:
MutableFile(nsPIDOMWindow* aWindow);
MutableFileBase();
MutableFile(DOMEventTargetHelper* aOwner);
virtual ~MutableFile();
nsString mName;
nsString mType;
virtual ~MutableFileBase();
nsCOMPtr<nsIFile> mFile;

View File

@ -4,20 +4,18 @@
# 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/.
TEST_DIRS += ['test']
EXPORTS.mozilla.dom += [
'File.h',
'AsyncHelper.h',
'FileHandle.h',
'FileHelper.h',
'FileRequest.h',
'FileService.h',
'MetadataHelper.h',
'MutableFile.h',
]
UNIFIED_SOURCES += [
'AsyncHelper.cpp',
'File.cpp',
'FileHandle.cpp',
'FileHelper.cpp',
'FileRequest.cpp',

View File

@ -1,205 +0,0 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const IndexedDatabaseKey = "IDB";
const DeviceStorageKey = "DS";
var fileStorages = [
{ key: IndexedDatabaseKey }
// { key: DeviceStorageKey }
];
var utils = SpecialPowers.getDOMWindowUtils(window);
var testGenerator = testSteps();
function runTest()
{
allowUnlimitedQuota();
SimpleTest.waitForExplicitFinish();
testGenerator.next();
}
function finishTest()
{
resetUnlimitedQuota();
SimpleTest.executeSoon(function() {
testGenerator.close();
SimpleTest.finish();
});
}
function grabEventAndContinueHandler(event)
{
testGenerator.send(event);
}
function continueToNextStep()
{
SimpleTest.executeSoon(function() {
testGenerator.next();
});
}
function errorHandler(event)
{
ok(false, "indexedDB error, code " + event.target.errorCode);
finishTest();
}
function unexpectedSuccessHandler()
{
ok(false, "Got success, but did not expect it!");
finishTest();
}
function ExpectError(name)
{
this._name = name;
}
ExpectError.prototype = {
handleEvent: function(event)
{
is(event.type, "error", "Got an error event");
is(event.target.error.name, this._name, "Expected error was thrown.");
event.preventDefault();
event.stopPropagation();
grabEventAndContinueHandler(event);
}
};
function addPermission(type, allow, url)
{
if (!url) {
url = window.document;
}
SpecialPowers.addPermission(type, allow, url);
}
function removePermission(type, url)
{
if (!url) {
url = window.document;
}
SpecialPowers.removePermission(type, url);
}
function allowUnlimitedQuota(url)
{
addPermission("indexedDB-unlimited", true, url);
}
function resetUnlimitedQuota(url)
{
removePermission("indexedDB-unlimited", url);
}
function getMutableFile(fileStorageKey, name)
{
var requestService = SpecialPowers.getDOMRequestService();
var request = requestService.createRequest(window);
switch (fileStorageKey) {
case IndexedDatabaseKey:
var dbname = window.location.pathname;
indexedDB.open(dbname, 1).onsuccess = function(event) {
var db = event.target.result;
db.createMutableFile(name).onsuccess = function(event) {
var fileHandle = event.target.result;
requestService.fireSuccess(request, fileHandle);
}
}
break;
case DeviceStorageKey:
var dbname = window.location.pathname;
indexedDB.open(dbname, 1).onsuccess = function(event) {
var db = event.target.result;
db.createMutableFile(name).onsuccess = function(event) {
var fileHandle = event.target.result;
requestService.fireSuccess(request, fileHandle);
}
}
break;
}
return request;
}
function getFileHandle(fileStorageKey, name)
{
var requestService = SpecialPowers.getDOMRequestService();
var request = requestService.createRequest(window);
switch (fileStorageKey) {
case IndexedDatabaseKey:
var dbname = window.location.pathname;
indexedDB.open(dbname, 1).onsuccess = function(event) {
var db = event.target.result;
db.mozCreateFileHandle(name).onsuccess = function(event) {
var fileHandle = event.target.result;
requestService.fireSuccess(request, fileHandle);
}
}
break;
case DeviceStorageKey:
var dbname = window.location.pathname;
indexedDB.open(dbname, 1).onsuccess = function(event) {
var db = event.target.result;
db.mozCreateFileHandle(name).onsuccess = function(event) {
var fileHandle = event.target.result;
requestService.fireSuccess(request, fileHandle);
}
}
break;
}
return request;
}
function getBuffer(size)
{
let buffer = new ArrayBuffer(size);
is(buffer.byteLength, size, "Correct byte length");
return buffer;
}
function getRandomBuffer(size)
{
let buffer = getBuffer(size);
let view = new Uint8Array(buffer);
for (let i = 0; i < size; i++) {
view[i] = parseInt(Math.random() * 255)
}
return buffer;
}
function compareBuffers(buffer1, buffer2)
{
if (buffer1.byteLength != buffer2.byteLength) {
return false;
}
let view1 = new Uint8Array(buffer1);
let view2 = new Uint8Array(buffer2);
for (let i = 0; i < buffer1.byteLength; i++) {
if (view1[i] != view2[i]) {
return false;
}
}
return true;
}
function getRandomBlob(size)
{
return new Blob([getRandomBuffer(size)], { type: "binary/random" });
}
function getFileId(blob)
{
return SpecialPowers.unwrap(utils.getFileId(blob));
}

View File

@ -1,39 +0,0 @@
[DEFAULT]
skip-if = e10s
support-files =
dummy_worker.js
helpers.js
[test_append_read_data.html]
skip-if = buildapp == 'b2g'
[test_compat.html]
skip-if = buildapp == 'b2g'
[test_filehandle_lifetimes.html]
skip-if = buildapp == 'b2g'
[test_filehandle_lifetimes_nested.html]
skip-if = buildapp == 'b2g'
[test_filehandle_ordering.html]
skip-if = buildapp == 'b2g'
[test_getFile.html]
skip-if = buildapp == 'b2g'
[test_getFileId.html]
[test_location.html]
skip-if = buildapp == 'b2g'
[test_overlapping_filehandles.html]
skip-if = buildapp == 'b2g'
[test_progress_events.html]
skip-if = buildapp == 'b2g' # b2g(All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:109) b2g-debug(All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:109) b2g-desktop(All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:109)
[test_readonly_filehandles.html]
skip-if = buildapp == 'b2g'
[test_request_readyState.html]
skip-if = buildapp == 'b2g'
[test_stream_tracking.html]
skip-if = buildapp == 'b2g'
[test_success_events_after_abort.html]
skip-if = buildapp == 'b2g'
[test_truncate.html]
skip-if = buildapp == 'b2g'
[test_workers.html]
skip-if = buildapp == 'b2g'
[test_write_read_data.html]
skip-if = buildapp == 'b2g'

View File

@ -1,8 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MOCHITEST_MANIFESTS += ['mochitest.ini']

View File

@ -1,101 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
var testString = "Lorem ipsum his ponderum delicatissimi ne, at noster dolores urbanitas pro, cibo elaboraret no his. Ea dicunt maiorum usu. Ad appareat facilisis mediocritatem eos. Tale graeci mentitum in eos, hinc insolens at nam. Graecis nominavi aliquyam eu vix. Id solet assentior sadipscing pro. Et per atqui graecis, usu quot viris repudiandae ei, mollis evertitur an nam. At nam dolor ignota, liber labore omnesque ea mei, has movet voluptaria in. Vel an impetus omittantur. Vim movet option salutandi ex, ne mei ignota corrumpit. Mucius comprehensam id per. Est ea putant maiestatis.";
for (let i = 0; i < 5; i++) {
testString += testString;
}
var testBuffer = getRandomBuffer(100000);
var testBlob = new Blob([testBuffer], {type: "binary/random"});
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let location = 0;
let fileHandle = mutableFile.open("readwrite");
is(fileHandle.location, location, "Correct location");
request = fileHandle.append(testString);
ok(fileHandle.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = 0;
request = fileHandle.readAsText(testString.length);
location += testString.length
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultString = event.target.result;
ok(resultString == testString, "Correct string data");
request = fileHandle.append(testBuffer);
ok(fileHandle.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = location;
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
location += testBuffer.byteLength;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
request = fileHandle.append(testBlob);
ok(fileHandle.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = location;
request = fileHandle.readAsArrayBuffer(testBlob.size);
location += testBlob.size;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct blob data");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let result = event.target.result;
is(result.size, location, "Correct size");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,41 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getFileHandle(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let fileHandle = event.target.result;
fileHandle.onerror = errorHandler;
let lockedFile = fileHandle.open();
ok(lockedFile.fileHandle === fileHandle, "Correct property");
request = lockedFile.getMetadata({ size: true });
ok(request.lockedFile === lockedFile, "Correct property");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,49 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open();
continueToNextStep();
yield undefined;
try {
fileHandle.getMetadata({ size: true });
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "FileHandleInactiveError", "Good error.");
is(e.code, 0, "Good error code.");
}
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,61 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open();
let fileHandle2;
let comp = SpecialPowers.wrap(SpecialPowers.Components);
let thread = comp.classes["@mozilla.org/thread-manager;1"]
.getService(comp.interfaces.nsIThreadManager)
.currentThread;
let eventHasRun;
thread.dispatch(function() {
eventHasRun = true;
fileHandle2 = mutableFile.open();
}, SpecialPowers.Ci.nsIThread.DISPATCH_NORMAL);
while (!eventHasRun) {
thread.processNextEvent(false);
}
ok(fileHandle2, "Non-null fileHandle2");
continueToNextStep();
yield undefined;
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,54 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle1 = mutableFile.open("readwrite");
let fileHandle2 = mutableFile.open("readwrite");
let request1 = fileHandle2.write("2");
let request2 = fileHandle1.write("1");
fileHandle1.oncomplete = grabEventAndContinueHandler;
fileHandle2.oncomplete = grabEventAndContinueHandler;
yield undefined;
yield undefined;
let fileHandle3 = mutableFile.open("readonly");
let request3 = fileHandle3.readAsText(1);
request3.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result, "2", "File handles were ordered properly.");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,45 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
request = mutableFile.getFile();
ok(request instanceof DOMRequest, "Correct interface");
ok(!(request instanceof FileRequest), "Correct interface");
ok(!('fileHandle' in request), "Property should not exist");
ok(request.fileHandle === undefined, "Property should not exist");
ok(!('lockedFile' in request), "Property should not exist");
ok(request.lockedFile === undefined, "Property should not exist");
ok(!('onprogress' in request), "Property should not exist");
ok(request.onprogress === undefined, "Property should not exist");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,96 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
is(fileHandle.location, 0, "Correct location");
fileHandle.location = 100000;
is(fileHandle.location, 100000, "Correct location");
fileHandle.location = null;
ok(fileHandle.location === null, "Correct location");
try {
fileHandle.readAsArrayBuffer(1);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
try {
fileHandle.readAsText(1);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
try {
fileHandle.write({});
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
request = fileHandle.append("foo");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
ok(fileHandle.location === null, "Correct location");
try {
fileHandle.truncate();
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
request = fileHandle.truncate(0);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, 0, "Correct location");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,65 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
for (let i = 0; i < 50; i++) {
let stepNumber = 0;
request = mutableFile.open("readwrite").append("string1");
request.onsuccess = function(event) {
is(stepNumber, 1, "This callback came first");
stepNumber++;
event.target.fileHandle.oncomplete = grabEventAndContinueHandler;
}
request = mutableFile.open("readwrite").append("string2");
request.onsuccess = function(event) {
is(stepNumber, 2, "This callback came second");
stepNumber++;
event.target.fileHandle.oncomplete = grabEventAndContinueHandler;
}
request = mutableFile.open("readwrite").append("string3");
request.onsuccess = function(event) {
is(stepNumber, 3, "This callback came third");
stepNumber++;
event.target.fileHandle.oncomplete = grabEventAndContinueHandler;
}
stepNumber++;
yield undefined; yield undefined; yield undefined;;
is(stepNumber, 4, "All callbacks received");
}
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,70 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
var testBuffer = getRandomBuffer(100000);
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
let sum = 0;
request = fileHandle.write(testBuffer);
request.onprogress = function(event) {
let loaded = event.loaded;
let total = event.total;
ok(loaded >= 0 && loaded <= total, "Correct loaded progress");
is(total, testBuffer.byteLength, "Correct total progress");
sum += event.loaded - sum;
}
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(sum, testBuffer.byteLength, "Correct loaded progress sum");
sum = 0;
fileHandle.location = 0;
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
request.onprogress = function(event) {
let loaded = event.loaded;
let total = event.total;
ok(loaded >= 0 && loaded <= total, "Correct loaded progress");
is(total, testBuffer.byteLength, "Correct total progress");
sum += event.loaded - sum;
}
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(sum, testBuffer.byteLength, "Correct loaded progress sum");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,73 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
request = mutableFile.open("readwrite").write({});
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.fileHandle.mode, "readwrite", "Correct mode");
try {
mutableFile.open().write({});
ok(false, "Writing to a readonly file handle should fail!");
}
catch (e) {
ok(true, "Writing to a readonly file handle failed");
}
try {
mutableFile.open().append({});
ok(false, "Appending to a readonly file handle should fail!");
}
catch (e) {
ok(true, "Appending to a readonly file handle failed");
}
try {
mutableFile.open().truncate({});
ok(false, "Truncating a readonly file handle should fail!");
}
catch (e) {
ok(true, "Truncating a readonly file handle failed");
}
try {
mutableFile.open().flush({});
ok(false, "Flushing a readonly file handle should fail!");
}
catch (e) {
ok(true, "Flushing a readonly file handle failed");
}
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,57 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
is(request.readyState, "pending", "Correct readyState");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(request.readyState, "done", "Correct readyState");
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write("string");
is(request.readyState, "pending", "Correct readyState");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(request.readyState, "done", "Correct readyState");
fileHandle.location = 0;
request = fileHandle.readAsText(6);
request.onsuccess = grabEventAndContinueHandler;
is(request.readyState, "pending", "Correct readyState");
event = yield undefined;
ok(event.target.result, "Got something");
is(request.readyState, "done", "Correct readyState");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,103 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
var testBuffer = getRandomBuffer(100000);
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
request = mutableFile.getFile();
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let file = event.target.result;
let resultBuffer1;
let resultBuffer2;
let reader1 = new FileReader();
reader1.readAsArrayBuffer(file);
reader1.onerror = errorHandler;
reader1.onload = function(event)
{
resultBuffer1 = event.target.result;
let reader = new FileReader();
try {
reader.readAsArrayBuffer(file);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "FileHandleInactiveError", "Good error.");
is(e.code, 0, "Good error code.");
}
if (resultBuffer2) {
testGenerator.next();
}
}
let reader2 = new FileReader();
reader2.readAsArrayBuffer(file);
reader2.onerror = errorHandler;
reader2.onload = function(event)
{
resultBuffer2 = event.target.result;
let reader = new FileReader();
try {
reader.readAsArrayBuffer(file);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "FileHandleInactiveError", "Good error.");
is(e.code, 0, "Good error code.");
}
if (resultBuffer1) {
testGenerator.next();
}
}
yield undefined;
ok(compareBuffers(resultBuffer1, testBuffer), "Correct data");
ok(compareBuffers(resultBuffer2, testBuffer), "Correct data");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,66 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open();
fileHandle.oncomplete = unexpectedSuccessHandler;
fileHandle.onabort = grabEventAndContinueHandler;
let sawError = false;
request = fileHandle.getMetadata({ size: true });
request.onsuccess = unexpectedSuccessHandler;
request.onerror = function(event) {
is(event.target.error.name, "AbortError", "Good error");
sawError = true;
event.stopPropagation();
}
fileHandle.abort();
event = yield undefined;
is(event.type, "abort", "Got abort event");
is(sawError, true, "Saw getMetadata() error");
// Make sure the success event isn't queued somehow.
let comp = SpecialPowers.wrap(SpecialPowers.Components);
var thread = comp.classes["@mozilla.org/thread-manager;1"]
.getService(comp.interfaces.nsIThreadManager)
.currentThread;
while (thread.hasPendingEvents()) {
thread.processNextEvent(false);
}
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,82 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
var testBuffer = getRandomBuffer(100000);
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.bin");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, 100000, "Correct location");
for (let i = 0; i < 10; i++) {
let location = fileHandle.location - 10000;
fileHandle.location = location;
request = fileHandle.truncate();
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, location, "Correct location");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result.size, location, "Correct size");
}
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let location = fileHandle.location;
for (let i = 0; i < 10; i++) {
location -= 10000;
request = fileHandle.truncate(location);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, location, "Correct location");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result.size, location, "Correct size");
}
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,61 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript;version=1.7">
function testSteps()
{
var testBuffer = getRandomBuffer(100000);
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
request = mutableFile.getFile();
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let file = event.target.result;
var worker = new Worker("dummy_worker.js");
try {
worker.postMessage(file);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "DataCloneError", "Good error.");
is(e.code, DOMException.DATA_CLONE_ERR, "Good error code.")
}
worker.terminate();
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -1,101 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
var testString = "Lorem ipsum his ponderum delicatissimi ne, at noster dolores urbanitas pro, cibo elaboraret no his. Ea dicunt maiorum usu. Ad appareat facilisis mediocritatem eos. Tale graeci mentitum in eos, hinc insolens at nam. Graecis nominavi aliquyam eu vix. Id solet assentior sadipscing pro. Et per atqui graecis, usu quot viris repudiandae ei, mollis evertitur an nam. At nam dolor ignota, liber labore omnesque ea mei, has movet voluptaria in. Vel an impetus omittantur. Vim movet option salutandi ex, ne mei ignota corrumpit. Mucius comprehensam id per. Est ea putant maiestatis.";
for (let i = 0; i < 5; i++) {
testString += testString;
}
var testBuffer = getRandomBuffer(100000);
var testBlob = new Blob([testBuffer], {type: "binary/random"});
for each (let fileStorage in fileStorages) {
let request = getMutableFile(fileStorage.key, "test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let location = 0;
let fileHandle = mutableFile.open("readwrite");
is(fileHandle.location, location, "Correct location");
request = fileHandle.write(testString);
location += testString.length;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = 0;
request = fileHandle.readAsText(testString.length);
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultString = event.target.result;
ok(resultString == testString, "Correct string data");
request = fileHandle.write(testBuffer);
location += testBuffer.byteLength;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location -= testBuffer.byteLength;
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
request = fileHandle.write(testBlob);
location += testBlob.size;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location -= testBlob.size;
request = fileHandle.readAsArrayBuffer(testBlob.size);
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct blob data");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let result = event.target.result;
is(result.size, location, "Correct size");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,109 @@
/* -*- 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 "FileSnapshot.h"
#include "IDBFileHandle.h"
#include "mozilla/Assertions.h"
#include "nsDebug.h"
namespace mozilla {
namespace dom {
namespace indexedDB {
NS_IMPL_ISUPPORTS_INHERITED0(FileImplSnapshot, DOMFileImpl)
// Create as a stored file
FileImplSnapshot::FileImplSnapshot(const nsAString& aName,
const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile,
IDBFileHandle* aFileHandle,
FileInfo* aFileInfo)
: DOMFileImplBase(aName, aContentType, aLength),
mFile(aFile), mFileHandle(aFileHandle), mWholeFile(true)
{
MOZ_ASSERT(mFile, "Null file!");
MOZ_ASSERT(mFileHandle, "Null file handle!");
mFileInfos.AppendElement(aFileInfo);
}
// Create slice
FileImplSnapshot::FileImplSnapshot(const FileImplSnapshot* aOther,
uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
: DOMFileImplBase(aContentType, aOther->mStart + aStart, aLength),
mFile(aOther->mFile), mFileHandle(aOther->mFileHandle),
mWholeFile(false)
{
MOZ_ASSERT(mFile, "Null file!");
MOZ_ASSERT(mFileHandle, "Null file handle!");
FileInfo* fileInfo;
if (IndexedDatabaseManager::IsClosed()) {
fileInfo = aOther->GetFileInfo();
} else {
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
fileInfo = aOther->GetFileInfo();
}
mFileInfos.AppendElement(fileInfo);
}
FileImplSnapshot::~FileImplSnapshot()
{
}
void
FileImplSnapshot::Unlink()
{
FileImplSnapshot* tmp = this;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileHandle);
}
void
FileImplSnapshot::Traverse(nsCycleCollectionTraversalCallback &cb)
{
FileImplSnapshot* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileHandle);
}
nsresult
FileImplSnapshot::GetInternalStream(nsIInputStream** aStream)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = mFileHandle->OpenInputStream(mWholeFile, mStart, mLength,
aStream);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
already_AddRefed<nsIDOMBlob>
FileImplSnapshot::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIDOMBlob> t =
new DOMFile(new FileImplSnapshot(this, aStart, aLength, aContentType));
return t.forget();
}
nsresult
FileImplSnapshot::GetMozFullPathInternal(nsAString& aFilename)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(mIsFile, "Should only be called on files");
return mFile->GetPath(aFilename);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla

View File

@ -4,8 +4,8 @@
* 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_File_h
#define mozilla_dom_File_h
#ifndef mozilla_dom_indexeddb_filesnapshot_h__
#define mozilla_dom_indexeddb_filesnapshot_h__
#include "mozilla/Attributes.h"
#include "nsAutoPtr.h"
@ -15,45 +15,45 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
class FileHandle;
class File;
class IDBFileHandle;
class FileImpl : public DOMFileImplBase
class FileImplSnapshot : public DOMFileImplBase
{
friend class File;
public:
NS_DECL_ISUPPORTS_INHERITED
// Create as a file
FileImpl(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle);
// Create as a stored file
FileImpl(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle,
indexedDB::FileInfo* aFileInfo);
FileImplSnapshot(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, IDBFileHandle* aFileHandle,
FileInfo* aFileInfo);
// Overrides
virtual nsresult GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
virtual nsresult
GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual nsresult
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual void Unlink() MOZ_OVERRIDE;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual void
Unlink() MOZ_OVERRIDE;
virtual bool IsCCed() const MOZ_OVERRIDE
virtual void
Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool
IsCCed() const MOZ_OVERRIDE
{
return true;
}
protected:
// Create slice
FileImpl(const FileImpl* aOther, uint64_t aStart, uint64_t aLength,
const nsAString& aContentType);
FileImplSnapshot(const FileImplSnapshot* aOther, uint64_t aStart,
uint64_t aLength, const nsAString& aContentType);
virtual ~FileImpl();
virtual ~FileImplSnapshot();
virtual already_AddRefed<nsIDOMBlob>
CreateSlice(uint64_t aStart, uint64_t aLength,
@ -62,7 +62,7 @@ protected:
virtual bool
IsStoredFile() const MOZ_OVERRIDE
{
return mStoredFile;
return true;
}
virtual bool
@ -79,13 +79,13 @@ protected:
private:
nsCOMPtr<nsIFile> mFile;
nsRefPtr<FileHandle> mFileHandle;
nsRefPtr<IDBFileHandle> mFileHandle;
bool mWholeFile;
bool mStoredFile;
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_File_h
#endif // mozilla_dom_indexeddb_filesnapshot_h__

View File

@ -0,0 +1,196 @@
/* -*- 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 "IDBFileHandle.h"
#include "IDBEvents.h"
#include "IDBMutableFile.h"
#include "mozilla/dom/FileService.h"
#include "mozilla/dom/IDBFileHandleBinding.h"
#include "mozilla/dom/MetadataHelper.h"
#include "mozilla/EventDispatcher.h"
#include "nsIAppShell.h"
#include "nsServiceManagerUtils.h"
#include "nsWidgetsCID.h"
namespace {
NS_DEFINE_CID(kAppShellCID2, NS_APPSHELL_CID);
} // anonymous namespace
namespace mozilla {
namespace dom {
namespace indexedDB {
IDBFileHandle::IDBFileHandle(FileMode aMode,
RequestMode aRequestMode,
IDBMutableFile* aMutableFile)
: FileHandleBase(aMode, aRequestMode)
, mMutableFile(aMutableFile)
{
SetIsDOMBinding();
}
IDBFileHandle::~IDBFileHandle()
{
}
// static
already_AddRefed<IDBFileHandle>
IDBFileHandle::Create(FileMode aMode,
RequestMode aRequestMode,
IDBMutableFile* aMutableFile)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
nsRefPtr<IDBFileHandle> fileHandle =
new IDBFileHandle(aMode, aRequestMode, aMutableFile);
fileHandle->BindToOwner(aMutableFile);
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID2);
if (NS_WARN_IF(!appShell)) {
return nullptr;
}
nsresult rv = appShell->RunBeforeNextEvent(fileHandle);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
fileHandle->SetCreating();
FileService* service = FileService::GetOrCreate();
if (NS_WARN_IF(!service)) {
return nullptr;
}
rv = service->Enqueue(fileHandle, nullptr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return fileHandle.forget();
}
mozilla::dom::MutableFileBase*
IDBFileHandle::MutableFile() const
{
return mMutableFile;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBFileHandle, DOMEventTargetHelper,
mMutableFile)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBFileHandle)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(IDBFileHandle, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(IDBFileHandle, DOMEventTargetHelper)
nsresult
IDBFileHandle::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
aVisitor.mCanHandle = true;
aVisitor.mParentTarget = mMutableFile;
return NS_OK;
}
// virtual
JSObject*
IDBFileHandle::WrapObject(JSContext* aCx)
{
return IDBFileHandleBinding::Wrap(aCx, this);
}
already_AddRefed<IDBFileRequest>
IDBFileHandle::GetMetadata(const IDBFileMetadataParameters& aParameters,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
// Common state checking
if (!CheckState(aRv)) {
return nullptr;
}
// Do nothing if the window is closed
if (!CheckWindow()) {
return nullptr;
}
nsRefPtr<MetadataParameters> params =
new MetadataParameters(aParameters.mSize, aParameters.mLastModified);
if (!params->IsConfigured()) {
aRv.ThrowTypeError(MSG_METADATA_NOT_CONFIGURED);
return nullptr;
}
nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<MetadataHelper> helper =
new MetadataHelper(this, fileRequest, params);
if (NS_WARN_IF(NS_FAILED(helper->Enqueue()))) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
return fileRequest.forget().downcast<IDBFileRequest>();
}
NS_IMETHODIMP
IDBFileHandle::Run()
{
OnReturnToEventLoop();
return NS_OK;
}
nsresult
IDBFileHandle::OnCompleteOrAbort(bool aAborted)
{
nsCOMPtr<nsIDOMEvent> event;
if (aAborted) {
event = CreateGenericEvent(this, NS_LITERAL_STRING(ABORT_EVT_STR),
eDoesBubble, eNotCancelable);
} else {
event = CreateGenericEvent(this, NS_LITERAL_STRING(COMPLETE_EVT_STR),
eDoesNotBubble, eNotCancelable);
}
if (NS_WARN_IF(!event)) {
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
}
bool dummy;
if (NS_FAILED(DispatchEvent(event, &dummy))) {
NS_WARNING("Dispatch failed!");
}
return NS_OK;
}
bool
IDBFileHandle::CheckWindow()
{
return GetOwner();
}
already_AddRefed<mozilla::dom::FileRequestBase>
IDBFileHandle::GenerateFileRequest()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return IDBFileRequest::Create(GetOwner(), this,
/* aWrapAsDOMRequest */ false);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,145 @@
/* -*- 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/. */
#ifndef mozilla_dom_indexeddb_idbfilehandle_h__
#define mozilla_dom_indexeddb_idbfilehandle_h__
#include "IDBFileRequest.h"
#include "js/TypeDecls.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/FileHandle.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCycleCollectionParticipant.h"
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
struct IDBFileMetadataParameters;
namespace indexedDB {
class IDBMutableFile;
class IDBFileHandle MOZ_FINAL : public DOMEventTargetHelper,
public nsIRunnable,
public FileHandleBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIRUNNABLE
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBFileHandle, DOMEventTargetHelper)
static already_AddRefed<IDBFileHandle>
Create(FileMode aMode,
RequestMode aRequestMode,
IDBMutableFile* aMutableFile);
virtual MutableFileBase*
MutableFile() const MOZ_OVERRIDE;
// nsIDOMEventTarget
virtual nsresult
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
// WrapperCache
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
nsPIDOMWindow*
GetParentObject() const
{
return GetOwner();
}
IDBMutableFile*
GetMutableFile() const
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return mMutableFile;
}
IDBMutableFile*
GetFileHandle() const
{
return GetMutableFile();
}
already_AddRefed<IDBFileRequest>
GetMetadata(const IDBFileMetadataParameters& aParameters, ErrorResult& aRv);
already_AddRefed<IDBFileRequest>
ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
{
return Read(aSize, false, NullString(), aRv).downcast<IDBFileRequest>();
}
already_AddRefed<IDBFileRequest>
ReadAsText(uint64_t aSize, const nsAString& aEncoding, ErrorResult& aRv)
{
return Read(aSize, true, aEncoding, aRv).downcast<IDBFileRequest>();
}
template<class T>
already_AddRefed<IDBFileRequest>
Write(const T& aValue, ErrorResult& aRv)
{
return
WriteOrAppend(aValue, false, aRv).template downcast<IDBFileRequest>();
}
template<class T>
already_AddRefed<IDBFileRequest>
Append(const T& aValue, ErrorResult& aRv)
{
return WriteOrAppend(aValue, true, aRv).template downcast<IDBFileRequest>();
}
already_AddRefed<IDBFileRequest>
Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
{
return FileHandleBase::Truncate(aSize, aRv).downcast<IDBFileRequest>();
}
already_AddRefed<IDBFileRequest>
Flush(ErrorResult& aRv)
{
return FileHandleBase::Flush(aRv).downcast<IDBFileRequest>();
}
IMPL_EVENT_HANDLER(complete)
IMPL_EVENT_HANDLER(abort)
IMPL_EVENT_HANDLER(error)
private:
IDBFileHandle(FileMode aMode,
RequestMode aRequestMode,
IDBMutableFile* aMutableFile);
~IDBFileHandle();
virtual nsresult
OnCompleteOrAbort(bool aAborted) MOZ_OVERRIDE;
virtual bool
CheckWindow() MOZ_OVERRIDE;
virtual already_AddRefed<FileRequestBase>
GenerateFileRequest() MOZ_OVERRIDE;
nsRefPtr<IDBMutableFile> mMutableFile;
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbfilehandle_h__

View File

@ -0,0 +1,159 @@
/* -*- 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 "IDBFileRequest.h"
#include "IDBFileHandle.h"
#include "js/RootingAPI.h"
#include "jsapi.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/FileHelper.h"
#include "mozilla/dom/IDBFileRequestBinding.h"
#include "mozilla/dom/ProgressEvent.h"
#include "mozilla/EventDispatcher.h"
#include "nsCOMPtr.h"
#include "nsCxPusher.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsIDOMEvent.h"
#include "nsIScriptContext.h"
#include "nsLiteralString.h"
namespace mozilla {
namespace dom {
namespace indexedDB {
IDBFileRequest::IDBFileRequest(nsPIDOMWindow* aWindow)
: DOMRequest(aWindow), mWrapAsDOMRequest(false)
{
}
IDBFileRequest::~IDBFileRequest()
{
}
// static
already_AddRefed<IDBFileRequest>
IDBFileRequest::Create(nsPIDOMWindow* aOwner, IDBFileHandle* aFileHandle,
bool aWrapAsDOMRequest)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
nsRefPtr<IDBFileRequest> request = new IDBFileRequest(aOwner);
request->mFileHandle = aFileHandle;
request->mWrapAsDOMRequest = aWrapAsDOMRequest;
return request.forget();
}
nsresult
IDBFileRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
aVisitor.mCanHandle = true;
aVisitor.mParentTarget = mFileHandle;
return NS_OK;
}
void
IDBFileRequest::OnProgress(uint64_t aProgress, uint64_t aProgressMax)
{
FireProgressEvent(aProgress, aProgressMax);
}
nsresult
IDBFileRequest::NotifyHelperCompleted(FileHelper* aFileHelper)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
nsresult rv = aFileHelper->ResultCode();
// If the request failed then fire error event and return.
if (NS_FAILED(rv)) {
FireError(rv);
return NS_OK;
}
// Otherwise we need to get the result from the helper.
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_STATE(sc);
AutoJSContext cx;
MOZ_ASSERT(cx, "Failed to get a context!");
JS::Rooted<JS::Value> result(cx);
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
MOZ_ASSERT(global, "Failed to get global object!");
JSAutoCompartment ac(cx, global);
rv = aFileHelper->GetSuccessResult(cx, &result);
if (NS_FAILED(rv)) {
NS_WARNING("GetSuccessResult failed!");
}
if (NS_SUCCEEDED(rv)) {
FireSuccess(result);
}
else {
FireError(rv);
}
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBFileRequest, DOMRequest,
mFileHandle)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBFileRequest)
NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
NS_IMPL_ADDREF_INHERITED(IDBFileRequest, DOMRequest)
NS_IMPL_RELEASE_INHERITED(IDBFileRequest, DOMRequest)
// virtual
JSObject*
IDBFileRequest::WrapObject(JSContext* aCx)
{
if (mWrapAsDOMRequest) {
return DOMRequest::WrapObject(aCx);
}
return IDBFileRequestBinding::Wrap(aCx, this);
}
IDBFileHandle*
IDBFileRequest::GetFileHandle() const
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return static_cast<IDBFileHandle*>(mFileHandle.get());
}
void
IDBFileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
{
if (NS_FAILED(CheckInnerWindowCorrectness())) {
return;
}
ProgressEventInit init;
init.mBubbles = false;
init.mCancelable = false;
init.mLengthComputable = false;
init.mLoaded = aLoaded;
init.mTotal = aTotal;
nsRefPtr<ProgressEvent> event =
ProgressEvent::Constructor(this, NS_LITERAL_STRING("progress"), init);
DispatchTrustedEvent(event);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,83 @@
/* -*- 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/. */
#ifndef mozilla_dom_indexeddb_idbfilerequest_h__
#define mozilla_dom_indexeddb_idbfilerequest_h__
#include "DOMRequest.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/FileRequest.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
class nsPIDOMWindow;
namespace mozilla {
class EventChainPreVisitor;
namespace dom {
namespace indexedDB {
class IDBFileHandle;
class IDBFileRequest MOZ_FINAL : public DOMRequest,
public FileRequestBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBFileRequest, DOMRequest)
static already_AddRefed<IDBFileRequest>
Create(nsPIDOMWindow* aOwner, IDBFileHandle* aFileHandle,
bool aWrapAsDOMRequest);
// nsIDOMEventTarget
virtual nsresult
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
// FileRequest
virtual void
OnProgress(uint64_t aProgress, uint64_t aProgressMax) MOZ_OVERRIDE;
virtual nsresult
NotifyHelperCompleted(FileHelper* aFileHelper) MOZ_OVERRIDE;
// nsWrapperCache
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
IDBFileHandle*
GetFileHandle() const;
IDBFileHandle*
GetLockedFile() const
{
return GetFileHandle();
}
IMPL_EVENT_HANDLER(progress)
private:
IDBFileRequest(nsPIDOMWindow* aWindow);
~IDBFileRequest();
void
FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
nsRefPtr<IDBFileHandle> mFileHandle;
bool mWrapAsDOMRequest;
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbfilerequest_h__

View File

@ -6,18 +6,56 @@
#include "IDBMutableFile.h"
#include "mozilla/dom/File.h"
#include "nsIDOMFile.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/FileService.h"
#include "mozilla/dom/IDBMutableFileBinding.h"
#include "mozilla/dom/MetadataHelper.h"
#include "mozilla/dom/quota/FileStreams.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsError.h"
#include "FileSnapshot.h"
#include "IDBDatabase.h"
#include "IDBFileHandle.h"
#include "IDBFileRequest.h"
using namespace mozilla::dom;
USING_INDEXEDDB_NAMESPACE
USING_QUOTA_NAMESPACE
namespace {
class GetFileHelper : public MetadataHelper
{
public:
GetFileHelper(FileHandleBase* aFileHandle,
FileRequestBase* aFileRequest,
MetadataParameters* aParams,
IDBMutableFile* aMutableFile)
: MetadataHelper(aFileHandle, aFileRequest, aParams),
mMutableFile(aMutableFile)
{ }
virtual nsresult
GetSuccessResult(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
virtual void
ReleaseObjects() MOZ_OVERRIDE
{
mMutableFile = nullptr;
MetadataHelper::ReleaseObjects();
}
private:
nsRefPtr<IDBMutableFile> mMutableFile;
};
inline
already_AddRefed<nsIFile>
GetFileFor(FileInfo* aFileInfo)
@ -36,18 +74,27 @@ GetFileFor(FileInfo* aFileInfo)
} // anonymous namespace
namespace mozilla {
namespace dom {
namespace indexedDB {
IDBMutableFile::IDBMutableFile(IDBDatabase* aOwner)
: MutableFile(aOwner)
: DOMEventTargetHelper(aOwner)
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBMutableFile, MutableFile, mDatabase)
IDBMutableFile::~IDBMutableFile()
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBMutableFile, DOMEventTargetHelper,
mDatabase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBMutableFile)
NS_INTERFACE_MAP_END_INHERITING(MutableFile)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(IDBMutableFile, MutableFile)
NS_IMPL_RELEASE_INHERITED(IDBMutableFile, MutableFile)
NS_IMPL_ADDREF_INHERITED(IDBMutableFile, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(IDBMutableFile, DOMEventTargetHelper)
// static
already_AddRefed<IDBMutableFile>
@ -78,12 +125,6 @@ IDBMutableFile::Create(const nsAString& aName,
return newFile.forget();
}
bool
IDBMutableFile::IsShuttingDown()
{
return QuotaManager::IsShuttingDown() || MutableFile::IsShuttingDown();
}
bool
IDBMutableFile::IsInvalid()
{
@ -97,7 +138,7 @@ IDBMutableFile::Storage()
}
already_AddRefed<nsISupports>
IDBMutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
IDBMutableFile::CreateStream(bool aReadOnly)
{
PersistenceType persistenceType = mDatabase->Type();
const nsACString& group = mDatabase->Group();
@ -107,13 +148,13 @@ IDBMutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
if (aReadOnly) {
nsRefPtr<FileInputStream> stream =
FileInputStream::Create(persistenceType, group, origin, aFile, -1, -1,
FileInputStream::Create(persistenceType, group, origin, mFile, -1, -1,
nsIFileInputStream::DEFER_OPEN);
result = NS_ISUPPORTS_CAST(nsIFileInputStream*, stream);
}
else {
nsRefPtr<FileStream> stream =
FileStream::Create(persistenceType, group, origin, aFile, -1, -1,
FileStream::Create(persistenceType, group, origin, mFile, -1, -1,
nsIFileStream::DEFER_OPEN);
result = NS_ISUPPORTS_CAST(nsIFileStream*, stream);
}
@ -136,13 +177,13 @@ IDBMutableFile::UnsetThreadLocals()
}
already_AddRefed<nsIDOMFile>
IDBMutableFile::CreateFileObject(mozilla::dom::FileHandle* aFileHandle,
uint32_t aFileSize)
IDBMutableFile::CreateFileObject(IDBFileHandle* aFileHandle, uint32_t aFileSize)
{
nsCOMPtr<nsIDOMFile> file = new DOMFile(
new FileImpl(mName, mType, aFileSize, mFile, aFileHandle, mFileInfo));
nsCOMPtr<nsIDOMFile> fileSnapshot = new DOMFile(
new FileImplSnapshot(mName, mType, aFileSize, mFile, aFileHandle,
mFileInfo));
return file.forget();
return fileSnapshot.forget();
}
// virtual
@ -151,3 +192,78 @@ IDBMutableFile::WrapObject(JSContext* aCx)
{
return IDBMutableFileBinding::Wrap(aCx, this);
}
already_AddRefed<IDBFileHandle>
IDBMutableFile::Open(FileMode aMode, ErrorResult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
if (QuotaManager::IsShuttingDown() || FileService::IsShuttingDown()) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
nsRefPtr<IDBFileHandle> fileHandle =
IDBFileHandle::Create(aMode, FileHandleBase::NORMAL, this);
if (!fileHandle) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
return fileHandle.forget();
}
already_AddRefed<DOMRequest>
IDBMutableFile::GetFile(ErrorResult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
// Do nothing if the window is closed
if (!GetOwner()) {
return nullptr;
}
nsRefPtr<IDBFileHandle> fileHandle =
IDBFileHandle::Create(FileMode::Readonly, FileHandleBase::PARALLEL, this);
nsRefPtr<IDBFileRequest> request =
IDBFileRequest::Create(GetOwner(), fileHandle, /* aWrapAsDOMRequest */
true);
nsRefPtr<MetadataParameters> params = new MetadataParameters(true, false);
nsRefPtr<GetFileHelper> helper =
new GetFileHelper(fileHandle, request, params, this);
nsresult rv = helper->Enqueue();
if (NS_FAILED(rv)) {
aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;
}
return request.forget();
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
nsresult
GetFileHelper::GetSuccessResult(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal)
{
MOZ_ASSERT(NS_IsMainThread());
auto fileHandle = static_cast<IDBFileHandle*>(mFileHandle.get());
nsCOMPtr<nsIDOMFile> domFile =
mMutableFile->CreateFileObject(fileHandle, mParams->Size());
nsresult rv =
nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile), aVal);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
}
return NS_OK;
}

View File

@ -7,48 +7,69 @@
#ifndef mozilla_dom_indexeddb_idbmutablefile_h__
#define mozilla_dom_indexeddb_idbmutablefile_h__
#include "IndexedDatabase.h"
#include "js/TypeDecls.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/FileModeBinding.h"
#include "mozilla/dom/indexedDB/FileInfo.h"
#include "mozilla/dom/MutableFile.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
BEGIN_INDEXEDDB_NAMESPACE
class nsIDOMFile;
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
namespace dom {
class DOMRequest;
namespace indexedDB {
class IDBDatabase;
class IDBFileHandle;
class IDBMutableFile : public MutableFile
class IDBMutableFile MOZ_FINAL : public DOMEventTargetHelper,
public MutableFileBase
{
typedef mozilla::dom::FileHandle FileHandle;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBMutableFile, MutableFile)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBMutableFile, DOMEventTargetHelper)
static already_AddRefed<IDBMutableFile>
Create(const nsAString& aName, const nsAString& aType,
IDBDatabase* aDatabase, already_AddRefed<FileInfo> aFileInfo);
const nsAString&
Name() const
{
return mName;
}
virtual int64_t
GetFileId() MOZ_OVERRIDE
const nsAString&
Type() const
{
return mType;
}
int64_t
GetFileId() const
{
return mFileInfo->Id();
}
virtual FileInfo*
GetFileInfo() MOZ_OVERRIDE
FileInfo*
GetFileInfo() const
{
return mFileInfo;
}
virtual bool
IsShuttingDown() MOZ_OVERRIDE;
virtual bool
IsInvalid() MOZ_OVERRIDE;
@ -56,7 +77,7 @@ public:
Storage() MOZ_OVERRIDE;
virtual already_AddRefed<nsISupports>
CreateStream(nsIFile* aFile, bool aReadOnly) MOZ_OVERRIDE;
CreateStream(bool aReadOnly) MOZ_OVERRIDE;
virtual void
SetThreadLocals() MOZ_OVERRIDE;
@ -64,14 +85,32 @@ public:
virtual void
UnsetThreadLocals() MOZ_OVERRIDE;
virtual already_AddRefed<nsIDOMFile>
CreateFileObject(FileHandle* aFileHandle, uint32_t aFileSize) MOZ_OVERRIDE;
already_AddRefed<nsIDOMFile>
CreateFileObject(IDBFileHandle* aFileHandle, uint32_t aFileSize);
// nsWrapperCache
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
nsPIDOMWindow*
GetParentObject() const
{
return GetOwner();
}
void
GetName(nsString& aName) const
{
aName = mName;
}
void
GetType(nsString& aType) const
{
aType = mType;
}
IDBDatabase*
Database()
{
@ -80,17 +119,28 @@ public:
return mDatabase;
}
already_AddRefed<IDBFileHandle>
Open(FileMode aMode, ErrorResult& aError);
already_AddRefed<DOMRequest>
GetFile(ErrorResult& aError);
IMPL_EVENT_HANDLER(abort)
IMPL_EVENT_HANDLER(error)
private:
IDBMutableFile(IDBDatabase* aOwner);
~IDBMutableFile();
~IDBMutableFile()
{
}
nsString mName;
nsString mType;
nsRefPtr<IDBDatabase> mDatabase;
nsRefPtr<FileInfo> mFileInfo;
};
END_INDEXEDDB_NAMESPACE
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbmutablefile_h__

View File

@ -14,8 +14,8 @@
#include <algorithm>
#include "jsfriendapi.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/IDBMutableFileBinding.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/MutableFileBinding.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/Blob.h"
@ -1573,13 +1573,13 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
IDBTransaction* transaction = cloneWriteInfo->mTransaction;
FileManager* fileManager = transaction->Database()->Manager();
MutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(MutableFile, aObj, mutableFile))) {
IDBMutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, aObj, mutableFile))) {
nsRefPtr<FileInfo> fileInfo = mutableFile->GetFileInfo();
MOZ_ASSERT(fileInfo);
// Throw when trying to store non IDB mutable files or IDB mutable files
// across databases.
if (!fileInfo || fileInfo->Manager() != fileManager) {
// Throw when trying to store mutable files across databases.
if (fileInfo->Manager() != fileManager) {
return false;
}

View File

@ -12,10 +12,13 @@ EXPORTS.mozilla.dom.indexedDB += [
'DatabaseInfo.h',
'FileInfo.h',
'FileManager.h',
'FileSnapshot.h',
'IDBCursor.h',
'IDBDatabase.h',
'IDBEvents.h',
'IDBFactory.h',
'IDBFileHandle.h',
'IDBFileRequest.h',
'IDBIndex.h',
'IDBKeyRange.h',
'IDBMutableFile.h',
@ -36,9 +39,12 @@ UNIFIED_SOURCES += [
'DatabaseInfo.cpp',
'FileInfo.cpp',
'FileManager.cpp',
'FileSnapshot.cpp',
'IDBDatabase.cpp',
'IDBEvents.cpp',
'IDBFactory.cpp',
'IDBFileHandle.cpp',
'IDBFileRequest.cpp',
'IDBKeyRange.cpp',
'IDBMutableFile.cpp',
'IDBRequest.cpp',

View File

@ -15,6 +15,23 @@ if (!SpecialPowers.isMainProcess()) {
}
}
function getBuffer(size)
{
let buffer = new ArrayBuffer(size);
is(buffer.byteLength, size, "Correct byte length");
return buffer;
}
function getRandomBuffer(size)
{
let buffer = getBuffer(size);
let view = new Uint8Array(buffer);
for (let i = 0; i < size; i++) {
view[i] = parseInt(Math.random() * 255)
}
return buffer;
}
function getView(size)
{
let buffer = new ArrayBuffer(size);

View File

@ -3,6 +3,7 @@ support-files =
bfcache_iframe1.html
bfcache_iframe2.html
blob_worker_crash_iframe.html
dummy_worker.js
error_events_abort_transactions_iframe.html
event_propagation_iframe.html
exceptions_in_events_iframe.html
@ -93,14 +94,47 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_file_transaction_abort.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_filehandle_append_read_data.html]
skip-if = buildapp == 'b2g'
[test_filehandle_compat.html]
skip-if = buildapp == 'b2g'
[test_filehandle_getFile.html]
skip-if = buildapp == 'b2g'
[test_filehandle_lifetimes.html]
skip-if = buildapp == 'b2g'
[test_filehandle_lifetimes_nested.html]
skip-if = buildapp == 'b2g'
[test_filehandle_location.html]
skip-if = buildapp == 'b2g'
[test_filehandle_ordering.html]
skip-if = buildapp == 'b2g'
[test_filehandle_overlapping.html]
skip-if = buildapp == 'b2g'
[test_filehandle_progress_events.html]
skip-if = buildapp == 'b2g' # b2g(All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:109) b2g-debug(All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:109) b2g-desktop(All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:109)
[test_filehandle_quota.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_filehandle_readonly_exceptions.html]
skip-if = buildapp == 'b2g'
[test_filehandle_request_readyState.html]
skip-if = buildapp == 'b2g'
[test_filehandle_serialization.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_filehandle_store_snapshot.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_filehandle_stream_tracking.html]
skip-if = buildapp == 'b2g'
[test_filehandle_success_events_after_abort.html]
skip-if = buildapp == 'b2g'
[test_filehandle_truncate.html]
skip-if = buildapp == 'b2g'
[test_filehandle_workers.html]
skip-if = buildapp == 'b2g'
[test_filehandle_write_read_data.html]
skip-if = buildapp == 'b2g'
[test_getAll.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_getFileId.html]
[test_get_filehandle.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_globalObjects_content.html]

View File

@ -0,0 +1,110 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
var testString = "Lorem ipsum his ponderum delicatissimi ne, at noster dolores urbanitas pro, cibo elaboraret no his. Ea dicunt maiorum usu. Ad appareat facilisis mediocritatem eos. Tale graeci mentitum in eos, hinc insolens at nam. Graecis nominavi aliquyam eu vix. Id solet assentior sadipscing pro. Et per atqui graecis, usu quot viris repudiandae ei, mollis evertitur an nam. At nam dolor ignota, liber labore omnesque ea mei, has movet voluptaria in. Vel an impetus omittantur. Vim movet option salutandi ex, ne mei ignota corrumpit. Mucius comprehensam id per. Est ea putant maiestatis.";
for (let i = 0; i < 5; i++) {
testString += testString;
}
var testBuffer = getRandomBuffer(100000);
var testBlob = new Blob([testBuffer], {type: "binary/random"});
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let location = 0;
let fileHandle = mutableFile.open("readwrite");
is(fileHandle.location, location, "Correct location");
request = fileHandle.append(testString);
ok(fileHandle.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = 0;
request = fileHandle.readAsText(testString.length);
location += testString.length
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultString = event.target.result;
ok(resultString == testString, "Correct string data");
request = fileHandle.append(testBuffer);
ok(fileHandle.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = location;
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
location += testBuffer.byteLength;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
request = fileHandle.append(testBlob);
ok(fileHandle.location === null, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = location;
request = fileHandle.readAsArrayBuffer(testBlob.size);
location += testBlob.size;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct blob data");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let result = event.target.result;
is(result.size, location, "Correct size");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,50 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.mozCreateFileHandle("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let fileHandle = event.target.result;
fileHandle.onerror = errorHandler;
let lockedFile = fileHandle.open();
ok(lockedFile.fileHandle === fileHandle, "Correct property");
request = lockedFile.getMetadata({ size: true });
ok(request.lockedFile === lockedFile, "Correct property");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,54 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
request = mutableFile.getFile();
ok(request instanceof DOMRequest, "Correct interface");
ok(!(request instanceof IDBFileRequest), "Correct interface");
ok(!('fileHandle' in request), "Property should not exist");
ok(request.fileHandle === undefined, "Property should not exist");
ok(!('lockedFile' in request), "Property should not exist");
ok(request.lockedFile === undefined, "Property should not exist");
ok(!('onprogress' in request), "Property should not exist");
ok(request.onprogress === undefined, "Property should not exist");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,58 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open();
continueToNextStep();
yield undefined;
try {
fileHandle.getMetadata({ size: true });
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "FileHandleInactiveError", "Good error.");
is(e.code, 0, "Good error code.");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,70 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open();
let fileHandle2;
let comp = SpecialPowers.wrap(SpecialPowers.Components);
let thread = comp.classes["@mozilla.org/thread-manager;1"]
.getService(comp.interfaces.nsIThreadManager)
.currentThread;
let eventHasRun;
thread.dispatch(function() {
eventHasRun = true;
fileHandle2 = mutableFile.open();
}, SpecialPowers.Ci.nsIThread.DISPATCH_NORMAL);
while (!eventHasRun) {
thread.processNextEvent(false);
}
ok(fileHandle2, "Non-null fileHandle2");
continueToNextStep();
yield undefined;
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,105 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
is(fileHandle.location, 0, "Correct location");
fileHandle.location = 100000;
is(fileHandle.location, 100000, "Correct location");
fileHandle.location = null;
ok(fileHandle.location === null, "Correct location");
try {
fileHandle.readAsArrayBuffer(1);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
try {
fileHandle.readAsText(1);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
try {
fileHandle.write({});
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
request = fileHandle.append("foo");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
ok(fileHandle.location === null, "Correct location");
try {
fileHandle.truncate();
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "InvalidStateError", "Good error.");
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
}
request = fileHandle.truncate(0);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, 0, "Correct location");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,63 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle1 = mutableFile.open("readwrite");
let fileHandle2 = mutableFile.open("readwrite");
let request1 = fileHandle2.write("2");
let request2 = fileHandle1.write("1");
fileHandle1.oncomplete = grabEventAndContinueHandler;
fileHandle2.oncomplete = grabEventAndContinueHandler;
yield undefined;
yield undefined;
let fileHandle3 = mutableFile.open("readonly");
let request3 = fileHandle3.readAsText(1);
request3.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result, "2", "File handles were ordered properly.");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,74 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
for (let i = 0; i < 50; i++) {
let stepNumber = 0;
request = mutableFile.open("readwrite").append("string1");
request.onsuccess = function(event) {
is(stepNumber, 1, "This callback came first");
stepNumber++;
event.target.fileHandle.oncomplete = grabEventAndContinueHandler;
}
request = mutableFile.open("readwrite").append("string2");
request.onsuccess = function(event) {
is(stepNumber, 2, "This callback came second");
stepNumber++;
event.target.fileHandle.oncomplete = grabEventAndContinueHandler;
}
request = mutableFile.open("readwrite").append("string3");
request.onsuccess = function(event) {
is(stepNumber, 3, "This callback came third");
stepNumber++;
event.target.fileHandle.oncomplete = grabEventAndContinueHandler;
}
stepNumber++;
yield undefined; yield undefined; yield undefined;;
is(stepNumber, 4, "All callbacks received");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,79 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
var testBuffer = getRandomBuffer(100000);
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
let sum = 0;
request = fileHandle.write(testBuffer);
request.onprogress = function(event) {
let loaded = event.loaded;
let total = event.total;
ok(loaded >= 0 && loaded <= total, "Correct loaded progress");
is(total, testBuffer.byteLength, "Correct total progress");
sum += event.loaded - sum;
}
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(sum, testBuffer.byteLength, "Correct loaded progress sum");
sum = 0;
fileHandle.location = 0;
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
request.onprogress = function(event) {
let loaded = event.loaded;
let total = event.total;
ok(loaded >= 0 && loaded <= total, "Correct loaded progress");
is(total, testBuffer.byteLength, "Correct total progress");
sum += event.loaded - sum;
}
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(sum, testBuffer.byteLength, "Correct loaded progress sum");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,82 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
request = mutableFile.open("readwrite").write({});
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.fileHandle.mode, "readwrite", "Correct mode");
try {
mutableFile.open().write({});
ok(false, "Writing to a readonly file handle should fail!");
}
catch (e) {
ok(true, "Writing to a readonly file handle failed");
}
try {
mutableFile.open().append({});
ok(false, "Appending to a readonly file handle should fail!");
}
catch (e) {
ok(true, "Appending to a readonly file handle failed");
}
try {
mutableFile.open().truncate({});
ok(false, "Truncating a readonly file handle should fail!");
}
catch (e) {
ok(true, "Truncating a readonly file handle failed");
}
try {
mutableFile.open().flush({});
ok(false, "Flushing a readonly file handle should fail!");
}
catch (e) {
ok(true, "Flushing a readonly file handle failed");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,70 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
is(request.readyState, "pending", "Correct readyState");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(request.readyState, "done", "Correct readyState");
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
is(request.readyState, "pending", "Correct readyState");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(request.readyState, "done", "Correct readyState");
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write("string");
is(request.readyState, "pending", "Correct readyState");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(request.readyState, "done", "Correct readyState");
fileHandle.location = 0;
request = fileHandle.readAsText(6);
request.onsuccess = grabEventAndContinueHandler;
is(request.readyState, "pending", "Correct readyState");
event = yield undefined;
ok(event.target.result, "Got something");
is(request.readyState, "done", "Correct readyState");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,112 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
var testBuffer = getRandomBuffer(100000);
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
request = mutableFile.getFile();
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let file = event.target.result;
let resultBuffer1;
let resultBuffer2;
let reader1 = new FileReader();
reader1.readAsArrayBuffer(file);
reader1.onerror = errorHandler;
reader1.onload = function(event)
{
resultBuffer1 = event.target.result;
let reader = new FileReader();
try {
reader.readAsArrayBuffer(file);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "FileHandleInactiveError", "Good error.");
is(e.code, 0, "Good error code.");
}
if (resultBuffer2) {
testGenerator.next();
}
}
let reader2 = new FileReader();
reader2.readAsArrayBuffer(file);
reader2.onerror = errorHandler;
reader2.onload = function(event)
{
resultBuffer2 = event.target.result;
let reader = new FileReader();
try {
reader.readAsArrayBuffer(file);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "FileHandleInactiveError", "Good error.");
is(e.code, 0, "Good error code.");
}
if (resultBuffer1) {
testGenerator.next();
}
}
yield undefined;
ok(compareBuffers(resultBuffer1, testBuffer), "Correct data");
ok(compareBuffers(resultBuffer2, testBuffer), "Correct data");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,75 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open();
fileHandle.oncomplete = unexpectedSuccessHandler;
fileHandle.onabort = grabEventAndContinueHandler;
let sawError = false;
request = fileHandle.getMetadata({ size: true });
request.onsuccess = unexpectedSuccessHandler;
request.onerror = function(event) {
is(event.target.error.name, "AbortError", "Good error");
sawError = true;
event.stopPropagation();
}
fileHandle.abort();
event = yield undefined;
is(event.type, "abort", "Got abort event");
is(sawError, true, "Saw getMetadata() error");
// Make sure the success event isn't queued somehow.
let comp = SpecialPowers.wrap(SpecialPowers.Components);
var thread = comp.classes["@mozilla.org/thread-manager;1"]
.getService(comp.interfaces.nsIThreadManager)
.currentThread;
while (thread.hasPendingEvents()) {
thread.processNextEvent(false);
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script> <!-- This is included just to skip this test in test_ipc.html -->
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,91 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
var testBuffer = getRandomBuffer(100000);
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.bin");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, 100000, "Correct location");
for (let i = 0; i < 10; i++) {
let location = fileHandle.location - 10000;
fileHandle.location = location;
request = fileHandle.truncate();
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, location, "Correct location");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result.size, location, "Correct size");
}
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let location = fileHandle.location;
for (let i = 0; i < 10; i++) {
location -= 10000;
request = fileHandle.truncate(location);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(fileHandle.location, location, "Correct location");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result.size, location, "Correct size");
}
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,70 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
var testBuffer = getRandomBuffer(100000);
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let fileHandle = mutableFile.open("readwrite");
request = fileHandle.write(testBuffer);
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
request = mutableFile.getFile();
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let file = event.target.result;
var worker = new Worker("dummy_worker.js");
try {
worker.postMessage(file);
ok(false, "Should have thrown!");
}
catch (e) {
ok(e instanceof DOMException, "Got exception.");
is(e.name, "DataCloneError", "Good error.");
is(e.code, DOMException.DATA_CLONE_ERR, "Good error code.")
}
worker.terminate();
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,110 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>File Handle Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const name = window.location.pathname;
var testString = "Lorem ipsum his ponderum delicatissimi ne, at noster dolores urbanitas pro, cibo elaboraret no his. Ea dicunt maiorum usu. Ad appareat facilisis mediocritatem eos. Tale graeci mentitum in eos, hinc insolens at nam. Graecis nominavi aliquyam eu vix. Id solet assentior sadipscing pro. Et per atqui graecis, usu quot viris repudiandae ei, mollis evertitur an nam. At nam dolor ignota, liber labore omnesque ea mei, has movet voluptaria in. Vel an impetus omittantur. Vim movet option salutandi ex, ne mei ignota corrumpit. Mucius comprehensam id per. Est ea putant maiestatis.";
for (let i = 0; i < 5; i++) {
testString += testString;
}
var testBuffer = getRandomBuffer(100000);
var testBlob = new Blob([testBuffer], {type: "binary/random"});
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
request = db.createMutableFile("test.txt");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let mutableFile = event.target.result;
mutableFile.onerror = errorHandler;
let location = 0;
let fileHandle = mutableFile.open("readwrite");
is(fileHandle.location, location, "Correct location");
request = fileHandle.write(testString);
location += testString.length;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location = 0;
request = fileHandle.readAsText(testString.length);
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultString = event.target.result;
ok(resultString == testString, "Correct string data");
request = fileHandle.write(testBuffer);
location += testBuffer.byteLength;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location -= testBuffer.byteLength;
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
request = fileHandle.write(testBlob);
location += testBlob.size;
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
fileHandle.location -= testBlob.size;
request = fileHandle.readAsArrayBuffer(testBlob.size);
is(fileHandle.location, location, "Correct location");
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
resultBuffer = event.target.result;
ok(compareBuffers(resultBuffer, testBuffer), "Correct blob data");
request = fileHandle.getMetadata({ size: true });
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let result = event.target.result;
is(result.size, location, "Correct size");
finishTest();
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -22,6 +22,7 @@
yield undefined;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>

View File

@ -369,14 +369,10 @@ var interfaceNamesInGlobalScope =
{name: "External", b2g: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
"File",
// IMPORTANT: Do not change this list without review from a DOM peer!
"FileHandle",
// IMPORTANT: Do not change this list without review from a DOM peer!
"FileList",
// IMPORTANT: Do not change this list without review from a DOM peer!
"FileReader",
// IMPORTANT: Do not change this list without review from a DOM peer!
"FileRequest",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "FMRadio", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -565,6 +561,10 @@ var interfaceNamesInGlobalScope =
"IDBDatabase",
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBFactory",
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBFileHandle",
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBFileRequest",
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBIndex",
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -737,8 +737,6 @@ var interfaceNamesInGlobalScope =
{name: "MozWifiP2pManager", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozWifiP2pStatusChangeEvent", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"MutableFile",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MutationEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -1,50 +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 obtaone at http://mozilla.org/MPL/2.0/. */
dictionary DOMFileMetadataParameters
{
boolean size = true;
boolean lastModified = true;
};
interface FileHandle : EventTarget
{
readonly attribute MutableFile? mutableFile;
// this is deprecated due to renaming in the spec
readonly attribute MutableFile? fileHandle; // now mutableFile
readonly attribute FileMode mode;
readonly attribute boolean active;
attribute unsigned long long? location;
[Throws]
FileRequest? getMetadata(optional DOMFileMetadataParameters parameters);
[Throws]
FileRequest? readAsArrayBuffer(unsigned long long size);
[Throws]
FileRequest? readAsText(unsigned long long size,
optional DOMString? encoding = null);
[Throws]
FileRequest? write(ArrayBuffer value);
[Throws]
FileRequest? write(Blob value);
[Throws]
FileRequest? write(DOMString value);
[Throws]
FileRequest? append(ArrayBuffer value);
[Throws]
FileRequest? append(Blob value);
[Throws]
FileRequest? append(DOMString value);
[Throws]
FileRequest? truncate(optional unsigned long long size);
[Throws]
FileRequest? flush();
[Throws]
void abort();
attribute EventHandler oncomplete;
attribute EventHandler onabort;
attribute EventHandler onerror;
};

View File

@ -0,0 +1,50 @@
/* 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 obtaone at http://mozilla.org/MPL/2.0/. */
dictionary IDBFileMetadataParameters
{
boolean size = true;
boolean lastModified = true;
};
interface IDBFileHandle : EventTarget
{
readonly attribute IDBMutableFile? mutableFile;
// this is deprecated due to renaming in the spec
readonly attribute IDBMutableFile? fileHandle; // now mutableFile
readonly attribute FileMode mode;
readonly attribute boolean active;
attribute unsigned long long? location;
[Throws]
IDBFileRequest? getMetadata(optional IDBFileMetadataParameters parameters);
[Throws]
IDBFileRequest? readAsArrayBuffer(unsigned long long size);
[Throws]
IDBFileRequest? readAsText(unsigned long long size,
optional DOMString? encoding = null);
[Throws]
IDBFileRequest? write(ArrayBuffer value);
[Throws]
IDBFileRequest? write(Blob value);
[Throws]
IDBFileRequest? write(DOMString value);
[Throws]
IDBFileRequest? append(ArrayBuffer value);
[Throws]
IDBFileRequest? append(Blob value);
[Throws]
IDBFileRequest? append(DOMString value);
[Throws]
IDBFileRequest? truncate(optional unsigned long long size);
[Throws]
IDBFileRequest? flush();
[Throws]
void abort();
attribute EventHandler oncomplete;
attribute EventHandler onabort;
attribute EventHandler onerror;
};

View File

@ -4,11 +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/. */
interface FileRequest : DOMRequest {
readonly attribute FileHandle? fileHandle;
interface IDBFileRequest : DOMRequest {
readonly attribute IDBFileHandle? fileHandle;
// this is deprecated due to renaming in the spec
readonly attribute FileHandle? lockedFile; // now fileHandle
readonly attribute IDBFileHandle? lockedFile; // now fileHandle
attribute EventHandler onprogress;
};

View File

@ -3,6 +3,18 @@
* 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/. */
interface IDBMutableFile : MutableFile {
interface IDBMutableFile : EventTarget {
readonly attribute DOMString name;
readonly attribute DOMString type;
readonly attribute IDBDatabase database;
[Throws]
IDBFileHandle open(optional FileMode mode = "readonly");
[Throws]
DOMRequest getFile();
attribute EventHandler onabort;
attribute EventHandler onerror;
};

View File

@ -1,18 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
interface MutableFile : EventTarget {
readonly attribute DOMString name;
readonly attribute DOMString type;
[Throws]
FileHandle open(optional FileMode mode = "readonly");
[Throws]
DOMRequest getFile();
attribute EventHandler onabort;
attribute EventHandler onerror;
};

View File

@ -118,12 +118,10 @@ WEBIDL_FILES = [
'EventSource.webidl',
'EventTarget.webidl',
'File.webidl',
'FileHandle.webidl',
'FileList.webidl',
'FileMode.webidl',
'FileReader.webidl',
'FileReaderSync.webidl',
'FileRequest.webidl',
'FocusEvent.webidl',
'FormData.webidl',
'Function.webidl',
@ -211,6 +209,8 @@ WEBIDL_FILES = [
'IDBDatabase.webidl',
'IDBEnvironment.webidl',
'IDBFactory.webidl',
'IDBFileHandle.webidl',
'IDBFileRequest.webidl',
'IDBIndex.webidl',
'IDBKeyRange.webidl',
'IDBMutableFile.webidl',
@ -261,7 +261,6 @@ WEBIDL_FILES = [
'MozPowerManager.webidl',
'MozTimeManager.webidl',
'MozWakeLock.webidl',
'MutableFile.webidl',
'MutationEvent.webidl',
'MutationObserver.webidl',
'NativeOSFileInternals.webidl',