--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ b/dom/devicestorage/DeviceStorageRequestChild.cpp
@@ -2,16 +2,17 @@
/* 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 "DeviceStorageRequestChild.h"
#include "nsDeviceStorage.h"
#include "nsDOMFile.h"
+#include "mozilla/dom/ipc/Blob.h"
namespace mozilla {
namespace dom {
namespace devicestorage {
DeviceStorageRequestChild::DeviceStorageRequestChild()
{
MOZ_COUNT_CTOR(DeviceStorageRequestChild);
@@ -23,16 +24,17 @@ DeviceStorageRequestChild::DeviceStorage
, mFile(aFile)
{
MOZ_COUNT_CTOR(DeviceStorageRequestChild);
}
DeviceStorageRequestChild::~DeviceStorageRequestChild() {
MOZ_COUNT_DTOR(DeviceStorageRequestChild);
}
+
bool
DeviceStorageRequestChild::Recv__delete__(const DeviceStorageResponseValue& aValue)
{
switch (aValue.type()) {
case DeviceStorageResponseValue::TErrorResponse:
{
ErrorResponse r = aValue;
@@ -45,29 +47,18 @@ DeviceStorageRequestChild::Recv__delete_
jsval result = StringToJsval(mRequest->GetOwner(), mFile->mPath);
mRequest->FireSuccess(result);
break;
}
case DeviceStorageResponseValue::TBlobResponse:
{
BlobResponse r = aValue;
-
- // I am going to hell for this. bent says he'll save me.
- const InfallibleTArray<PRUint8> bits = r.bits();
- void* buffer = PR_Malloc(bits.Length());
- memcpy(buffer, (void*) bits.Elements(), bits.Length());
-
- nsString mimeType;
- mimeType.AssignWithConversion(r.contentType());
-
- nsCOMPtr<nsIDOMBlob> blob = new nsDOMMemoryFile(buffer,
- bits.Length(),
- mFile->mPath,
- mimeType);
+ BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
+ nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
jsval result = BlobToJsval(mRequest->GetOwner(), blob);
mRequest->FireSuccess(result);
break;
}
case DeviceStorageResponseValue::TEnumerationResponse:
{
@@ -75,17 +66,17 @@ DeviceStorageRequestChild::Recv__delete_
nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
PRUint32 count = r.paths().Length();
for (PRUint32 i = 0; i < count; i++) {
nsCOMPtr<nsIFile> f;
NS_NewLocalFile(r.paths()[i].fullpath(), false, getter_AddRefs(f));
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(f);
- dsf->SetPath(r.paths()[i].path());
+ dsf->SetPath(r.paths()[i].name());
cursor->mFiles.AppendElement(dsf);
}
nsCOMPtr<ContinueCursorEvent> event = new ContinueCursorEvent(cursor);
NS_DispatchToMainThread(event);
break;
}
--- a/dom/devicestorage/DeviceStorageRequestParent.cpp
+++ b/dom/devicestorage/DeviceStorageRequestParent.cpp
@@ -3,16 +3,19 @@
* 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 "DeviceStorageRequestParent.h"
#include "nsDOMFile.h"
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
#include "mozilla/unused.h"
+#include "mozilla/dom/ipc/Blob.h"
+#include "ContentParent.h"
+#include "nsProxyRelease.h"
namespace mozilla {
namespace dom {
namespace devicestorage {
DeviceStorageRequestParent::DeviceStorageRequestParent(const DeviceStorageParams& aParams)
{
MOZ_COUNT_CTOR(DeviceStorageRequestParent);
@@ -21,65 +24,73 @@ DeviceStorageRequestParent::DeviceStorag
case DeviceStorageParams::TDeviceStorageAddParams:
{
DeviceStorageAddParams p = aParams;
nsCOMPtr<nsIFile> f;
NS_NewLocalFile(p.fullpath(), false, getter_AddRefs(f));
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(f);
- nsRefPtr<WriteFileEvent> r = new WriteFileEvent(this, dsf, p.bits());
+
+ BlobParent* bp = static_cast<BlobParent*>(p.blobParent());
+ nsCOMPtr<nsIDOMBlob> blob = bp->GetBlob();
+
+ nsCOMPtr<nsIInputStream> stream;
+ blob->GetInternalStream(getter_AddRefs(stream));
+
+ nsRefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream);
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
target->Dispatch(r, NS_DISPATCH_NORMAL);
break;
}
case DeviceStorageParams::TDeviceStorageGetParams:
{
DeviceStorageGetParams p = aParams;
nsCOMPtr<nsIFile> f;
NS_NewLocalFile(p.fullpath(), false, getter_AddRefs(f));
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(f);
- nsRefPtr<ReadFileEvent> r = new ReadFileEvent(this, dsf);
+ dsf->SetPath(p.name());
+ nsRefPtr<CancelableRunnable> r = new ReadFileEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
target->Dispatch(r, NS_DISPATCH_NORMAL);
break;
}
case DeviceStorageParams::TDeviceStorageDeleteParams:
{
DeviceStorageDeleteParams p = aParams;
nsCOMPtr<nsIFile> f;
NS_NewLocalFile(p.fullpath(), false, getter_AddRefs(f));
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(f);
- nsRefPtr<DeleteFileEvent> r = new DeleteFileEvent(this, dsf);
+ nsRefPtr<CancelableRunnable> r = new DeleteFileEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
target->Dispatch(r, NS_DISPATCH_NORMAL);
break;
}
case DeviceStorageParams::TDeviceStorageEnumerationParams:
{
DeviceStorageEnumerationParams p = aParams;
nsCOMPtr<nsIFile> f;
NS_NewLocalFile(p.fullpath(), false, getter_AddRefs(f));
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(f);
- nsRefPtr<EnumerateFileEvent> r = new EnumerateFileEvent(this, dsf, p.since());
+ nsRefPtr<CancelableRunnable> r = new EnumerateFileEvent(this, dsf, p.since());
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
target->Dispatch(r, NS_DISPATCH_NORMAL);
break;
}
default:
{
@@ -89,227 +100,251 @@ DeviceStorageRequestParent::DeviceStorag
}
}
DeviceStorageRequestParent::~DeviceStorageRequestParent()
{
MOZ_COUNT_DTOR(DeviceStorageRequestParent);
}
+NS_IMPL_THREADSAFE_ADDREF(DeviceStorageRequestParent);
+NS_IMPL_THREADSAFE_RELEASE(DeviceStorageRequestParent);
+
+void
+DeviceStorageRequestParent::ActorDestroy(ActorDestroyReason)
+{
+ PRInt32 count = mRunnables.Length();
+ for (PRInt32 index = 0; index < count; index++) {
+ mRunnables[index]->Cancel();
+ }
+}
+
DeviceStorageRequestParent::PostErrorEvent::PostErrorEvent(DeviceStorageRequestParent* aParent,
const char* aError)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
{
- mError.AssignWithConversion(aError);
+ CopyASCIItoUTF16(aError, mError);
}
DeviceStorageRequestParent::PostErrorEvent::~PostErrorEvent() {}
-NS_IMETHODIMP
-DeviceStorageRequestParent::PostErrorEvent::Run() {
+nsresult
+DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
ErrorResponse response(mError);
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
DeviceStorageRequestParent::PostSuccessEvent::PostSuccessEvent(DeviceStorageRequestParent* aParent)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
{
}
DeviceStorageRequestParent::PostSuccessEvent::~PostSuccessEvent() {}
-NS_IMETHODIMP
-DeviceStorageRequestParent::PostSuccessEvent::Run() {
+nsresult
+DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
SuccessResponse response;
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
DeviceStorageRequestParent::PostBlobSuccessEvent::PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
- void* aBuffer,
+ DeviceStorageFile* aFile,
PRUint32 aLength,
nsACString& aMimeType)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
+ , mLength(aLength)
+ , mFile(aFile)
, mMimeType(aMimeType)
{
- mBits.SetCapacity(aLength);
- void* bits = mBits.Elements();
- memcpy(bits, aBuffer, aLength);
}
DeviceStorageRequestParent::PostBlobSuccessEvent::~PostBlobSuccessEvent() {}
-NS_IMETHODIMP
-DeviceStorageRequestParent::PostBlobSuccessEvent::Run() {
+nsresult
+DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
- BlobResponse response(mBits, mMimeType);
+ nsString mime;
+ mime.AssignWithConversion(mMimeType);
+ CopyASCIItoUTF16(mMimeType, mime);
+
+ nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(mFile->mPath, mime, mLength, mFile->mFile);
+
+ ContentParent* cp = static_cast<ContentParent*>(mParent->Manager());
+ BlobParent* actor = cp->GetOrCreateActorForBlob(blob);
+
+ BlobResponse response;
+ response.blobParent() = actor;
+
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
DeviceStorageRequestParent::PostEnumerationSuccessEvent::PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent,
InfallibleTArray<DeviceStorageFileValue>& aPaths)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
, mPaths(aPaths)
{
}
DeviceStorageRequestParent::PostEnumerationSuccessEvent::~PostEnumerationSuccessEvent() {}
-NS_IMETHODIMP
-DeviceStorageRequestParent::PostEnumerationSuccessEvent::Run() {
+nsresult
+DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
EnumerationResponse response(mPaths);
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
DeviceStorageRequestParent::WriteFileEvent::WriteFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile,
- InfallibleTArray<PRUint8>& aBits)
- : mParent(aParent)
+ nsIInputStream* aInputStream)
+ : CancelableRunnable(aParent)
, mFile(aFile)
- , mBits(aBits)
+ , mInputStream(aInputStream)
{
}
DeviceStorageRequestParent::WriteFileEvent::~WriteFileEvent()
{
}
-NS_IMETHODIMP
-DeviceStorageRequestParent::WriteFileEvent::Run()
+nsresult
+DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
{
+ NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
nsRefPtr<nsRunnable> r;
- nsresult rv = mFile->Write(mBits);
+
+ if (!mInputStream) {
+ r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
+ NS_DispatchToMainThread(r);
+ return NS_OK;
+ }
+
+ nsresult rv = mFile->Write(mInputStream);
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
}
else {
r = new PostPathResultEvent(mParent, mFile->mPath);
}
NS_DispatchToMainThread(r);
return NS_OK;
}
DeviceStorageRequestParent::DeleteFileEvent::DeleteFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::DeleteFileEvent::~DeleteFileEvent()
{
}
-NS_IMETHODIMP
-DeviceStorageRequestParent::DeleteFileEvent::Run()
+nsresult
+DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
mFile->mFile->Remove(true);
nsRefPtr<nsRunnable> r;
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
}
else {
r = new PostPathResultEvent(mParent, mFile->mPath);
}
+
NS_DispatchToMainThread(r);
return NS_OK;
}
DeviceStorageRequestParent::ReadFileEvent::ReadFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
, mFile(aFile)
{
nsCOMPtr<nsIMIMEService> mimeService = do_GetService(NS_MIMESERVICE_CONTRACTID);
if (mimeService) {
nsresult rv = mimeService->GetTypeFromFile(mFile->mFile, mMimeType);
if (NS_FAILED(rv)) {
mMimeType.Truncate();
}
}
}
DeviceStorageRequestParent::ReadFileEvent::~ReadFileEvent()
{
}
-NS_IMETHODIMP
-DeviceStorageRequestParent::ReadFileEvent::Run()
+nsresult
+DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
nsCOMPtr<nsIRunnable> r;
bool check = false;
mFile->mFile->Exists(&check);
+
if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
NS_DispatchToMainThread(r);
return NS_OK;
}
PRInt64 fileSize;
nsresult rv = mFile->mFile->GetFileSize(&fileSize);
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r);
return NS_OK;
}
-
- PRFileDesc *fileHandle;
- rv = mFile->mFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle);
- // i am going to hell. this is temp until bent provides seralizaiton of blobs.
- void* buf = (void*) malloc(fileSize);
- PRInt32 read = PR_Read(fileHandle, buf, fileSize);
- if (read != fileSize) {
- r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
- NS_DispatchToMainThread(r);
- return NS_OK;
- }
-
- r = new PostBlobSuccessEvent(mParent, buf, fileSize, mMimeType);
-
- PR_Free(buf);
- PR_Close(fileHandle);
-
+ r = new PostBlobSuccessEvent(mParent, mFile, fileSize, mMimeType);
NS_DispatchToMainThread(r);
return NS_OK;
}
DeviceStorageRequestParent::EnumerateFileEvent::EnumerateFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile,
PRUint32 aSince)
- : mParent(aParent)
+ : CancelableRunnable(aParent)
, mFile(aFile)
, mSince(aSince)
{
}
DeviceStorageRequestParent::EnumerateFileEvent::~EnumerateFileEvent()
{
}
-NS_IMETHODIMP
-DeviceStorageRequestParent::EnumerateFileEvent::Run()
+nsresult
+DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
nsCOMPtr<nsIRunnable> r;
bool check = false;
mFile->mFile->Exists(&check);
if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
NS_DispatchToMainThread(r);
return NS_OK;
}
@@ -318,39 +353,39 @@ DeviceStorageRequestParent::EnumerateFil
mFile->CollectFiles(files, mSince);
InfallibleTArray<DeviceStorageFileValue> values;
PRUint32 count = files.Length();
for (PRUint32 i = 0; i < count; i++) {
nsString fullpath;
files[i]->mFile->GetPath(fullpath);
- DeviceStorageFileValue dsvf(fullpath, files[i]->mPath);
+ DeviceStorageFileValue dsvf(files[i]->mPath, fullpath);
values.AppendElement(dsvf);
}
r = new PostEnumerationSuccessEvent(mParent, values);
NS_DispatchToMainThread(r);
return NS_OK;
}
DeviceStorageRequestParent::PostPathResultEvent::PostPathResultEvent(DeviceStorageRequestParent* aParent,
- const nsAString& aPath)
- : mParent(aParent)
+ const nsAString& aPath)
+ : CancelableRunnable(aParent)
, mPath(aPath)
{
}
DeviceStorageRequestParent::PostPathResultEvent::~PostPathResultEvent()
{
}
-NS_IMETHODIMP
-DeviceStorageRequestParent::PostPathResultEvent::Run()
+nsresult
+DeviceStorageRequestParent::PostPathResultEvent::CancelableRun()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
SuccessResponse response;
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
--- a/dom/devicestorage/DeviceStorageRequestParent.h
+++ b/dom/devicestorage/DeviceStorageRequestParent.h
@@ -6,131 +6,172 @@
#ifndef mozilla_dom_devicestorage_DeviceStorageRequestParent_h
#define mozilla_dom_devicestorage_DeviceStorageRequestParent_h
#include "mozilla/dom/devicestorage/PDeviceStorageRequestParent.h"
#include "mozilla/dom/ContentChild.h"
#include "nsThreadUtils.h"
#include "nsDeviceStorage.h"
+#include "nsTArray.h"
namespace mozilla {
namespace dom {
namespace devicestorage {
class DeviceStorageRequestParent : public PDeviceStorageRequestParent
{
public:
DeviceStorageRequestParent(const DeviceStorageParams& aParams);
+
+ NS_IMETHOD_(nsrefcnt) AddRef();
+ NS_IMETHOD_(nsrefcnt) Release();
+ virtual void ActorDestroy(ActorDestroyReason);
+
+protected:
~DeviceStorageRequestParent();
private:
- class PostErrorEvent : public nsRunnable
+ nsAutoRefCnt mRefCnt;
+
+ class CancelableRunnable : public nsRunnable
+ {
+ public:
+ CancelableRunnable(DeviceStorageRequestParent* aParent)
+ : mParent(aParent)
+ , mCanceled(false)
+ {
+ mParent->AddRunnable(this);
+ }
+
+ virtual ~CancelableRunnable() {
+ }
+
+ NS_IMETHOD Run() {
+ nsresult rv = NS_OK;
+ if (!mCanceled) {
+ rv = CancelableRun();
+ mParent->RemoveRunnable(this);
+ }
+ return rv;
+ }
+
+ void Cancel() {
+ mCanceled = true;
+ }
+
+ virtual nsresult CancelableRun() = 0;
+
+ protected:
+ nsRefPtr<DeviceStorageRequestParent> mParent;
+ private:
+ bool mCanceled;
+ };
+
+ class PostErrorEvent : public CancelableRunnable
{
public:
PostErrorEvent(DeviceStorageRequestParent* aParent, const char* aError);
- ~PostErrorEvent();
- NS_IMETHOD Run();
+ virtual ~PostErrorEvent();
+ virtual nsresult CancelableRun();
private:
- DeviceStorageRequestParent* mParent;
nsString mError;
};
- class PostSuccessEvent : public nsRunnable
+ class PostSuccessEvent : public CancelableRunnable
{
public:
PostSuccessEvent(DeviceStorageRequestParent* aParent);
- ~PostSuccessEvent();
- NS_IMETHOD Run();
- private:
- DeviceStorageRequestParent* mParent;
- };
-
- class PostBlobSuccessEvent : public nsRunnable
- {
- public:
- PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, void* aBuffer, PRUint32 aLength, nsACString& aMimeType);
- ~PostBlobSuccessEvent();
- NS_IMETHOD Run();
- private:
- DeviceStorageRequestParent* mParent;
- InfallibleTArray<PRUint8> mBits;
- nsCString mMimeType;
- };
-
- class PostEnumerationSuccessEvent : public nsRunnable
- {
- public:
- PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent, InfallibleTArray<DeviceStorageFileValue>& aPaths);
- ~PostEnumerationSuccessEvent();
- NS_IMETHOD Run();
- private:
- DeviceStorageRequestParent* mParent;
- InfallibleTArray<DeviceStorageFileValue> mPaths;
+ virtual ~PostSuccessEvent();
+ virtual nsresult CancelableRun();
};
- class WriteFileEvent : public nsRunnable
- {
- public:
- WriteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, InfallibleTArray<PRUint8>& aBits);
- ~WriteFileEvent();
- NS_IMETHOD Run();
- private:
- DeviceStorageRequestParent* mParent;
- nsRefPtr<DeviceStorageFile> mFile;
- InfallibleTArray<PRUint8> mBits; // another copy?
- };
-
- class DeleteFileEvent : public nsRunnable
+ class PostBlobSuccessEvent : public CancelableRunnable
{
public:
- DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
- ~DeleteFileEvent();
- NS_IMETHOD Run();
+ PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, PRUint32 aLength, nsACString& aMimeType);
+ virtual ~PostBlobSuccessEvent();
+ virtual nsresult CancelableRun();
private:
- DeviceStorageRequestParent* mParent;
- nsRefPtr<DeviceStorageFile> mFile;
- };
-
- class ReadFileEvent : public nsRunnable
- {
- public:
- ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
- ~ReadFileEvent();
- NS_IMETHOD Run();
- private:
- DeviceStorageRequestParent* mParent;
+ PRUint32 mLength;
nsRefPtr<DeviceStorageFile> mFile;
nsCString mMimeType;
};
- class EnumerateFileEvent : public nsRunnable
+ class PostEnumerationSuccessEvent : public CancelableRunnable
+ {
+ public:
+ PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent, InfallibleTArray<DeviceStorageFileValue>& aPaths);
+ virtual ~PostEnumerationSuccessEvent();
+ virtual nsresult CancelableRun();
+ private:
+ InfallibleTArray<DeviceStorageFileValue> mPaths;
+ };
+
+ class WriteFileEvent : public CancelableRunnable
+ {
+ public:
+ WriteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, nsIInputStream* aInputStream);
+ virtual ~WriteFileEvent();
+ virtual nsresult CancelableRun();
+ private:
+ nsRefPtr<DeviceStorageFile> mFile;
+ nsCOMPtr<nsIInputStream> mInputStream;
+ };
+
+ class DeleteFileEvent : public CancelableRunnable
+ {
+ public:
+ DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
+ virtual ~DeleteFileEvent();
+ virtual nsresult CancelableRun();
+ private:
+ nsRefPtr<DeviceStorageFile> mFile;
+ };
+
+ class ReadFileEvent : public CancelableRunnable
+ {
+ public:
+ ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
+ virtual ~ReadFileEvent();
+ virtual nsresult CancelableRun();
+ private:
+ nsRefPtr<DeviceStorageFile> mFile;
+ nsCString mMimeType;
+ };
+
+ class EnumerateFileEvent : public CancelableRunnable
{
public:
EnumerateFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, PRUint32 aSince);
- ~EnumerateFileEvent();
- NS_IMETHOD Run();
+ virtual ~EnumerateFileEvent();
+ virtual nsresult CancelableRun();
private:
- DeviceStorageRequestParent* mParent;
nsRefPtr<DeviceStorageFile> mFile;
PRUint32 mSince;
};
- class PostPathResultEvent : public nsRunnable
+ class PostPathResultEvent : public CancelableRunnable
{
public:
PostPathResultEvent(DeviceStorageRequestParent* aParent, const nsAString& aPath);
- ~PostPathResultEvent();
- NS_IMETHOD Run();
+ virtual ~PostPathResultEvent();
+ virtual nsresult CancelableRun();
private:
- DeviceStorageRequestParent* mParent;
nsRefPtr<DeviceStorageFile> mFile;
- InfallibleTArray<PRUint8> mBits;
nsString mPath;
};
+protected:
+ void AddRunnable(CancelableRunnable* aRunnable) {
+ mRunnables.AppendElement(aRunnable);
+ }
+ void RemoveRunnable(CancelableRunnable* aRunnable) {
+ mRunnables.RemoveElement(aRunnable);
+ }
+ nsTArray<nsRefPtr<CancelableRunnable> > mRunnables;
};
} // namespace devicestorage
} // namespace dom
} // namespace mozilla
#endif
--- a/dom/devicestorage/PDeviceStorageRequest.ipdl
+++ b/dom/devicestorage/PDeviceStorageRequest.ipdl
@@ -1,13 +1,14 @@
/* -*- Mode: C++; tab-width: 8; 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/. */
+include protocol PBlob;
include protocol PContent;
namespace mozilla {
namespace dom {
namespace devicestorage {
struct ErrorResponse
@@ -16,32 +17,28 @@ struct ErrorResponse
};
struct SuccessResponse
{
};
struct BlobResponse
{
- // todo going away
- PRUint8[] bits;
- nsCString contentType;
+ PBlob blob;
};
struct DeviceStorageFileValue
{
- // todo going away
+ nsString name;
nsString fullpath;
- nsString path;
};
struct EnumerationResponse
{
DeviceStorageFileValue[] paths;
- // todo bent PBlob
};
union DeviceStorageResponseValue
{
ErrorResponse;
SuccessResponse;
BlobResponse;
EnumerationResponse;
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -1,14 +1,15 @@
/* 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 "mozilla/dom/ContentChild.h"
#include "mozilla/dom/PBrowserChild.h"
+#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/PContentPermissionRequestChild.h"
#include "nsDeviceStorage.h"
#include "nsDOMEvent.h"
#include "nsServiceManagerUtils.h"
@@ -141,27 +142,29 @@ DeviceStorageFile::AppendRelativePath()
}
mFile->AppendRelativePath(temp);
#else
mFile->AppendRelativePath(mPath);
#endif
}
nsresult
-DeviceStorageFile::Write(nsIDOMBlob* aBlob)
+DeviceStorageFile::Write(nsIInputStream* aInputStream)
{
+ if (!aInputStream) {
+ return NS_ERROR_FAILURE;
+ }
+
nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
if (NS_FAILED(rv)) {
return rv;
}
- nsCOMPtr<nsIInputStream> stream;
- aBlob->GetInternalStream(getter_AddRefs(stream));
PRUint32 bufSize;
- stream->Available(&bufSize);
+ aInputStream->Available(&bufSize);
nsCOMPtr<nsIOutputStream> outputStream;
NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile);
if (!outputStream) {
return NS_ERROR_FAILURE;
}
@@ -170,17 +173,17 @@ DeviceStorageFile::Write(nsIDOMBlob* aBl
outputStream,
4096*4);
if (!bufferedOutputStream) {
return NS_ERROR_FAILURE;
}
PRUint32 wrote;
- bufferedOutputStream->WriteFrom(stream, bufSize, &wrote);
+ bufferedOutputStream->WriteFrom(aInputStream, bufSize, &wrote);
bufferedOutputStream->Close();
outputStream->Close();
if (bufSize != wrote) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
@@ -527,17 +530,16 @@ public:
else {
mError.Append(NS_LITERAL_STRING("null path"));
}
}
NS_IMETHOD Run()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
mRequest->FireError(mError);
mRequest = nullptr;
return NS_OK;
}
private:
nsRefPtr<DOMRequest> mRequest;
nsString mError;
@@ -555,17 +557,16 @@ ContinueCursorEvent::ContinueCursorEvent
ContinueCursorEvent::~ContinueCursorEvent() {}
NS_IMETHODIMP
ContinueCursorEvent::Run() {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
jsval val;
-
nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
if (cursor->mFiles.Length() == 0) {
val = JSVAL_NULL;
}
else {
nsRefPtr<DeviceStorageFile> file = cursor->mFiles[0];
cursor->mFiles.RemoveElementAt(0);
@@ -813,17 +814,20 @@ public:
}
~WriteFileEvent() {}
NS_IMETHOD Run()
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
- nsresult rv = mFile->Write(mBlob);
+ nsCOMPtr<nsIInputStream> stream;
+ mBlob->GetInternalStream(getter_AddRefs(stream));
+
+ nsresult rv = mFile->Write(stream);
if (NS_FAILED(rv)) {
mFile->mFile->Remove(false);
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
POST_ERROR_EVENT_UNKNOWN,
mFile);
NS_DispatchToMainThread(event);
@@ -854,17 +858,16 @@ public:
~ReadFileEvent() {}
NS_IMETHOD Run()
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
nsRefPtr<nsRunnable> r;
-
if (!mFile->mEditable) {
bool check = false;
mFile->mFile->Exists(&check);
if (!check) {
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST, mFile);
}
}
@@ -898,17 +901,17 @@ public:
mFile->mFile->Remove(true);
nsRefPtr<nsRunnable> r;
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
- r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_UNKNOWN, mFile);
+ r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST, mFile);
}
else {
r = new PostResultEvent(mRequest, mFile->mPath);
}
NS_DispatchToMainThread(r);
return NS_OK;
}
@@ -1048,44 +1051,40 @@ public:
switch(mRequestType) {
case DEVICE_STORAGE_REQUEST_WRITE:
{
if (!mBlob) {
return NS_ERROR_FAILURE;
}
if (XRE_GetProcessType() != GeckoProcessType_Default) {
- PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, mFile);
- nsCOMPtr<nsIInputStream> stream;
- mBlob->GetInternalStream(getter_AddRefs(stream));
-
- InfallibleTArray<PRUint8> bits;
- PRUint32 bufSize, numRead;
+ BlobChild* actor = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mBlob);
+ if (!actor) {
+ return NS_ERROR_FAILURE;
+ }
- stream->Available(&bufSize);
- bits.SetCapacity(bufSize);
+ DeviceStorageAddParams params;
+ params.blobChild() = actor;
+ params.name() = mFile->mPath;
+ params.fullpath() = fullpath;
- void* buffer = (void*) bits.Elements();
-
- stream->Read((char*)buffer, bufSize, &numRead);
-
- DeviceStorageAddParams params(fullpath, bits);
+ PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, mFile);
ContentChild::GetSingleton()->SendPDeviceStorageRequestConstructor(child, params);
return NS_OK;
}
r = new WriteFileEvent(mBlob, mFile, mRequest);
break;
}
case DEVICE_STORAGE_REQUEST_READ:
{
if (XRE_GetProcessType() != GeckoProcessType_Default) {
PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, mFile);
- DeviceStorageGetParams params(fullpath);
+ DeviceStorageGetParams params(mFile->mPath, fullpath);
ContentChild::GetSingleton()->SendPDeviceStorageRequestConstructor(child, params);
return NS_OK;
}
r = new ReadFileEvent(mFile, mRequest);
break;
}
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -48,18 +48,18 @@ public:
void SetPath(const nsAString& aPath);
void SetEditable(bool aEditable);
NS_DECL_ISUPPORTS
// we want to make sure that the names of file can't reach
// outside of the type of storage the user asked for.
bool IsSafePath();
-
- nsresult Write(nsIDOMBlob* blob);
+
+ nsresult Write(nsIInputStream* aInputStream);
nsresult Write(InfallibleTArray<PRUint8>& bits);
void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRUint64 aSince = 0);
void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRUint64 aSince, nsAString& aRootPath);
private:
void NormalizeFilePath();
void AppendRelativePath();
};
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -957,23 +957,26 @@ ContentParent::DeallocPBrowser(PBrowserP
TabParent* parent = static_cast<TabParent*>(frame);
NS_RELEASE(parent);
return true;
}
PDeviceStorageRequestParent*
ContentParent::AllocPDeviceStorageRequest(const DeviceStorageParams& aParams)
{
- return new DeviceStorageRequestParent(aParams);
+ DeviceStorageRequestParent* result = new DeviceStorageRequestParent(aParams);
+ NS_ADDREF(result);
+ return result;
}
bool
ContentParent::DeallocPDeviceStorageRequest(PDeviceStorageRequestParent* doomed)
{
- delete doomed;
+ DeviceStorageRequestParent *parent = static_cast<DeviceStorageRequestParent*>(doomed);
+ NS_RELEASE(parent);
return true;
}
PBlobParent*
ContentParent::AllocPBlob(const BlobConstructorParams& aParams)
{
return BlobParent::Create(aParams);
}
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -68,22 +68,24 @@ struct FontListEntry {
PRUint16 weight;
PRInt16 stretch;
PRUint8 italic;
PRUint8 index;
};
struct DeviceStorageAddParams
{
+ PBlob blob;
+ nsString name;
nsString fullpath;
- PRUint8[] bits;
};
struct DeviceStorageGetParams
{
+ nsString name;
nsString fullpath;
};
struct DeviceStorageDeleteParams
{
nsString fullpath;
};