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

View File

@ -446,10 +446,6 @@ DOMInterfaces = {
}, },
}, },
'FileHandle': {
'nativeType': 'mozilla::dom::FileHandle',
},
'FileList': { 'FileList': {
'nativeType': 'nsDOMFileList', 'nativeType': 'nsDOMFileList',
'headerFile': 'nsDOMFile.h', 'headerFile': 'nsDOMFile.h',
@ -466,10 +462,6 @@ DOMInterfaces = {
'wrapperCache': False, 'wrapperCache': False,
}, },
'FileRequest': {
'nativeType': 'mozilla::dom::FileRequest',
},
'FormData': [ 'FormData': [
{ {
'nativeType': 'nsFormData' 'nativeType': 'nsFormData'
@ -656,6 +648,14 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::indexedDB::IDBFactory', 'nativeType': 'mozilla::dom::indexedDB::IDBFactory',
}, },
'IDBFileHandle': {
'nativeType': 'mozilla::dom::indexedDB::IDBFileHandle',
},
'IDBFileRequest': {
'nativeType': 'mozilla::dom::indexedDB::IDBFileRequest',
},
'IDBIndex': { 'IDBIndex': {
'nativeType': 'mozilla::dom::indexedDB::IDBIndex', 'nativeType': 'mozilla::dom::indexedDB::IDBIndex',
'binaryNames': { 'binaryNames': {
@ -889,10 +889,6 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::Voicemail', 'nativeType': 'mozilla::dom::Voicemail',
}, },
'MutableFile': {
'nativeType': 'mozilla::dom::MutableFile'
},
'MutationObserver': { 'MutationObserver': {
'nativeType': 'nsDOMMutationObserver', '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 "FileService.h"
#include "FileStreamWrappers.h" #include "FileStreamWrappers.h"
#include "MemoryStreams.h" #include "MemoryStreams.h"
#include "MetadataHelper.h"
#include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/FileHandleBinding.h"
#include "mozilla/EventDispatcher.h"
#include "MutableFile.h" #include "MutableFile.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsDebug.h" #include "nsDebug.h"
#include "nsError.h" #include "nsError.h"
#include "nsIAppShell.h"
#include "nsIDOMEvent.h"
#include "nsIDOMFile.h" #include "nsIDOMFile.h"
#include "nsIEventTarget.h" #include "nsIEventTarget.h"
#include "nsISeekableStream.h" #include "nsISeekableStream.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h" #include "nsString.h"
#include "nsStringStream.h" #include "nsStringStream.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsWidgetsCID.h" #include "xpcpublic.h"
#define STREAM_COPY_BLOCK_SIZE 32768 #define STREAM_COPY_BLOCK_SIZE 32768
@ -39,13 +33,11 @@ namespace dom {
namespace { namespace {
NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
class ReadHelper : public FileHelper class ReadHelper : public FileHelper
{ {
public: public:
ReadHelper(FileHandle* aFileHandle, ReadHelper(FileHandleBase* aFileHandle,
FileRequest* aFileRequest, FileRequestBase* aFileRequest,
uint64_t aLocation, uint64_t aLocation,
uint64_t aSize) uint64_t aSize)
: FileHelper(aFileHandle, aFileRequest), : FileHelper(aFileHandle, aFileRequest),
@ -74,8 +66,8 @@ protected:
class ReadTextHelper : public ReadHelper class ReadTextHelper : public ReadHelper
{ {
public: public:
ReadTextHelper(FileHandle* aFileHandle, ReadTextHelper(FileHandleBase* aFileHandle,
FileRequest* aFileRequest, FileRequestBase* aFileRequest,
uint64_t aLocation, uint64_t aLocation,
uint64_t aSize, uint64_t aSize,
const nsAString& aEncoding) const nsAString& aEncoding)
@ -94,8 +86,8 @@ private:
class WriteHelper : public FileHelper class WriteHelper : public FileHelper
{ {
public: public:
WriteHelper(FileHandle* aFileHandle, WriteHelper(FileHandleBase* aFileHandle,
FileRequest* aFileRequest, FileRequestBase* aFileRequest,
uint64_t aLocation, uint64_t aLocation,
nsIInputStream* aStream, nsIInputStream* aStream,
uint64_t aLength) uint64_t aLength)
@ -117,8 +109,8 @@ private:
class TruncateHelper : public FileHelper class TruncateHelper : public FileHelper
{ {
public: public:
TruncateHelper(FileHandle* aFileHandle, TruncateHelper(FileHandleBase* aFileHandle,
FileRequest* aFileRequest, FileRequestBase* aFileRequest,
uint64_t aOffset) uint64_t aOffset)
: FileHelper(aFileHandle, aFileRequest), : FileHelper(aFileHandle, aFileRequest),
mOffset(aOffset) mOffset(aOffset)
@ -148,8 +140,8 @@ private:
class FlushHelper : public FileHelper class FlushHelper : public FileHelper
{ {
public: public:
FlushHelper(FileHandle* aFileHandle, FlushHelper(FileHandleBase* aFileHandle,
FileRequest* aFileRequest) FileRequestBase* aFileRequest)
: FileHelper(aFileHandle, aFileRequest) : FileHelper(aFileHandle, aFileRequest)
{ } { }
@ -172,7 +164,7 @@ private:
class OpenStreamHelper : public FileHelper class OpenStreamHelper : public FileHelper
{ {
public: public:
OpenStreamHelper(FileHandle* aFileHandle, OpenStreamHelper(FileHandleBase* aFileHandle,
bool aWholeFile, bool aWholeFile,
uint64_t aStart, uint64_t aStart,
uint64_t aLength) uint64_t aLength)
@ -197,95 +189,28 @@ private:
nsCOMPtr<nsIInputStream> mStream; 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 } // anonymous namespace
// static FileHandleBase::FileHandleBase(FileMode aMode,
already_AddRefed<FileHandle> RequestMode aRequestMode)
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()
: mReadyState(INITIAL), : mReadyState(INITIAL),
mMode(FileMode::Readonly), mMode(aMode),
mRequestMode(NORMAL), mRequestMode(aRequestMode),
mLocation(0), mLocation(0),
mPendingRequests(0), mPendingRequests(0),
mAborted(false), mAborted(false),
mCreating(false) mCreating(false)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
SetIsDOMBinding();
} }
FileHandle::~FileHandle() FileHandleBase::~FileHandleBase()
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 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 void
FileHandle::OnNewRequest() FileHandleBase::OnNewRequest()
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
if (!mPendingRequests) { if (!mPendingRequests) {
@ -296,30 +221,31 @@ FileHandle::OnNewRequest()
} }
void void
FileHandle::OnRequestFinished() FileHandleBase::OnRequestFinished()
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(mPendingRequests, "Mismatched calls!"); MOZ_ASSERT(mPendingRequests, "Mismatched calls!");
--mPendingRequests; --mPendingRequests;
if (!mPendingRequests) { if (!mPendingRequests) {
MOZ_ASSERT(mAborted || mReadyState == LOADING, "Bad state!"); MOZ_ASSERT(mAborted || mReadyState == LOADING, "Bad state!");
mReadyState = FileHandle::FINISHING; mReadyState = FileHandleBase::FINISHING;
Finish(); Finish();
} }
} }
nsresult nsresult
FileHandle::CreateParallelStream(nsISupports** aStream) FileHandleBase::CreateParallelStream(nsISupports** aStream)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
if (mMutableFile->IsInvalid()) { MutableFileBase* mutableFile = MutableFile();
if (mutableFile->IsInvalid()) {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
nsCOMPtr<nsISupports> stream = nsCOMPtr<nsISupports> stream =
mMutableFile->CreateStream(mMutableFile->mFile, mutableFile->CreateStream(mMode == FileMode::Readonly);
mMode == FileMode::Readonly);
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
mParallelStreams.AppendElement(stream); mParallelStreams.AppendElement(stream);
@ -329,18 +255,19 @@ FileHandle::CreateParallelStream(nsISupports** aStream)
} }
nsresult nsresult
FileHandle::GetOrCreateStream(nsISupports** aStream) FileHandleBase::GetOrCreateStream(nsISupports** aStream)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
if (mMutableFile->IsInvalid()) { MutableFileBase* mutableFile = MutableFile();
if (mutableFile->IsInvalid()) {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
if (!mStream) { if (!mStream) {
nsCOMPtr<nsISupports> stream = nsCOMPtr<nsISupports> stream =
mMutableFile->CreateStream(mMutableFile->mFile, mutableFile->CreateStream(mMode == FileMode::Readonly);
mMode == FileMode::Readonly);
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
stream.swap(mStream); stream.swap(mStream);
@ -352,15 +279,8 @@ FileHandle::GetOrCreateStream(nsISupports** aStream)
return NS_OK; return NS_OK;
} }
already_AddRefed<FileRequest>
FileHandle::GenerateFileRequest()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
return FileRequest::Create(GetOwner(), this, /* aWrapAsDOMRequest */ false);
}
bool bool
FileHandle::IsOpen() const FileHandleBase::IsOpen() const
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -389,51 +309,9 @@ FileHandle::IsOpen() const
return false; return false;
} }
// virtual already_AddRefed<FileRequestBase>
JSObject* FileHandleBase::Read(uint64_t aSize, bool aHasEncoding,
FileHandle::WrapObject(JSContext* aCx) const nsAString& aEncoding, ErrorResult& aRv)
{
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)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -443,14 +321,18 @@ FileHandle::ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
} }
// Do nothing if the window is closed // Do nothing if the window is closed
if (!GetOwner()) { if (!CheckWindow()) {
return nullptr; return nullptr;
} }
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest(); nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<ReadHelper> helper = nsRefPtr<ReadHelper> helper;
new ReadHelper(this, fileRequest, mLocation, aSize); 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())) || if (NS_WARN_IF(NS_FAILED(helper->Init())) ||
NS_WARN_IF(NS_FAILED(helper->Enqueue()))) { NS_WARN_IF(NS_FAILED(helper->Enqueue()))) {
@ -463,40 +345,8 @@ FileHandle::ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
return fileRequest.forget(); return fileRequest.forget();
} }
already_AddRefed<FileRequest> already_AddRefed<FileRequestBase>
FileHandle::ReadAsText(uint64_t aSize, const nsAString& aEncoding, FileHandleBase::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
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)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 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 // Do nothing if the window is closed
if (!GetOwner()) { if (!CheckWindow()) {
return nullptr; return nullptr;
} }
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest(); nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<TruncateHelper> helper = nsRefPtr<TruncateHelper> helper =
new TruncateHelper(this, fileRequest, location); new TruncateHelper(this, fileRequest, location);
@ -541,8 +391,8 @@ FileHandle::Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv)
return fileRequest.forget(); return fileRequest.forget();
} }
already_AddRefed<FileRequest> already_AddRefed<FileRequestBase>
FileHandle::Flush(ErrorResult& aRv) FileHandleBase::Flush(ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -552,11 +402,11 @@ FileHandle::Flush(ErrorResult& aRv)
} }
// Do nothing if the window is closed // Do nothing if the window is closed
if (!GetOwner()) { if (!CheckWindow()) {
return nullptr; return nullptr;
} }
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest(); nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
nsRefPtr<FlushHelper> helper = new FlushHelper(this, fileRequest); nsRefPtr<FlushHelper> helper = new FlushHelper(this, fileRequest);
@ -569,7 +419,7 @@ FileHandle::Flush(ErrorResult& aRv)
} }
void void
FileHandle::Abort(ErrorResult& aRv) FileHandleBase::Abort(ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 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() // We can't use IsOpen here since we need it to be possible to call Abort()
// even from outside of transaction callbacks. // even from outside of transaction callbacks.
if (mReadyState != FileHandle::INITIAL && if (mReadyState != FileHandleBase::INITIAL &&
mReadyState != FileHandle::LOADING) { mReadyState != FileHandleBase::LOADING) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR); aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
return; return;
} }
@ -595,8 +445,8 @@ FileHandle::Abort(ErrorResult& aRv)
} }
} }
NS_IMETHODIMP void
FileHandle::Run() FileHandleBase::OnReturnToEventLoop()
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -611,13 +461,11 @@ FileHandle::Run()
NS_WARNING("Failed to finish!"); NS_WARNING("Failed to finish!");
} }
} }
return NS_OK;
} }
nsresult nsresult
FileHandle::OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength, FileHandleBase::OpenInputStream(bool aWholeFile, uint64_t aStart,
nsIInputStream** aResult) uint64_t aLength, nsIInputStream** aResult)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(mRequestMode == PARALLEL, 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 // Do nothing if the window is closed
if (!GetOwner()) { if (!CheckWindow()) {
return NS_OK; return NS_OK;
} }
@ -648,7 +496,7 @@ FileHandle::OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength,
} }
bool bool
FileHandle::CheckState(ErrorResult& aRv) FileHandleBase::CheckState(ErrorResult& aRv)
{ {
if (!IsOpen()) { if (!IsOpen()) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_INACTIVE_ERR); aRv.Throw(NS_ERROR_DOM_FILEHANDLE_INACTIVE_ERR);
@ -659,7 +507,7 @@ FileHandle::CheckState(ErrorResult& aRv)
} }
bool bool
FileHandle::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv) FileHandleBase::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv)
{ {
// Common state checking // Common state checking
if (!CheckState(aRv)) { if (!CheckState(aRv)) {
@ -682,7 +530,7 @@ FileHandle::CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv)
} }
bool bool
FileHandle::CheckStateForWrite(ErrorResult& aRv) FileHandleBase::CheckStateForWrite(ErrorResult& aRv)
{ {
// Common state checking // Common state checking
if (!CheckState(aRv)) { if (!CheckState(aRv)) {
@ -698,9 +546,10 @@ FileHandle::CheckStateForWrite(ErrorResult& aRv)
return true; return true;
} }
already_AddRefed<FileRequest> already_AddRefed<FileRequestBase>
FileHandle::WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength, FileHandleBase::WriteInternal(nsIInputStream* aInputStream,
bool aAppend, ErrorResult& aRv) uint64_t aInputLength, bool aAppend,
ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 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_IF(!aAppend, mLocation != UINT64_MAX);
MOZ_ASSERT(aInputStream); MOZ_ASSERT(aInputStream);
MOZ_ASSERT(aInputLength); MOZ_ASSERT(aInputLength);
MOZ_ASSERT(GetOwner()); MOZ_ASSERT(CheckWindow());
nsRefPtr<FileRequest> fileRequest = GenerateFileRequest(); nsRefPtr<FileRequestBase> fileRequest = GenerateFileRequest();
uint64_t location = aAppend ? UINT64_MAX : mLocation; uint64_t location = aAppend ? UINT64_MAX : mLocation;
@ -734,7 +583,7 @@ FileHandle::WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength,
} }
nsresult nsresult
FileHandle::Finish() FileHandleBase::Finish()
{ {
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -753,8 +602,8 @@ FileHandle::Finish()
// static // static
already_AddRefed<nsIInputStream> already_AddRefed<nsIInputStream>
FileHandle::GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength, FileHandleBase::GetInputStream(const ArrayBuffer& aValue,
ErrorResult& aRv) uint64_t* aInputLength, ErrorResult& aRv)
{ {
aValue.ComputeLengthAndData(); aValue.ComputeLengthAndData();
const char* data = reinterpret_cast<const char*>(aValue.Data()); const char* data = reinterpret_cast<const char*>(aValue.Data());
@ -773,8 +622,8 @@ FileHandle::GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength,
// static // static
already_AddRefed<nsIInputStream> already_AddRefed<nsIInputStream>
FileHandle::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength, FileHandleBase::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength,
ErrorResult& aRv) ErrorResult& aRv)
{ {
uint64_t length; uint64_t length;
aRv = aValue->GetSize(&length); aRv = aValue->GetSize(&length);
@ -794,8 +643,8 @@ FileHandle::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength,
// static // static
already_AddRefed<nsIInputStream> already_AddRefed<nsIInputStream>
FileHandle::GetInputStream(const nsAString& aValue, uint64_t* aInputLength, FileHandleBase::GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
ErrorResult& aRv) ErrorResult& aRv)
{ {
NS_ConvertUTF16toUTF8 cstr(aValue); NS_ConvertUTF16toUTF8 cstr(aValue);
@ -809,7 +658,7 @@ FileHandle::GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
return stream.forget(); return stream.forget();
} }
FinishHelper::FinishHelper(FileHandle* aFileHandle) FinishHelper::FinishHelper(FileHandleBase* aFileHandle)
: mFileHandle(aFileHandle), : mFileHandle(aFileHandle),
mAborted(aFileHandle->mAborted) mAborted(aFileHandle->mAborted)
{ {
@ -823,27 +672,16 @@ NS_IMETHODIMP
FinishHelper::Run() FinishHelper::Run()
{ {
if (NS_IsMainThread()) { if (NS_IsMainThread()) {
mFileHandle->mReadyState = FileHandle::DONE; mFileHandle->mReadyState = FileHandleBase::DONE;
FileService* service = FileService::Get(); FileService* service = FileService::Get();
if (service) { if (service) {
service->NotifyFileHandleCompleted(mFileHandle); service->NotifyFileHandleCompleted(mFileHandle);
} }
nsCOMPtr<nsIDOMEvent> event; nsresult rv = mFileHandle->OnCompleteOrAbort(mAborted);
if (mAborted) { if (NS_WARN_IF(NS_FAILED(rv))) {
event = CreateGenericEvent(mFileHandle, NS_LITERAL_STRING("abort"), return rv;
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!");
} }
mFileHandle = nullptr; mFileHandle = nullptr;
@ -851,7 +689,7 @@ FinishHelper::Run()
return NS_OK; return NS_OK;
} }
if (mFileHandle->mMutableFile->IsInvalid()) { if (mFileHandle->MutableFile()->IsInvalid()) {
mAborted = true; mAborted = true;
} }

View File

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

View File

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

View File

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

View File

@ -6,145 +6,20 @@
#include "FileRequest.h" #include "FileRequest.h"
#include "FileHandle.h"
#include "FileHelper.h"
#include "js/RootingAPI.h"
#include "jsapi.h"
#include "MainThreadUtils.h" #include "MainThreadUtils.h"
#include "mozilla/dom/FileRequestBinding.h" #include "mozilla/Assertions.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"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
FileRequest::FileRequest(nsPIDOMWindow* aWindow) FileRequestBase::FileRequestBase()
: DOMRequest(aWindow), mWrapAsDOMRequest(false)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread());
} }
FileRequest::~FileRequest() FileRequestBase::~FileRequestBase()
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(NS_IsMainThread());
}
// 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);
} }
} // namespace dom } // namespace dom

View File

@ -7,73 +7,35 @@
#ifndef mozilla_dom_FileRequest_h #ifndef mozilla_dom_FileRequest_h
#define mozilla_dom_FileRequest_h #define mozilla_dom_FileRequest_h
#include "DOMRequest.h" #include "nscore.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
class nsPIDOMWindow;
namespace mozilla { namespace mozilla {
class EventChainPreVisitor;
namespace dom { namespace dom {
class FileHandle;
class FileHelper; class FileHelper;
class FileRequest : public DOMRequest /**
* This class provides a base for FileRequest implementations.
*/
class FileRequestBase
{ {
public: 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> virtual void
Create(nsPIDOMWindow* aOwner, FileHandle* aFileHandle, OnProgress(uint64_t aProgress, uint64_t aProgressMax) = 0;
bool aWrapAsDOMRequest);
// nsIDOMEventTarget
virtual nsresult virtual nsresult
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE; NotifyHelperCompleted(FileHelper* aFileHelper) = 0;
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)
protected: protected:
FileRequest(nsPIDOMWindow* aWindow); FileRequestBase();
~FileRequest();
void virtual ~FileRequestBase();
FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
nsRefPtr<FileHandle> mFileHandle;
bool mWrapAsDOMRequest;
}; };
} // namespace dom } // namespace dom

View File

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

View File

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

View File

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

View File

@ -6,85 +6,32 @@
#include "MutableFile.h" #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 "nsDebug.h"
#include "nsError.h"
#include "nsIDOMFile.h"
#include "nsIFile.h" #include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
namespace { MutableFileBase::MutableFileBase()
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)
{ {
} }
MutableFile::MutableFile(DOMEventTargetHelper* aOwner) MutableFileBase::~MutableFileBase()
: DOMEventTargetHelper(aOwner)
{ {
} }
MutableFile::~MutableFile()
{
}
bool
MutableFile::IsShuttingDown()
{
return FileService::IsShuttingDown();
}
// virtual // virtual
already_AddRefed<nsISupports> already_AddRefed<nsISupports>
MutableFile::CreateStream(nsIFile* aFile, bool aReadOnly) MutableFileBase::CreateStream(bool aReadOnly)
{ {
nsresult rv; nsresult rv;
if (aReadOnly) { if (aReadOnly) {
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), aFile, -1, -1, rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), mFile, -1, -1,
nsIFileInputStream::DEFER_OPEN); nsIFileInputStream::DEFER_OPEN);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr; return nullptr;
@ -93,7 +40,7 @@ MutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
} }
nsCOMPtr<nsIFileStream> stream; nsCOMPtr<nsIFileStream> stream;
rv = NS_NewLocalFileStream(getter_AddRefs(stream), aFile, -1, -1, rv = NS_NewLocalFileStream(getter_AddRefs(stream), mFile, -1, -1,
nsIFileStream::DEFER_OPEN); nsIFileStream::DEFER_OPEN);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr; return nullptr;
@ -101,88 +48,5 @@ MutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
return stream.forget(); 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 dom
} // namespace mozilla } // namespace mozilla

View File

@ -7,75 +7,33 @@
#ifndef mozilla_dom_MutableFile_h #ifndef mozilla_dom_MutableFile_h
#define 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 "nsCOMPtr.h"
#include "nsString.h" #include "nsString.h"
class nsIDOMFile;
class nsIFile; class nsIFile;
class nsIOfflineStorage; class nsIOfflineStorage;
class nsPIDOMWindow;
namespace mozilla { namespace mozilla {
class ErrorResult;
namespace dom { namespace dom {
class DOMRequest;
class FileHandle;
class FileService; class FileService;
class FinishHelper;
class FileHelper;
namespace indexedDB {
class FileInfo;
} // namespace indexedDB
/** /**
* This class provides a default MutableFile implementation, but it can be also * This class provides a base for MutableFile implementations.
* subclassed. The subclass can override implementation of GetFileId, * The subclasses can override implementation of IsInvalid, CreateStream,
* GetFileInfo, IsShuttingDown, IsInvalid, CreateStream, SetThreadLocals, * SetThreadLocals and UnsetThreadLocals.
* UnsetThreadLocals and CreateFileObject.
* (for example IDBMutableFile provides IndexedDB specific implementation). * (for example IDBMutableFile provides IndexedDB specific implementation).
*/ */
class MutableFile : public DOMEventTargetHelper class MutableFileBase
{ {
friend class FileHandle;
friend class FileService; friend class FileService;
friend class FinishHelper;
friend class FileHelper;
public: public:
const nsAString& NS_IMETHOD_(MozExternalRefCountType)
Name() const AddRef() = 0;
{
return mName;
}
const nsAString& NS_IMETHOD_(MozExternalRefCountType)
Type() const Release() = 0;
{
return mType;
}
virtual int64_t
GetFileId()
{
return -1;
}
virtual mozilla::dom::indexedDB::FileInfo*
GetFileInfo()
{
return nullptr;
}
virtual bool
IsShuttingDown();
virtual bool virtual bool
IsInvalid() IsInvalid()
@ -89,7 +47,7 @@ public:
Storage() = 0; Storage() = 0;
virtual already_AddRefed<nsISupports> virtual already_AddRefed<nsISupports>
CreateStream(nsIFile* aFile, bool aReadOnly); CreateStream(bool aReadOnly);
virtual void virtual void
SetThreadLocals() 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: protected:
MutableFile(nsPIDOMWindow* aWindow); MutableFileBase();
MutableFile(DOMEventTargetHelper* aOwner); virtual ~MutableFileBase();
virtual ~MutableFile();
nsString mName;
nsString mType;
nsCOMPtr<nsIFile> mFile; nsCOMPtr<nsIFile> mFile;

View File

@ -4,20 +4,18 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += ['test']
EXPORTS.mozilla.dom += [ EXPORTS.mozilla.dom += [
'File.h', 'AsyncHelper.h',
'FileHandle.h', 'FileHandle.h',
'FileHelper.h', 'FileHelper.h',
'FileRequest.h', 'FileRequest.h',
'FileService.h', 'FileService.h',
'MetadataHelper.h',
'MutableFile.h', 'MutableFile.h',
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'AsyncHelper.cpp', 'AsyncHelper.cpp',
'File.cpp',
'FileHandle.cpp', 'FileHandle.cpp',
'FileHelper.cpp', 'FileHelper.cpp',
'FileRequest.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, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_File_h #ifndef mozilla_dom_indexeddb_filesnapshot_h__
#define mozilla_dom_File_h #define mozilla_dom_indexeddb_filesnapshot_h__
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
@ -15,45 +15,45 @@
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
namespace indexedDB {
class FileHandle; class IDBFileHandle;
class File;
class FileImpl : public DOMFileImplBase class FileImplSnapshot : public DOMFileImplBase
{ {
friend class File;
public: public:
NS_DECL_ISUPPORTS_INHERITED 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 // Create as a stored file
FileImpl(const nsAString& aName, const nsAString& aContentType, FileImplSnapshot(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle, uint64_t aLength, nsIFile* aFile, IDBFileHandle* aFileHandle,
indexedDB::FileInfo* aFileInfo); FileInfo* aFileInfo);
// Overrides // 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
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE; Unlink() MOZ_OVERRIDE;
virtual bool IsCCed() const MOZ_OVERRIDE virtual void
Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool
IsCCed() const MOZ_OVERRIDE
{ {
return true; return true;
} }
protected: protected:
// Create slice // Create slice
FileImpl(const FileImpl* aOther, uint64_t aStart, uint64_t aLength, FileImplSnapshot(const FileImplSnapshot* aOther, uint64_t aStart,
const nsAString& aContentType); uint64_t aLength, const nsAString& aContentType);
virtual ~FileImpl(); virtual ~FileImplSnapshot();
virtual already_AddRefed<nsIDOMBlob> virtual already_AddRefed<nsIDOMBlob>
CreateSlice(uint64_t aStart, uint64_t aLength, CreateSlice(uint64_t aStart, uint64_t aLength,
@ -62,7 +62,7 @@ protected:
virtual bool virtual bool
IsStoredFile() const MOZ_OVERRIDE IsStoredFile() const MOZ_OVERRIDE
{ {
return mStoredFile; return true;
} }
virtual bool virtual bool
@ -79,13 +79,13 @@ protected:
private: private:
nsCOMPtr<nsIFile> mFile; nsCOMPtr<nsIFile> mFile;
nsRefPtr<FileHandle> mFileHandle; nsRefPtr<IDBFileHandle> mFileHandle;
bool mWholeFile; bool mWholeFile;
bool mStoredFile;
}; };
} // namespace indexedDB
} // namespace dom } // namespace dom
} // namespace mozilla } // 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 "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/IDBMutableFileBinding.h"
#include "mozilla/dom/MetadataHelper.h"
#include "mozilla/dom/quota/FileStreams.h" #include "mozilla/dom/quota/FileStreams.h"
#include "mozilla/dom/quota/QuotaManager.h" #include "mozilla/dom/quota/QuotaManager.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsError.h"
#include "FileSnapshot.h"
#include "IDBDatabase.h" #include "IDBDatabase.h"
#include "IDBFileHandle.h"
#include "IDBFileRequest.h"
using namespace mozilla::dom;
USING_INDEXEDDB_NAMESPACE USING_INDEXEDDB_NAMESPACE
USING_QUOTA_NAMESPACE USING_QUOTA_NAMESPACE
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 inline
already_AddRefed<nsIFile> already_AddRefed<nsIFile>
GetFileFor(FileInfo* aFileInfo) GetFileFor(FileInfo* aFileInfo)
@ -36,18 +74,27 @@ GetFileFor(FileInfo* aFileInfo)
} // anonymous namespace } // anonymous namespace
namespace mozilla {
namespace dom {
namespace indexedDB {
IDBMutableFile::IDBMutableFile(IDBDatabase* aOwner) 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_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_ADDREF_INHERITED(IDBMutableFile, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(IDBMutableFile, MutableFile) NS_IMPL_RELEASE_INHERITED(IDBMutableFile, DOMEventTargetHelper)
// static // static
already_AddRefed<IDBMutableFile> already_AddRefed<IDBMutableFile>
@ -78,12 +125,6 @@ IDBMutableFile::Create(const nsAString& aName,
return newFile.forget(); return newFile.forget();
} }
bool
IDBMutableFile::IsShuttingDown()
{
return QuotaManager::IsShuttingDown() || MutableFile::IsShuttingDown();
}
bool bool
IDBMutableFile::IsInvalid() IDBMutableFile::IsInvalid()
{ {
@ -97,7 +138,7 @@ IDBMutableFile::Storage()
} }
already_AddRefed<nsISupports> already_AddRefed<nsISupports>
IDBMutableFile::CreateStream(nsIFile* aFile, bool aReadOnly) IDBMutableFile::CreateStream(bool aReadOnly)
{ {
PersistenceType persistenceType = mDatabase->Type(); PersistenceType persistenceType = mDatabase->Type();
const nsACString& group = mDatabase->Group(); const nsACString& group = mDatabase->Group();
@ -107,13 +148,13 @@ IDBMutableFile::CreateStream(nsIFile* aFile, bool aReadOnly)
if (aReadOnly) { if (aReadOnly) {
nsRefPtr<FileInputStream> stream = nsRefPtr<FileInputStream> stream =
FileInputStream::Create(persistenceType, group, origin, aFile, -1, -1, FileInputStream::Create(persistenceType, group, origin, mFile, -1, -1,
nsIFileInputStream::DEFER_OPEN); nsIFileInputStream::DEFER_OPEN);
result = NS_ISUPPORTS_CAST(nsIFileInputStream*, stream); result = NS_ISUPPORTS_CAST(nsIFileInputStream*, stream);
} }
else { else {
nsRefPtr<FileStream> stream = nsRefPtr<FileStream> stream =
FileStream::Create(persistenceType, group, origin, aFile, -1, -1, FileStream::Create(persistenceType, group, origin, mFile, -1, -1,
nsIFileStream::DEFER_OPEN); nsIFileStream::DEFER_OPEN);
result = NS_ISUPPORTS_CAST(nsIFileStream*, stream); result = NS_ISUPPORTS_CAST(nsIFileStream*, stream);
} }
@ -136,13 +177,13 @@ IDBMutableFile::UnsetThreadLocals()
} }
already_AddRefed<nsIDOMFile> already_AddRefed<nsIDOMFile>
IDBMutableFile::CreateFileObject(mozilla::dom::FileHandle* aFileHandle, IDBMutableFile::CreateFileObject(IDBFileHandle* aFileHandle, uint32_t aFileSize)
uint32_t aFileSize)
{ {
nsCOMPtr<nsIDOMFile> file = new DOMFile( nsCOMPtr<nsIDOMFile> fileSnapshot = new DOMFile(
new FileImpl(mName, mType, aFileSize, mFile, aFileHandle, mFileInfo)); new FileImplSnapshot(mName, mType, aFileSize, mFile, aFileHandle,
mFileInfo));
return file.forget(); return fileSnapshot.forget();
} }
// virtual // virtual
@ -151,3 +192,78 @@ IDBMutableFile::WrapObject(JSContext* aCx)
{ {
return IDBMutableFileBinding::Wrap(aCx, this); 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__ #ifndef mozilla_dom_indexeddb_idbmutablefile_h__
#define mozilla_dom_indexeddb_idbmutablefile_h__ #define mozilla_dom_indexeddb_idbmutablefile_h__
#include "IndexedDatabase.h" #include "js/TypeDecls.h"
#include "MainThreadUtils.h" #include "MainThreadUtils.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/dom/FileModeBinding.h"
#include "mozilla/dom/indexedDB/FileInfo.h" #include "mozilla/dom/indexedDB/FileInfo.h"
#include "mozilla/dom/MutableFile.h" #include "mozilla/dom/MutableFile.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
BEGIN_INDEXEDDB_NAMESPACE class nsIDOMFile;
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
namespace dom {
class DOMRequest;
namespace indexedDB {
class IDBDatabase; class IDBDatabase;
class IDBFileHandle;
class IDBMutableFile : public MutableFile class IDBMutableFile MOZ_FINAL : public DOMEventTargetHelper,
public MutableFileBase
{ {
typedef mozilla::dom::FileHandle FileHandle;
public: public:
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBMutableFile, MutableFile) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBMutableFile, DOMEventTargetHelper)
static already_AddRefed<IDBMutableFile> static already_AddRefed<IDBMutableFile>
Create(const nsAString& aName, const nsAString& aType, Create(const nsAString& aName, const nsAString& aType,
IDBDatabase* aDatabase, already_AddRefed<FileInfo> aFileInfo); IDBDatabase* aDatabase, already_AddRefed<FileInfo> aFileInfo);
const nsAString&
Name() const
{
return mName;
}
virtual int64_t const nsAString&
GetFileId() MOZ_OVERRIDE Type() const
{
return mType;
}
int64_t
GetFileId() const
{ {
return mFileInfo->Id(); return mFileInfo->Id();
} }
virtual FileInfo* FileInfo*
GetFileInfo() MOZ_OVERRIDE GetFileInfo() const
{ {
return mFileInfo; return mFileInfo;
} }
virtual bool
IsShuttingDown() MOZ_OVERRIDE;
virtual bool virtual bool
IsInvalid() MOZ_OVERRIDE; IsInvalid() MOZ_OVERRIDE;
@ -56,7 +77,7 @@ public:
Storage() MOZ_OVERRIDE; Storage() MOZ_OVERRIDE;
virtual already_AddRefed<nsISupports> virtual already_AddRefed<nsISupports>
CreateStream(nsIFile* aFile, bool aReadOnly) MOZ_OVERRIDE; CreateStream(bool aReadOnly) MOZ_OVERRIDE;
virtual void virtual void
SetThreadLocals() MOZ_OVERRIDE; SetThreadLocals() MOZ_OVERRIDE;
@ -64,14 +85,32 @@ public:
virtual void virtual void
UnsetThreadLocals() MOZ_OVERRIDE; UnsetThreadLocals() MOZ_OVERRIDE;
virtual already_AddRefed<nsIDOMFile> already_AddRefed<nsIDOMFile>
CreateFileObject(FileHandle* aFileHandle, uint32_t aFileSize) MOZ_OVERRIDE; CreateFileObject(IDBFileHandle* aFileHandle, uint32_t aFileSize);
// nsWrapperCache // nsWrapperCache
virtual JSObject* virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE; WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL // WebIDL
nsPIDOMWindow*
GetParentObject() const
{
return GetOwner();
}
void
GetName(nsString& aName) const
{
aName = mName;
}
void
GetType(nsString& aType) const
{
aType = mType;
}
IDBDatabase* IDBDatabase*
Database() Database()
{ {
@ -80,17 +119,28 @@ public:
return mDatabase; 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: private:
IDBMutableFile(IDBDatabase* aOwner); IDBMutableFile(IDBDatabase* aOwner);
~IDBMutableFile();
~IDBMutableFile() nsString mName;
{ nsString mType;
}
nsRefPtr<IDBDatabase> mDatabase; nsRefPtr<IDBDatabase> mDatabase;
nsRefPtr<FileInfo> mFileInfo; nsRefPtr<FileInfo> mFileInfo;
}; };
END_INDEXEDDB_NAMESPACE } // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbmutablefile_h__ #endif // mozilla_dom_indexeddb_idbmutablefile_h__

View File

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

View File

@ -12,10 +12,13 @@ EXPORTS.mozilla.dom.indexedDB += [
'DatabaseInfo.h', 'DatabaseInfo.h',
'FileInfo.h', 'FileInfo.h',
'FileManager.h', 'FileManager.h',
'FileSnapshot.h',
'IDBCursor.h', 'IDBCursor.h',
'IDBDatabase.h', 'IDBDatabase.h',
'IDBEvents.h', 'IDBEvents.h',
'IDBFactory.h', 'IDBFactory.h',
'IDBFileHandle.h',
'IDBFileRequest.h',
'IDBIndex.h', 'IDBIndex.h',
'IDBKeyRange.h', 'IDBKeyRange.h',
'IDBMutableFile.h', 'IDBMutableFile.h',
@ -36,9 +39,12 @@ UNIFIED_SOURCES += [
'DatabaseInfo.cpp', 'DatabaseInfo.cpp',
'FileInfo.cpp', 'FileInfo.cpp',
'FileManager.cpp', 'FileManager.cpp',
'FileSnapshot.cpp',
'IDBDatabase.cpp', 'IDBDatabase.cpp',
'IDBEvents.cpp', 'IDBEvents.cpp',
'IDBFactory.cpp', 'IDBFactory.cpp',
'IDBFileHandle.cpp',
'IDBFileRequest.cpp',
'IDBKeyRange.cpp', 'IDBKeyRange.cpp',
'IDBMutableFile.cpp', 'IDBMutableFile.cpp',
'IDBRequest.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) function getView(size)
{ {
let buffer = new ArrayBuffer(size); let buffer = new ArrayBuffer(size);

View File

@ -3,6 +3,7 @@ support-files =
bfcache_iframe1.html bfcache_iframe1.html
bfcache_iframe2.html bfcache_iframe2.html
blob_worker_crash_iframe.html blob_worker_crash_iframe.html
dummy_worker.js
error_events_abort_transactions_iframe.html error_events_abort_transactions_iframe.html
event_propagation_iframe.html event_propagation_iframe.html
exceptions_in_events_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 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_file_transaction_abort.html] [test_file_transaction_abort.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage 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] [test_filehandle_quota.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage 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] [test_filehandle_serialization.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_filehandle_store_snapshot.html] [test_filehandle_store_snapshot.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage 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] [test_getAll.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_getFileId.html]
[test_get_filehandle.html] [test_get_filehandle.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_globalObjects_content.html] [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; yield undefined;
} }
</script> </script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script> <script type="text/javascript;version=1.7" src="helpers.js"></script>
</head> </head>

View File

@ -369,14 +369,10 @@ var interfaceNamesInGlobalScope =
{name: "External", b2g: false}, {name: "External", b2g: false},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
"File", "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! // IMPORTANT: Do not change this list without review from a DOM peer!
"FileList", "FileList",
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
"FileReader", "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! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "FMRadio", b2g: true}, {name: "FMRadio", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
@ -565,6 +561,10 @@ var interfaceNamesInGlobalScope =
"IDBDatabase", "IDBDatabase",
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
"IDBFactory", "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! // IMPORTANT: Do not change this list without review from a DOM peer!
"IDBIndex", "IDBIndex",
// IMPORTANT: Do not change this list without review from a DOM peer! // 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"}, {name: "MozWifiP2pManager", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozWifiP2pStatusChangeEvent", b2g: true, permission: "wifi-manage"}, {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! // IMPORTANT: Do not change this list without review from a DOM peer!
"MutationEvent", "MutationEvent",
// IMPORTANT: Do not change this list without review from a DOM peer! // 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
interface FileRequest : DOMRequest { interface IDBFileRequest : DOMRequest {
readonly attribute FileHandle? fileHandle; readonly attribute IDBFileHandle? fileHandle;
// this is deprecated due to renaming in the spec // this is deprecated due to renaming in the spec
readonly attribute FileHandle? lockedFile; // now fileHandle readonly attribute IDBFileHandle? lockedFile; // now fileHandle
attribute EventHandler onprogress; attribute EventHandler onprogress;
}; };

View File

@ -3,6 +3,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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; 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', 'EventSource.webidl',
'EventTarget.webidl', 'EventTarget.webidl',
'File.webidl', 'File.webidl',
'FileHandle.webidl',
'FileList.webidl', 'FileList.webidl',
'FileMode.webidl', 'FileMode.webidl',
'FileReader.webidl', 'FileReader.webidl',
'FileReaderSync.webidl', 'FileReaderSync.webidl',
'FileRequest.webidl',
'FocusEvent.webidl', 'FocusEvent.webidl',
'FormData.webidl', 'FormData.webidl',
'Function.webidl', 'Function.webidl',
@ -211,6 +209,8 @@ WEBIDL_FILES = [
'IDBDatabase.webidl', 'IDBDatabase.webidl',
'IDBEnvironment.webidl', 'IDBEnvironment.webidl',
'IDBFactory.webidl', 'IDBFactory.webidl',
'IDBFileHandle.webidl',
'IDBFileRequest.webidl',
'IDBIndex.webidl', 'IDBIndex.webidl',
'IDBKeyRange.webidl', 'IDBKeyRange.webidl',
'IDBMutableFile.webidl', 'IDBMutableFile.webidl',
@ -261,7 +261,6 @@ WEBIDL_FILES = [
'MozPowerManager.webidl', 'MozPowerManager.webidl',
'MozTimeManager.webidl', 'MozTimeManager.webidl',
'MozWakeLock.webidl', 'MozWakeLock.webidl',
'MutableFile.webidl',
'MutationEvent.webidl', 'MutationEvent.webidl',
'MutationObserver.webidl', 'MutationObserver.webidl',
'NativeOSFileInternals.webidl', 'NativeOSFileInternals.webidl',