gecko/dom/file/ArchiveRequest.cpp
Ryan VanderMeulen 252154d12a Backed out 12 changesets (bug 899367) for Windows and OSX mochitest failures on a CLOSED TREE.
Backed out changeset 46cf4c3eb447 (bug 899367)
Backed out changeset d8a876219fc7 (bug 899367)
Backed out changeset d930333f95a7 (bug 899367)
Backed out changeset efae8cc0fff8 (bug 899367)
Backed out changeset 1dd262d146a6 (bug 899367)
Backed out changeset 4c396b8a51d0 (bug 899367)
Backed out changeset c8c30176639a (bug 899367)
Backed out changeset aaa8fbcf9aaf (bug 899367)
Backed out changeset d1a782044a4b (bug 899367)
Backed out changeset b2672ab55046 (bug 899367)
Backed out changeset fc4deb0b06fa (bug 899367)
Backed out changeset b9f1018a609c (bug 899367)
2013-08-27 21:14:54 -04:00

278 lines
6.5 KiB
C++

/* -*- 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 "ArchiveRequest.h"
#include "mozilla/dom/ArchiveRequestBinding.h"
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsEventDispatcher.h"
USING_FILE_NAMESPACE
/**
* Class used to make asynchronous the ArchiveRequest.
*/
class ArchiveRequestEvent : public nsRunnable
{
public:
NS_DECL_NSIRUNNABLE
ArchiveRequestEvent(ArchiveRequest* request)
: mRequest(request)
{
MOZ_COUNT_CTOR(ArchiveRequestEvent);
}
~ArchiveRequestEvent()
{
MOZ_COUNT_DTOR(ArchiveRequestEvent);
}
private: //data
nsRefPtr<ArchiveRequest> mRequest;
};
NS_IMETHODIMP
ArchiveRequestEvent::Run()
{
NS_ABORT_IF_FALSE(mRequest, "the request is not longer valid");
mRequest->Run();
return NS_OK;
}
// ArchiveRequest
ArchiveRequest::ArchiveRequest(nsIDOMWindow* aWindow,
ArchiveReader* aReader)
: DOMRequest(aWindow),
mArchiveReader(aReader)
{
MOZ_ASSERT(aReader);
MOZ_COUNT_CTOR(ArchiveRequest);
/* An event to make this request asynchronous: */
nsRefPtr<ArchiveRequestEvent> event = new ArchiveRequestEvent(this);
NS_DispatchToCurrentThread(event);
}
ArchiveRequest::~ArchiveRequest()
{
MOZ_COUNT_DTOR(ArchiveRequest);
}
nsresult
ArchiveRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = true;
aVisitor.mParentTarget = nullptr;
return NS_OK;
}
/* virtual */ JSObject*
ArchiveRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return ArchiveRequestBinding::Wrap(aCx, aScope, this);
}
ArchiveReader*
ArchiveRequest::Reader() const
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return mArchiveReader;
}
// Here the request is processed:
void
ArchiveRequest::Run()
{
// Register this request to the reader.
// When the reader is ready to return data, a 'Ready()' will be called
nsresult rv = mArchiveReader->RegisterRequest(this);
if (NS_FAILED(rv)) {
FireError(rv);
}
}
void
ArchiveRequest::OpGetFilenames()
{
mOperation = GetFilenames;
}
void
ArchiveRequest::OpGetFile(const nsAString& aFilename)
{
mOperation = GetFile;
mFilename = aFilename;
}
void
ArchiveRequest::OpGetFiles()
{
mOperation = GetFiles;
}
nsresult
ArchiveRequest::ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
nsresult aStatus)
{
if (NS_FAILED(aStatus)) {
FireError(aStatus);
return NS_OK;
}
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_STATE(sc);
AutoPushJSContext cx(sc->GetNativeContext());
NS_ASSERTION(cx, "Failed to get a context!");
JS::Rooted<JSObject*> global(cx, sc->GetNativeGlobal());
NS_ASSERTION(global, "Failed to get global object!");
JSAutoCompartment ac(cx, global);
JS::Rooted<JS::Value> result(cx);
switch (mOperation) {
case GetFilenames:
rv = GetFilenamesResult(cx, result.address(), aFileList);
break;
case GetFile:
rv = GetFileResult(cx, result.address(), aFileList);
break;
case GetFiles:
rv = GetFilesResult(cx, result.address(), aFileList);
break;
}
if (NS_FAILED(rv)) {
NS_WARNING("Get*Result failed!");
}
if (NS_SUCCEEDED(rv)) {
FireSuccess(result);
}
else {
FireError(rv);
}
return NS_OK;
}
nsresult
ArchiveRequest::GetFilenamesResult(JSContext* aCx,
JS::Value* aValue,
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
{
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length(), nullptr));
nsresult rv;
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
nsCOMPtr<nsIDOMFile> file = aFileList[i];
nsString filename;
rv = file->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
JSString* str = JS_NewUCStringCopyZ(aCx, filename.get());
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
JS::Rooted<JS::Value> item(aCx, STRING_TO_JSVAL(str));
if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, &item)) {
return NS_ERROR_FAILURE;
}
}
if (!JS_FreezeObject(aCx, array)) {
return NS_ERROR_FAILURE;
}
*aValue = OBJECT_TO_JSVAL(array);
return NS_OK;
}
nsresult
ArchiveRequest::GetFileResult(JSContext* aCx,
JS::Value* aValue,
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
{
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
nsCOMPtr<nsIDOMFile> file = aFileList[i];
nsString filename;
nsresult rv = file->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
if (filename == mFilename) {
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
return nsContentUtils::WrapNative(aCx, global, file,
&NS_GET_IID(nsIDOMFile), aValue);
}
}
return NS_ERROR_FAILURE;
}
nsresult
ArchiveRequest::GetFilesResult(JSContext* aCx,
JS::Value* aValue,
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
{
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length(), nullptr));
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
nsCOMPtr<nsIDOMFile> file = aFileList[i];
JS::Rooted<JS::Value> value(aCx);
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
nsresult rv = nsContentUtils::WrapNative(aCx, global, file,
&NS_GET_IID(nsIDOMFile),
value.address());
if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, &value)) {
return NS_ERROR_FAILURE;
}
}
aValue->setObject(*array);
return NS_OK;
}
// static
already_AddRefed<ArchiveRequest>
ArchiveRequest::Create(nsIDOMWindow* aOwner,
ArchiveReader* aReader)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsRefPtr<ArchiveRequest> request = new ArchiveRequest(aOwner, aReader);
return request.forget();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ArchiveRequest, DOMRequest,
mArchiveReader)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ArchiveRequest)
NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
NS_IMPL_ADDREF_INHERITED(ArchiveRequest, DOMRequest)
NS_IMPL_RELEASE_INHERITED(ArchiveRequest, DOMRequest)