1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/file/ArchiveRequest.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,279 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "ArchiveRequest.h" 1.11 + 1.12 +#include "mozilla/EventDispatcher.h" 1.13 +#include "mozilla/dom/ArchiveRequestBinding.h" 1.14 +#include "nsContentUtils.h" 1.15 +#include "nsCxPusher.h" 1.16 + 1.17 +using namespace mozilla; 1.18 + 1.19 +USING_FILE_NAMESPACE 1.20 + 1.21 +/** 1.22 + * Class used to make asynchronous the ArchiveRequest. 1.23 + */ 1.24 +class ArchiveRequestEvent : public nsRunnable 1.25 +{ 1.26 +public: 1.27 + NS_DECL_NSIRUNNABLE 1.28 + 1.29 + ArchiveRequestEvent(ArchiveRequest* request) 1.30 + : mRequest(request) 1.31 + { 1.32 + MOZ_COUNT_CTOR(ArchiveRequestEvent); 1.33 + } 1.34 + 1.35 + ~ArchiveRequestEvent() 1.36 + { 1.37 + MOZ_COUNT_DTOR(ArchiveRequestEvent); 1.38 + } 1.39 + 1.40 +private: //data 1.41 + nsRefPtr<ArchiveRequest> mRequest; 1.42 +}; 1.43 + 1.44 +NS_IMETHODIMP 1.45 +ArchiveRequestEvent::Run() 1.46 +{ 1.47 + NS_ABORT_IF_FALSE(mRequest, "the request is not longer valid"); 1.48 + mRequest->Run(); 1.49 + return NS_OK; 1.50 +} 1.51 + 1.52 +// ArchiveRequest 1.53 + 1.54 +ArchiveRequest::ArchiveRequest(nsPIDOMWindow* aWindow, 1.55 + ArchiveReader* aReader) 1.56 +: DOMRequest(aWindow), 1.57 + mArchiveReader(aReader) 1.58 +{ 1.59 + MOZ_ASSERT(aReader); 1.60 + 1.61 + MOZ_COUNT_CTOR(ArchiveRequest); 1.62 + 1.63 + /* An event to make this request asynchronous: */ 1.64 + nsRefPtr<ArchiveRequestEvent> event = new ArchiveRequestEvent(this); 1.65 + NS_DispatchToCurrentThread(event); 1.66 +} 1.67 + 1.68 +ArchiveRequest::~ArchiveRequest() 1.69 +{ 1.70 + MOZ_COUNT_DTOR(ArchiveRequest); 1.71 +} 1.72 + 1.73 +nsresult 1.74 +ArchiveRequest::PreHandleEvent(EventChainPreVisitor& aVisitor) 1.75 +{ 1.76 + aVisitor.mCanHandle = true; 1.77 + aVisitor.mParentTarget = nullptr; 1.78 + return NS_OK; 1.79 +} 1.80 + 1.81 +/* virtual */ JSObject* 1.82 +ArchiveRequest::WrapObject(JSContext* aCx) 1.83 +{ 1.84 + return ArchiveRequestBinding::Wrap(aCx, this); 1.85 +} 1.86 + 1.87 +ArchiveReader* 1.88 +ArchiveRequest::Reader() const 1.89 +{ 1.90 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.91 + 1.92 + return mArchiveReader; 1.93 +} 1.94 + 1.95 +// Here the request is processed: 1.96 +void 1.97 +ArchiveRequest::Run() 1.98 +{ 1.99 + // Register this request to the reader. 1.100 + // When the reader is ready to return data, a 'Ready()' will be called 1.101 + nsresult rv = mArchiveReader->RegisterRequest(this); 1.102 + if (NS_FAILED(rv)) { 1.103 + FireError(rv); 1.104 + } 1.105 +} 1.106 + 1.107 +void 1.108 +ArchiveRequest::OpGetFilenames() 1.109 +{ 1.110 + mOperation = GetFilenames; 1.111 +} 1.112 + 1.113 +void 1.114 +ArchiveRequest::OpGetFile(const nsAString& aFilename) 1.115 +{ 1.116 + mOperation = GetFile; 1.117 + mFilename = aFilename; 1.118 +} 1.119 + 1.120 +void 1.121 +ArchiveRequest::OpGetFiles() 1.122 +{ 1.123 + mOperation = GetFiles; 1.124 +} 1.125 + 1.126 +nsresult 1.127 +ArchiveRequest::ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList, 1.128 + nsresult aStatus) 1.129 +{ 1.130 + if (NS_FAILED(aStatus)) { 1.131 + FireError(aStatus); 1.132 + return NS_OK; 1.133 + } 1.134 + 1.135 + nsresult rv; 1.136 + 1.137 + nsIScriptContext* sc = GetContextForEventHandlers(&rv); 1.138 + NS_ENSURE_STATE(sc); 1.139 + 1.140 + AutoPushJSContext cx(sc->GetNativeContext()); 1.141 + NS_ASSERTION(cx, "Failed to get a context!"); 1.142 + 1.143 + JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy()); 1.144 + NS_ASSERTION(global, "Failed to get global object!"); 1.145 + 1.146 + JSAutoCompartment ac(cx, global); 1.147 + 1.148 + JS::Rooted<JS::Value> result(cx); 1.149 + switch (mOperation) { 1.150 + case GetFilenames: 1.151 + rv = GetFilenamesResult(cx, result.address(), aFileList); 1.152 + break; 1.153 + 1.154 + case GetFile: 1.155 + rv = GetFileResult(cx, &result, aFileList); 1.156 + break; 1.157 + 1.158 + case GetFiles: 1.159 + rv = GetFilesResult(cx, &result, aFileList); 1.160 + break; 1.161 + } 1.162 + 1.163 + if (NS_FAILED(rv)) { 1.164 + NS_WARNING("Get*Result failed!"); 1.165 + } 1.166 + 1.167 + if (NS_SUCCEEDED(rv)) { 1.168 + FireSuccess(result); 1.169 + } 1.170 + else { 1.171 + FireError(rv); 1.172 + } 1.173 + 1.174 + return NS_OK; 1.175 +} 1.176 + 1.177 +nsresult 1.178 +ArchiveRequest::GetFilenamesResult(JSContext* aCx, 1.179 + JS::Value* aValue, 1.180 + nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList) 1.181 +{ 1.182 + JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length())); 1.183 + nsresult rv; 1.184 + 1.185 + if (!array) { 1.186 + return NS_ERROR_OUT_OF_MEMORY; 1.187 + } 1.188 + 1.189 + JS::Rooted<JSString*> str(aCx); 1.190 + for (uint32_t i = 0; i < aFileList.Length(); ++i) { 1.191 + nsCOMPtr<nsIDOMFile> file = aFileList[i]; 1.192 + 1.193 + nsString filename; 1.194 + rv = file->GetName(filename); 1.195 + NS_ENSURE_SUCCESS(rv, rv); 1.196 + 1.197 + str = JS_NewUCStringCopyZ(aCx, filename.get()); 1.198 + NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); 1.199 + 1.200 + if (NS_FAILED(rv) || 1.201 + !JS_DefineElement(aCx, array, i, JS::StringValue(str), nullptr, nullptr, 1.202 + JSPROP_ENUMERATE)) { 1.203 + return NS_ERROR_FAILURE; 1.204 + } 1.205 + } 1.206 + 1.207 + if (!JS_FreezeObject(aCx, array)) { 1.208 + return NS_ERROR_FAILURE; 1.209 + } 1.210 + 1.211 + *aValue = OBJECT_TO_JSVAL(array); 1.212 + return NS_OK; 1.213 +} 1.214 + 1.215 +nsresult 1.216 +ArchiveRequest::GetFileResult(JSContext* aCx, 1.217 + JS::MutableHandle<JS::Value> aValue, 1.218 + nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList) 1.219 +{ 1.220 + for (uint32_t i = 0; i < aFileList.Length(); ++i) { 1.221 + nsCOMPtr<nsIDOMFile> file = aFileList[i]; 1.222 + 1.223 + nsString filename; 1.224 + nsresult rv = file->GetName(filename); 1.225 + NS_ENSURE_SUCCESS(rv, rv); 1.226 + 1.227 + if (filename == mFilename) { 1.228 + return nsContentUtils::WrapNative(aCx, file, &NS_GET_IID(nsIDOMFile), 1.229 + aValue); 1.230 + } 1.231 + } 1.232 + 1.233 + return NS_ERROR_FAILURE; 1.234 +} 1.235 + 1.236 +nsresult 1.237 +ArchiveRequest::GetFilesResult(JSContext* aCx, 1.238 + JS::MutableHandle<JS::Value> aValue, 1.239 + nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList) 1.240 +{ 1.241 + JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length())); 1.242 + if (!array) { 1.243 + return NS_ERROR_OUT_OF_MEMORY; 1.244 + } 1.245 + 1.246 + for (uint32_t i = 0; i < aFileList.Length(); ++i) { 1.247 + nsCOMPtr<nsIDOMFile> file = aFileList[i]; 1.248 + 1.249 + JS::Rooted<JS::Value> value(aCx); 1.250 + nsresult rv = nsContentUtils::WrapNative(aCx, file, &NS_GET_IID(nsIDOMFile), 1.251 + &value); 1.252 + if (NS_FAILED(rv) || 1.253 + !JS_DefineElement(aCx, array, i, value, nullptr, nullptr, 1.254 + JSPROP_ENUMERATE)) { 1.255 + return NS_ERROR_FAILURE; 1.256 + } 1.257 + } 1.258 + 1.259 + aValue.setObject(*array); 1.260 + return NS_OK; 1.261 +} 1.262 + 1.263 +// static 1.264 +already_AddRefed<ArchiveRequest> 1.265 +ArchiveRequest::Create(nsPIDOMWindow* aOwner, 1.266 + ArchiveReader* aReader) 1.267 +{ 1.268 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.269 + 1.270 + nsRefPtr<ArchiveRequest> request = new ArchiveRequest(aOwner, aReader); 1.271 + 1.272 + return request.forget(); 1.273 +} 1.274 + 1.275 +NS_IMPL_CYCLE_COLLECTION_INHERITED(ArchiveRequest, DOMRequest, 1.276 + mArchiveReader) 1.277 + 1.278 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ArchiveRequest) 1.279 +NS_INTERFACE_MAP_END_INHERITING(DOMRequest) 1.280 + 1.281 +NS_IMPL_ADDREF_INHERITED(ArchiveRequest, DOMRequest) 1.282 +NS_IMPL_RELEASE_INHERITED(ArchiveRequest, DOMRequest)