dom/file/LockedFile.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef mozilla_dom_file_lockedfile_h__
michael@0 8 #define mozilla_dom_file_lockedfile_h__
michael@0 9
michael@0 10 #include "FileCommon.h"
michael@0 11 #include "mozilla/Attributes.h"
michael@0 12 #include "mozilla/DOMEventTargetHelper.h"
michael@0 13 #include "mozilla/dom/FileModeBinding.h"
michael@0 14 #include "mozilla/dom/TypedArray.h"
michael@0 15 #include "nsIInputStream.h"
michael@0 16 #include "nsIRunnable.h"
michael@0 17
michael@0 18 namespace mozilla {
michael@0 19 namespace dom {
michael@0 20 class DOMFileMetadataParameters;
michael@0 21 class DOMRequest;
michael@0 22 } // namespace dom
michael@0 23 } // namespace mozilla
michael@0 24
michael@0 25 namespace mozilla {
michael@0 26 class EventChainPreVisitor;
michael@0 27 } // namespace mozilla
michael@0 28
michael@0 29 BEGIN_FILE_NAMESPACE
michael@0 30
michael@0 31 class FileHandle;
michael@0 32 class FileRequest;
michael@0 33 class MetadataHelper;
michael@0 34
michael@0 35 class LockedFile : public DOMEventTargetHelper,
michael@0 36 public nsIRunnable
michael@0 37 {
michael@0 38 friend class FinishHelper;
michael@0 39 friend class FileService;
michael@0 40 friend class FileHelper;
michael@0 41 friend class MetadataHelper;
michael@0 42
michael@0 43 public:
michael@0 44 NS_DECL_ISUPPORTS_INHERITED
michael@0 45 NS_DECL_NSIRUNNABLE
michael@0 46
michael@0 47 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(LockedFile, DOMEventTargetHelper)
michael@0 48
michael@0 49 enum RequestMode
michael@0 50 {
michael@0 51 NORMAL = 0, // Sequential
michael@0 52 PARALLEL
michael@0 53 };
michael@0 54
michael@0 55 enum ReadyState
michael@0 56 {
michael@0 57 INITIAL = 0,
michael@0 58 LOADING,
michael@0 59 FINISHING,
michael@0 60 DONE
michael@0 61 };
michael@0 62
michael@0 63 static already_AddRefed<LockedFile>
michael@0 64 Create(FileHandle* aFileHandle,
michael@0 65 FileMode aMode,
michael@0 66 RequestMode aRequestMode = NORMAL);
michael@0 67
michael@0 68 // nsIDOMEventTarget
michael@0 69 virtual nsresult
michael@0 70 PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
michael@0 71
michael@0 72 nsresult
michael@0 73 CreateParallelStream(nsISupports** aStream);
michael@0 74
michael@0 75 nsresult
michael@0 76 GetOrCreateStream(nsISupports** aStream);
michael@0 77
michael@0 78 bool
michael@0 79 IsOpen() const;
michael@0 80
michael@0 81 bool
michael@0 82 IsAborted() const
michael@0 83 {
michael@0 84 return mAborted;
michael@0 85 }
michael@0 86
michael@0 87 FileHandle*
michael@0 88 Handle() const
michael@0 89 {
michael@0 90 return mFileHandle;
michael@0 91 }
michael@0 92
michael@0 93 nsresult
michael@0 94 OpenInputStream(bool aWholeFile, uint64_t aStart, uint64_t aLength,
michael@0 95 nsIInputStream** aResult);
michael@0 96
michael@0 97 // WrapperCache
michael@0 98 virtual JSObject*
michael@0 99 WrapObject(JSContext* aCx) MOZ_OVERRIDE;
michael@0 100
michael@0 101 // WebIDL
michael@0 102 nsPIDOMWindow*
michael@0 103 GetParentObject() const
michael@0 104 {
michael@0 105 return GetOwner();
michael@0 106 }
michael@0 107
michael@0 108 FileHandle*
michael@0 109 GetFileHandle() const
michael@0 110 {
michael@0 111 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 112
michael@0 113 return Handle();
michael@0 114 }
michael@0 115
michael@0 116 FileMode
michael@0 117 Mode() const
michael@0 118 {
michael@0 119 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 120
michael@0 121 return mMode;
michael@0 122 }
michael@0 123
michael@0 124 bool
michael@0 125 Active() const
michael@0 126 {
michael@0 127 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 128
michael@0 129 return IsOpen();
michael@0 130 }
michael@0 131
michael@0 132 Nullable<uint64_t>
michael@0 133 GetLocation() const
michael@0 134 {
michael@0 135 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 136
michael@0 137 if (mLocation == UINT64_MAX) {
michael@0 138 return Nullable<uint64_t>();
michael@0 139 }
michael@0 140
michael@0 141 return Nullable<uint64_t>(mLocation);
michael@0 142 }
michael@0 143
michael@0 144 void
michael@0 145 SetLocation(const Nullable<uint64_t>& aLocation)
michael@0 146 {
michael@0 147 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 148
michael@0 149 // Null means the end-of-file.
michael@0 150 if (aLocation.IsNull()) {
michael@0 151 mLocation = UINT64_MAX;
michael@0 152 } else {
michael@0 153 mLocation = aLocation.Value();
michael@0 154 }
michael@0 155 }
michael@0 156
michael@0 157 already_AddRefed<FileRequest>
michael@0 158 GetMetadata(const DOMFileMetadataParameters& aParameters, ErrorResult& aRv);
michael@0 159
michael@0 160 already_AddRefed<FileRequest>
michael@0 161 ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv);
michael@0 162
michael@0 163 already_AddRefed<FileRequest>
michael@0 164 ReadAsText(uint64_t aSize, const nsAString& aEncoding, ErrorResult& aRv);
michael@0 165
michael@0 166 template<class T>
michael@0 167 already_AddRefed<FileRequest>
michael@0 168 Write(const T& aValue, ErrorResult& aRv)
michael@0 169 {
michael@0 170 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 171
michael@0 172 return WriteOrAppend(aValue, false, aRv);
michael@0 173 }
michael@0 174
michael@0 175 template<class T>
michael@0 176 already_AddRefed<FileRequest>
michael@0 177 Append(const T& aValue, ErrorResult& aRv)
michael@0 178 {
michael@0 179 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 180
michael@0 181 return WriteOrAppend(aValue, true, aRv);
michael@0 182 }
michael@0 183
michael@0 184 already_AddRefed<FileRequest>
michael@0 185 Truncate(const Optional<uint64_t>& aSize, ErrorResult& aRv);
michael@0 186
michael@0 187 already_AddRefed<FileRequest>
michael@0 188 Flush(ErrorResult& aRv);
michael@0 189
michael@0 190 void
michael@0 191 Abort(ErrorResult& aRv);
michael@0 192
michael@0 193 IMPL_EVENT_HANDLER(complete)
michael@0 194 IMPL_EVENT_HANDLER(abort)
michael@0 195 IMPL_EVENT_HANDLER(error)
michael@0 196
michael@0 197 private:
michael@0 198 LockedFile();
michael@0 199 ~LockedFile();
michael@0 200
michael@0 201 void
michael@0 202 OnNewRequest();
michael@0 203
michael@0 204 void
michael@0 205 OnRequestFinished();
michael@0 206
michael@0 207 bool
michael@0 208 CheckState(ErrorResult& aRv);
michael@0 209
michael@0 210 bool
michael@0 211 CheckStateAndArgumentsForRead(uint64_t aSize, ErrorResult& aRv);
michael@0 212
michael@0 213 bool
michael@0 214 CheckStateForWrite(ErrorResult& aRv);
michael@0 215
michael@0 216 already_AddRefed<FileRequest>
michael@0 217 GenerateFileRequest();
michael@0 218
michael@0 219 template<class T>
michael@0 220 already_AddRefed<FileRequest>
michael@0 221 WriteOrAppend(const T& aValue, bool aAppend, ErrorResult& aRv)
michael@0 222 {
michael@0 223 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
michael@0 224
michael@0 225 // State checking for write
michael@0 226 if (!CheckStateForWrite(aRv)) {
michael@0 227 return nullptr;
michael@0 228 }
michael@0 229
michael@0 230 // Additional state checking for write
michael@0 231 if (!aAppend && mLocation == UINT64_MAX) {
michael@0 232 aRv.Throw(NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR);
michael@0 233 return nullptr;
michael@0 234 }
michael@0 235
michael@0 236 uint64_t length;
michael@0 237 nsCOMPtr<nsIInputStream> stream = GetInputStream(aValue, &length, aRv);
michael@0 238 if (aRv.Failed()) {
michael@0 239 return nullptr;
michael@0 240 }
michael@0 241
michael@0 242 if (!length) {
michael@0 243 return nullptr;
michael@0 244 }
michael@0 245
michael@0 246 // Do nothing if the window is closed
michael@0 247 if (!GetOwner()) {
michael@0 248 return nullptr;
michael@0 249 }
michael@0 250
michael@0 251 return WriteInternal(stream, length, aAppend, aRv);
michael@0 252 }
michael@0 253
michael@0 254 already_AddRefed<FileRequest>
michael@0 255 WriteInternal(nsIInputStream* aInputStream, uint64_t aInputLength,
michael@0 256 bool aAppend, ErrorResult& aRv);
michael@0 257
michael@0 258 nsresult
michael@0 259 Finish();
michael@0 260
michael@0 261 static already_AddRefed<nsIInputStream>
michael@0 262 GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength,
michael@0 263 ErrorResult& aRv);
michael@0 264
michael@0 265 static already_AddRefed<nsIInputStream>
michael@0 266 GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength, ErrorResult& aRv);
michael@0 267
michael@0 268 static already_AddRefed<nsIInputStream>
michael@0 269 GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
michael@0 270 ErrorResult& aRv);
michael@0 271
michael@0 272 nsRefPtr<FileHandle> mFileHandle;
michael@0 273 ReadyState mReadyState;
michael@0 274 FileMode mMode;
michael@0 275 RequestMode mRequestMode;
michael@0 276 uint64_t mLocation;
michael@0 277 uint32_t mPendingRequests;
michael@0 278
michael@0 279 nsTArray<nsCOMPtr<nsISupports> > mParallelStreams;
michael@0 280 nsCOMPtr<nsISupports> mStream;
michael@0 281
michael@0 282 bool mAborted;
michael@0 283 bool mCreating;
michael@0 284 };
michael@0 285
michael@0 286 class FinishHelper MOZ_FINAL : public nsIRunnable
michael@0 287 {
michael@0 288 friend class LockedFile;
michael@0 289
michael@0 290 public:
michael@0 291 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 292 NS_DECL_NSIRUNNABLE
michael@0 293
michael@0 294 private:
michael@0 295 FinishHelper(LockedFile* aLockedFile);
michael@0 296 ~FinishHelper()
michael@0 297 { }
michael@0 298
michael@0 299 nsRefPtr<LockedFile> mLockedFile;
michael@0 300 nsTArray<nsCOMPtr<nsISupports> > mParallelStreams;
michael@0 301 nsCOMPtr<nsISupports> mStream;
michael@0 302
michael@0 303 bool mAborted;
michael@0 304 };
michael@0 305
michael@0 306 END_FILE_NAMESPACE
michael@0 307
michael@0 308 #endif // mozilla_dom_file_lockedfile_h__

mercurial