1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/file/LockedFile.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,308 @@ 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 +#ifndef mozilla_dom_file_lockedfile_h__ 1.11 +#define mozilla_dom_file_lockedfile_h__ 1.12 + 1.13 +#include "FileCommon.h" 1.14 +#include "mozilla/Attributes.h" 1.15 +#include "mozilla/DOMEventTargetHelper.h" 1.16 +#include "mozilla/dom/FileModeBinding.h" 1.17 +#include "mozilla/dom/TypedArray.h" 1.18 +#include "nsIInputStream.h" 1.19 +#include "nsIRunnable.h" 1.20 + 1.21 +namespace mozilla { 1.22 +namespace dom { 1.23 +class DOMFileMetadataParameters; 1.24 +class DOMRequest; 1.25 +} // namespace dom 1.26 +} // namespace mozilla 1.27 + 1.28 +namespace mozilla { 1.29 +class EventChainPreVisitor; 1.30 +} // namespace mozilla 1.31 + 1.32 +BEGIN_FILE_NAMESPACE 1.33 + 1.34 +class FileHandle; 1.35 +class FileRequest; 1.36 +class MetadataHelper; 1.37 + 1.38 +class LockedFile : public DOMEventTargetHelper, 1.39 + public nsIRunnable 1.40 +{ 1.41 + friend class FinishHelper; 1.42 + friend class FileService; 1.43 + friend class FileHelper; 1.44 + friend class MetadataHelper; 1.45 + 1.46 +public: 1.47 + NS_DECL_ISUPPORTS_INHERITED 1.48 + NS_DECL_NSIRUNNABLE 1.49 + 1.50 + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(LockedFile, DOMEventTargetHelper) 1.51 + 1.52 + enum RequestMode 1.53 + { 1.54 + NORMAL = 0, // Sequential 1.55 + PARALLEL 1.56 + }; 1.57 + 1.58 + enum ReadyState 1.59 + { 1.60 + INITIAL = 0, 1.61 + LOADING, 1.62 + FINISHING, 1.63 + DONE 1.64 + }; 1.65 + 1.66 + static already_AddRefed<LockedFile> 1.67 + Create(FileHandle* aFileHandle, 1.68 + FileMode aMode, 1.69 + RequestMode aRequestMode = NORMAL); 1.70 + 1.71 + // nsIDOMEventTarget 1.72 + virtual nsresult 1.73 + PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE; 1.74 + 1.75 + nsresult 1.76 + CreateParallelStream(nsISupports** aStream); 1.77 + 1.78 + nsresult 1.79 + GetOrCreateStream(nsISupports** aStream); 1.80 + 1.81 + bool 1.82 + IsOpen() const; 1.83 + 1.84 + bool 1.85 + IsAborted() const 1.86 + { 1.87 + return mAborted; 1.88 + } 1.89 + 1.90 + FileHandle* 1.91 + Handle() const 1.92 + { 1.93 + return mFileHandle; 1.94 + } 1.95 + 1.96 + nsresult 1.97 + OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength, 1.98 + nsIInputStream** aResult); 1.99 + 1.100 + // WrapperCache 1.101 + virtual JSObject* 1.102 + WrapObject(JSContext* aCx) MOZ_OVERRIDE; 1.103 + 1.104 + // WebIDL 1.105 + nsPIDOMWindow* 1.106 + GetParentObject() const 1.107 + { 1.108 + return GetOwner(); 1.109 + } 1.110 + 1.111 + FileHandle* 1.112 + GetFileHandle() const 1.113 + { 1.114 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.115 + 1.116 + return Handle(); 1.117 + } 1.118 + 1.119 + FileMode 1.120 + Mode() const 1.121 + { 1.122 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.123 + 1.124 + return mMode; 1.125 + } 1.126 + 1.127 + bool 1.128 + Active() const 1.129 + { 1.130 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.131 + 1.132 + return IsOpen(); 1.133 + } 1.134 + 1.135 + Nullable<uint64_t> 1.136 + GetLocation() const 1.137 + { 1.138 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.139 + 1.140 + if (mLocation == UINT64_MAX) { 1.141 + return Nullable<uint64_t>(); 1.142 + } 1.143 + 1.144 + return Nullable<uint64_t>(mLocation); 1.145 + } 1.146 + 1.147 + void 1.148 + SetLocation(const Nullable<uint64_t>& aLocation) 1.149 + { 1.150 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.151 + 1.152 + // Null means the end-of-file. 1.153 + if (aLocation.IsNull()) { 1.154 + mLocation = UINT64_MAX; 1.155 + } else { 1.156 + mLocation = aLocation.Value(); 1.157 + } 1.158 + } 1.159 + 1.160 + already_AddRefed<FileRequest> 1.161 + GetMetadata(const DOMFileMetadataParameters& aParameters, ErrorResult& aRv); 1.162 + 1.163 + already_AddRefed<FileRequest> 1.164 + ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv); 1.165 + 1.166 + already_AddRefed<FileRequest> 1.167 + ReadAsText(uint64_t aSize, const nsAString& aEncoding, ErrorResult& aRv); 1.168 + 1.169 + template<class T> 1.170 + already_AddRefed<FileRequest> 1.171 + Write(const T& aValue, ErrorResult& aRv) 1.172 + { 1.173 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.174 + 1.175 + return WriteOrAppend(aValue, false, aRv); 1.176 + } 1.177 + 1.178 + template<class T> 1.179 + already_AddRefed<FileRequest> 1.180 + Append(const T& aValue, ErrorResult& aRv) 1.181 + { 1.182 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.183 + 1.184 + return WriteOrAppend(aValue, true, aRv); 1.185 + } 1.186 + 1.187 + already_AddRefed<FileRequest> 1.188 + Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv); 1.189 + 1.190 + already_AddRefed<FileRequest> 1.191 + Flush(ErrorResult& aRv); 1.192 + 1.193 + void 1.194 + Abort(ErrorResult& aRv); 1.195 + 1.196 + IMPL_EVENT_HANDLER(complete) 1.197 + IMPL_EVENT_HANDLER(abort) 1.198 + IMPL_EVENT_HANDLER(error) 1.199 + 1.200 +private: 1.201 + LockedFile(); 1.202 + ~LockedFile(); 1.203 + 1.204 + void 1.205 + OnNewRequest(); 1.206 + 1.207 + void 1.208 + OnRequestFinished(); 1.209 + 1.210 + bool 1.211 + CheckState(ErrorResult& aRv); 1.212 + 1.213 + bool 1.214 + CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv); 1.215 + 1.216 + bool 1.217 + CheckStateForWrite(ErrorResult& aRv); 1.218 + 1.219 + already_AddRefed<FileRequest> 1.220 + GenerateFileRequest(); 1.221 + 1.222 + template<class T> 1.223 + already_AddRefed<FileRequest> 1.224 + WriteOrAppend(const T& aValue, bool aAppend, ErrorResult& aRv) 1.225 + { 1.226 + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 1.227 + 1.228 + // State checking for write 1.229 + if (!CheckStateForWrite(aRv)) { 1.230 + return nullptr; 1.231 + } 1.232 + 1.233 + // Additional state checking for write 1.234 + if (!aAppend && mLocation == UINT64_MAX) { 1.235 + aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR); 1.236 + return nullptr; 1.237 + } 1.238 + 1.239 + uint64_t length; 1.240 + nsCOMPtr<nsIInputStream> stream = GetInputStream(aValue, &length, aRv); 1.241 + if (aRv.Failed()) { 1.242 + return nullptr; 1.243 + } 1.244 + 1.245 + if (!length) { 1.246 + return nullptr; 1.247 + } 1.248 + 1.249 + // Do nothing if the window is closed 1.250 + if (!GetOwner()) { 1.251 + return nullptr; 1.252 + } 1.253 + 1.254 + return WriteInternal(stream, length, aAppend, aRv); 1.255 + } 1.256 + 1.257 + already_AddRefed<FileRequest> 1.258 + WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength, 1.259 + bool aAppend, ErrorResult& aRv); 1.260 + 1.261 + nsresult 1.262 + Finish(); 1.263 + 1.264 + static already_AddRefed<nsIInputStream> 1.265 + GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength, 1.266 + ErrorResult& aRv); 1.267 + 1.268 + static already_AddRefed<nsIInputStream> 1.269 + GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength, ErrorResult& aRv); 1.270 + 1.271 + static already_AddRefed<nsIInputStream> 1.272 + GetInputStream(const nsAString& aValue, uint64_t* aInputLength, 1.273 + ErrorResult& aRv); 1.274 + 1.275 + nsRefPtr<FileHandle> mFileHandle; 1.276 + ReadyState mReadyState; 1.277 + FileMode mMode; 1.278 + RequestMode mRequestMode; 1.279 + uint64_t mLocation; 1.280 + uint32_t mPendingRequests; 1.281 + 1.282 + nsTArray<nsCOMPtr<nsISupports> > mParallelStreams; 1.283 + nsCOMPtr<nsISupports> mStream; 1.284 + 1.285 + bool mAborted; 1.286 + bool mCreating; 1.287 +}; 1.288 + 1.289 +class FinishHelper MOZ_FINAL : public nsIRunnable 1.290 +{ 1.291 + friend class LockedFile; 1.292 + 1.293 +public: 1.294 + NS_DECL_THREADSAFE_ISUPPORTS 1.295 + NS_DECL_NSIRUNNABLE 1.296 + 1.297 +private: 1.298 + FinishHelper(LockedFile* aLockedFile); 1.299 + ~FinishHelper() 1.300 + { } 1.301 + 1.302 + nsRefPtr<LockedFile> mLockedFile; 1.303 + nsTArray<nsCOMPtr<nsISupports> > mParallelStreams; 1.304 + nsCOMPtr<nsISupports> mStream; 1.305 + 1.306 + bool mAborted; 1.307 +}; 1.308 + 1.309 +END_FILE_NAMESPACE 1.310 + 1.311 +#endif // mozilla_dom_file_lockedfile_h__