content/base/public/nsDOMFile.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsDOMFile_h__
michael@0 7 #define nsDOMFile_h__
michael@0 8
michael@0 9 #include "mozilla/Attributes.h"
michael@0 10 #include "nsICharsetDetectionObserver.h"
michael@0 11 #include "nsIFile.h"
michael@0 12 #include "nsIDOMFile.h"
michael@0 13 #include "nsIDOMFileList.h"
michael@0 14 #include "nsIInputStream.h"
michael@0 15 #include "nsIJSNativeInitializer.h"
michael@0 16 #include "nsIMutable.h"
michael@0 17 #include "nsCOMArray.h"
michael@0 18 #include "nsCOMPtr.h"
michael@0 19 #include "nsString.h"
michael@0 20 #include "nsIXMLHttpRequest.h"
michael@0 21 #include "nsAutoPtr.h"
michael@0 22 #include "nsFileStreams.h"
michael@0 23 #include "nsTemporaryFileInputStream.h"
michael@0 24
michael@0 25 #include "mozilla/GuardObjects.h"
michael@0 26 #include "mozilla/LinkedList.h"
michael@0 27 #include <stdint.h>
michael@0 28 #include "mozilla/StaticMutex.h"
michael@0 29 #include "mozilla/StaticPtr.h"
michael@0 30 #include "mozilla/dom/DOMError.h"
michael@0 31 #include "mozilla/dom/indexedDB/FileInfo.h"
michael@0 32 #include "mozilla/dom/indexedDB/FileManager.h"
michael@0 33 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
michael@0 34 #include "nsWrapperCache.h"
michael@0 35 #include "nsCycleCollectionParticipant.h"
michael@0 36
michael@0 37 class nsIFile;
michael@0 38 class nsIInputStream;
michael@0 39 class nsIClassInfo;
michael@0 40
michael@0 41 class nsDOMFileBase : public nsIDOMFile,
michael@0 42 public nsIXHRSendable,
michael@0 43 public nsIMutable
michael@0 44 {
michael@0 45 public:
michael@0 46 typedef mozilla::dom::indexedDB::FileInfo FileInfo;
michael@0 47
michael@0 48 virtual already_AddRefed<nsIDOMBlob>
michael@0 49 CreateSlice(uint64_t aStart, uint64_t aLength,
michael@0 50 const nsAString& aContentType) = 0;
michael@0 51
michael@0 52 virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
michael@0 53 GetSubBlobs() const { return nullptr; }
michael@0 54
michael@0 55 NS_DECL_NSIDOMBLOB
michael@0 56 NS_DECL_NSIDOMFILE
michael@0 57 NS_DECL_NSIXHRSENDABLE
michael@0 58 NS_DECL_NSIMUTABLE
michael@0 59
michael@0 60 void
michael@0 61 SetLazyData(const nsAString& aName, const nsAString& aContentType,
michael@0 62 uint64_t aLength, uint64_t aLastModifiedDate)
michael@0 63 {
michael@0 64 NS_ASSERTION(aLength, "must have length");
michael@0 65
michael@0 66 mName = aName;
michael@0 67 mContentType = aContentType;
michael@0 68 mLength = aLength;
michael@0 69 mLastModificationDate = aLastModifiedDate;
michael@0 70 mIsFile = !aName.IsVoid();
michael@0 71 }
michael@0 72
michael@0 73 bool IsSizeUnknown() const
michael@0 74 {
michael@0 75 return mLength == UINT64_MAX;
michael@0 76 }
michael@0 77
michael@0 78 bool IsDateUnknown() const
michael@0 79 {
michael@0 80 return mIsFile && mLastModificationDate == UINT64_MAX;
michael@0 81 }
michael@0 82
michael@0 83 protected:
michael@0 84 nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
michael@0 85 uint64_t aLength, uint64_t aLastModifiedDate)
michael@0 86 : mIsFile(true), mImmutable(false), mContentType(aContentType),
michael@0 87 mName(aName), mStart(0), mLength(aLength), mLastModificationDate(aLastModifiedDate)
michael@0 88 {
michael@0 89 // Ensure non-null mContentType by default
michael@0 90 mContentType.SetIsVoid(false);
michael@0 91 }
michael@0 92
michael@0 93 nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
michael@0 94 uint64_t aLength)
michael@0 95 : mIsFile(true), mImmutable(false), mContentType(aContentType),
michael@0 96 mName(aName), mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
michael@0 97 {
michael@0 98 // Ensure non-null mContentType by default
michael@0 99 mContentType.SetIsVoid(false);
michael@0 100 }
michael@0 101
michael@0 102 nsDOMFileBase(const nsAString& aContentType, uint64_t aLength)
michael@0 103 : mIsFile(false), mImmutable(false), mContentType(aContentType),
michael@0 104 mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
michael@0 105 {
michael@0 106 // Ensure non-null mContentType by default
michael@0 107 mContentType.SetIsVoid(false);
michael@0 108 }
michael@0 109
michael@0 110 nsDOMFileBase(const nsAString& aContentType, uint64_t aStart,
michael@0 111 uint64_t aLength)
michael@0 112 : mIsFile(false), mImmutable(false), mContentType(aContentType),
michael@0 113 mStart(aStart), mLength(aLength), mLastModificationDate(UINT64_MAX)
michael@0 114 {
michael@0 115 NS_ASSERTION(aLength != UINT64_MAX,
michael@0 116 "Must know length when creating slice");
michael@0 117 // Ensure non-null mContentType by default
michael@0 118 mContentType.SetIsVoid(false);
michael@0 119 }
michael@0 120
michael@0 121 virtual ~nsDOMFileBase() {}
michael@0 122
michael@0 123 virtual bool IsStoredFile() const
michael@0 124 {
michael@0 125 return false;
michael@0 126 }
michael@0 127
michael@0 128 virtual bool IsWholeFile() const
michael@0 129 {
michael@0 130 NS_NOTREACHED("Should only be called on dom blobs backed by files!");
michael@0 131 return false;
michael@0 132 }
michael@0 133
michael@0 134 virtual bool IsSnapshot() const
michael@0 135 {
michael@0 136 return false;
michael@0 137 }
michael@0 138
michael@0 139 FileInfo* GetFileInfo() const
michael@0 140 {
michael@0 141 NS_ASSERTION(IsStoredFile(), "Should only be called on stored files!");
michael@0 142 NS_ASSERTION(!mFileInfos.IsEmpty(), "Must have at least one file info!");
michael@0 143
michael@0 144 return mFileInfos.ElementAt(0);
michael@0 145 }
michael@0 146
michael@0 147 bool mIsFile;
michael@0 148 bool mImmutable;
michael@0 149
michael@0 150 nsString mContentType;
michael@0 151 nsString mName;
michael@0 152 nsString mPath; // The path relative to a directory chosen by the user
michael@0 153
michael@0 154 uint64_t mStart;
michael@0 155 uint64_t mLength;
michael@0 156
michael@0 157 uint64_t mLastModificationDate;
michael@0 158
michael@0 159 // Protected by IndexedDatabaseManager::FileMutex()
michael@0 160 nsTArray<nsRefPtr<FileInfo> > mFileInfos;
michael@0 161 };
michael@0 162
michael@0 163 class nsDOMFile : public nsDOMFileBase
michael@0 164 {
michael@0 165 public:
michael@0 166 nsDOMFile(const nsAString& aName, const nsAString& aContentType,
michael@0 167 uint64_t aLength, uint64_t aLastModifiedDate)
michael@0 168 : nsDOMFileBase(aName, aContentType, aLength, aLastModifiedDate)
michael@0 169 { }
michael@0 170
michael@0 171 nsDOMFile(const nsAString& aName, const nsAString& aContentType,
michael@0 172 uint64_t aLength)
michael@0 173 : nsDOMFileBase(aName, aContentType, aLength)
michael@0 174 { }
michael@0 175
michael@0 176 nsDOMFile(const nsAString& aContentType, uint64_t aLength)
michael@0 177 : nsDOMFileBase(aContentType, aLength)
michael@0 178 { }
michael@0 179
michael@0 180 nsDOMFile(const nsAString& aContentType, uint64_t aStart, uint64_t aLength)
michael@0 181 : nsDOMFileBase(aContentType, aStart, aLength)
michael@0 182 { }
michael@0 183
michael@0 184 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 185 };
michael@0 186
michael@0 187 class nsDOMFileCC : public nsDOMFileBase
michael@0 188 {
michael@0 189 public:
michael@0 190 nsDOMFileCC(const nsAString& aName, const nsAString& aContentType,
michael@0 191 uint64_t aLength)
michael@0 192 : nsDOMFileBase(aName, aContentType, aLength)
michael@0 193 { }
michael@0 194
michael@0 195 nsDOMFileCC(const nsAString& aContentType, uint64_t aLength)
michael@0 196 : nsDOMFileBase(aContentType, aLength)
michael@0 197 { }
michael@0 198
michael@0 199 nsDOMFileCC(const nsAString& aContentType, uint64_t aStart, uint64_t aLength)
michael@0 200 : nsDOMFileBase(aContentType, aStart, aLength)
michael@0 201 { }
michael@0 202
michael@0 203 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 204
michael@0 205 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMFileCC, nsIDOMFile)
michael@0 206 };
michael@0 207
michael@0 208 class nsDOMFileFile : public nsDOMFile
michael@0 209 {
michael@0 210 public:
michael@0 211 // Create as a file
michael@0 212 nsDOMFileFile(nsIFile *aFile)
michael@0 213 : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
michael@0 214 mFile(aFile), mWholeFile(true), mStoredFile(false)
michael@0 215 {
michael@0 216 NS_ASSERTION(mFile, "must have file");
michael@0 217 // Lazily get the content type and size
michael@0 218 mContentType.SetIsVoid(true);
michael@0 219 mFile->GetLeafName(mName);
michael@0 220 }
michael@0 221
michael@0 222 nsDOMFileFile(nsIFile *aFile, FileInfo *aFileInfo)
michael@0 223 : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
michael@0 224 mFile(aFile), mWholeFile(true), mStoredFile(true)
michael@0 225 {
michael@0 226 NS_ASSERTION(mFile, "must have file");
michael@0 227 NS_ASSERTION(aFileInfo, "must have file info");
michael@0 228 // Lazily get the content type and size
michael@0 229 mContentType.SetIsVoid(true);
michael@0 230 mFile->GetLeafName(mName);
michael@0 231
michael@0 232 mFileInfos.AppendElement(aFileInfo);
michael@0 233 }
michael@0 234
michael@0 235 // Create as a file
michael@0 236 nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
michael@0 237 uint64_t aLength, nsIFile *aFile)
michael@0 238 : nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
michael@0 239 mFile(aFile), mWholeFile(true), mStoredFile(false)
michael@0 240 {
michael@0 241 NS_ASSERTION(mFile, "must have file");
michael@0 242 }
michael@0 243
michael@0 244 nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
michael@0 245 uint64_t aLength, nsIFile *aFile, uint64_t aLastModificationDate)
michael@0 246 : nsDOMFile(aName, aContentType, aLength, aLastModificationDate),
michael@0 247 mFile(aFile), mWholeFile(true), mStoredFile(false)
michael@0 248 {
michael@0 249 NS_ASSERTION(mFile, "must have file");
michael@0 250 }
michael@0 251
michael@0 252 // Create as a file with custom name
michael@0 253 nsDOMFileFile(nsIFile *aFile, const nsAString& aName,
michael@0 254 const nsAString& aContentType)
michael@0 255 : nsDOMFile(aName, aContentType, UINT64_MAX, UINT64_MAX),
michael@0 256 mFile(aFile), mWholeFile(true), mStoredFile(false)
michael@0 257 {
michael@0 258 NS_ASSERTION(mFile, "must have file");
michael@0 259 if (aContentType.IsEmpty()) {
michael@0 260 // Lazily get the content type and size
michael@0 261 mContentType.SetIsVoid(true);
michael@0 262 }
michael@0 263 }
michael@0 264
michael@0 265 // Create as a stored file
michael@0 266 nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
michael@0 267 uint64_t aLength, nsIFile* aFile,
michael@0 268 FileInfo* aFileInfo)
michael@0 269 : nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
michael@0 270 mFile(aFile), mWholeFile(true), mStoredFile(true)
michael@0 271 {
michael@0 272 NS_ASSERTION(mFile, "must have file");
michael@0 273 mFileInfos.AppendElement(aFileInfo);
michael@0 274 }
michael@0 275
michael@0 276 // Create as a stored blob
michael@0 277 nsDOMFileFile(const nsAString& aContentType, uint64_t aLength,
michael@0 278 nsIFile* aFile, FileInfo* aFileInfo)
michael@0 279 : nsDOMFile(aContentType, aLength),
michael@0 280 mFile(aFile), mWholeFile(true), mStoredFile(true)
michael@0 281 {
michael@0 282 NS_ASSERTION(mFile, "must have file");
michael@0 283 mFileInfos.AppendElement(aFileInfo);
michael@0 284 }
michael@0 285
michael@0 286 // Create as a file to be later initialized
michael@0 287 nsDOMFileFile()
michael@0 288 : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
michael@0 289 mWholeFile(true), mStoredFile(false)
michael@0 290 {
michael@0 291 // Lazily get the content type and size
michael@0 292 mContentType.SetIsVoid(true);
michael@0 293 mName.SetIsVoid(true);
michael@0 294 }
michael@0 295
michael@0 296 // Overrides
michael@0 297 NS_IMETHOD GetSize(uint64_t* aSize) MOZ_OVERRIDE;
michael@0 298 NS_IMETHOD GetType(nsAString& aType) MOZ_OVERRIDE;
michael@0 299 NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE;
michael@0 300 NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate) MOZ_OVERRIDE;
michael@0 301 NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
michael@0 302 NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
michael@0 303
michael@0 304 void SetPath(const nsAString& aFullPath);
michael@0 305
michael@0 306 protected:
michael@0 307 // Create slice
michael@0 308 nsDOMFileFile(const nsDOMFileFile* aOther, uint64_t aStart, uint64_t aLength,
michael@0 309 const nsAString& aContentType)
michael@0 310 : nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
michael@0 311 mFile(aOther->mFile), mWholeFile(false),
michael@0 312 mStoredFile(aOther->mStoredFile)
michael@0 313 {
michael@0 314 NS_ASSERTION(mFile, "must have file");
michael@0 315 mImmutable = aOther->mImmutable;
michael@0 316
michael@0 317 if (mStoredFile) {
michael@0 318 FileInfo* fileInfo;
michael@0 319
michael@0 320 using mozilla::dom::indexedDB::IndexedDatabaseManager;
michael@0 321
michael@0 322 if (IndexedDatabaseManager::IsClosed()) {
michael@0 323 fileInfo = aOther->GetFileInfo();
michael@0 324 }
michael@0 325 else {
michael@0 326 mozilla::MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
michael@0 327 fileInfo = aOther->GetFileInfo();
michael@0 328 }
michael@0 329
michael@0 330 mFileInfos.AppendElement(fileInfo);
michael@0 331 }
michael@0 332 }
michael@0 333
michael@0 334 virtual already_AddRefed<nsIDOMBlob>
michael@0 335 CreateSlice(uint64_t aStart, uint64_t aLength,
michael@0 336 const nsAString& aContentType) MOZ_OVERRIDE;
michael@0 337
michael@0 338 virtual bool IsStoredFile() const MOZ_OVERRIDE
michael@0 339 {
michael@0 340 return mStoredFile;
michael@0 341 }
michael@0 342
michael@0 343 virtual bool IsWholeFile() const MOZ_OVERRIDE
michael@0 344 {
michael@0 345 return mWholeFile;
michael@0 346 }
michael@0 347
michael@0 348 nsCOMPtr<nsIFile> mFile;
michael@0 349 bool mWholeFile;
michael@0 350 bool mStoredFile;
michael@0 351 };
michael@0 352
michael@0 353 /**
michael@0 354 * This class may be used off the main thread, and in particular, its
michael@0 355 * constructor and destructor may not run on the same thread. Be careful!
michael@0 356 */
michael@0 357 class nsDOMMemoryFile : public nsDOMFile
michael@0 358 {
michael@0 359 public:
michael@0 360 // Create as file
michael@0 361 nsDOMMemoryFile(void *aMemoryBuffer,
michael@0 362 uint64_t aLength,
michael@0 363 const nsAString& aName,
michael@0 364 const nsAString& aContentType)
michael@0 365 : nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
michael@0 366 mDataOwner(new DataOwner(aMemoryBuffer, aLength))
michael@0 367 {
michael@0 368 NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
michael@0 369 }
michael@0 370
michael@0 371 // Create as blob
michael@0 372 nsDOMMemoryFile(void *aMemoryBuffer,
michael@0 373 uint64_t aLength,
michael@0 374 const nsAString& aContentType)
michael@0 375 : nsDOMFile(aContentType, aLength),
michael@0 376 mDataOwner(new DataOwner(aMemoryBuffer, aLength))
michael@0 377 {
michael@0 378 NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
michael@0 379 }
michael@0 380
michael@0 381 NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
michael@0 382
michael@0 383 NS_IMETHOD_(bool) IsMemoryFile(void) MOZ_OVERRIDE;
michael@0 384
michael@0 385 protected:
michael@0 386 // Create slice
michael@0 387 nsDOMMemoryFile(const nsDOMMemoryFile* aOther, uint64_t aStart,
michael@0 388 uint64_t aLength, const nsAString& aContentType)
michael@0 389 : nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
michael@0 390 mDataOwner(aOther->mDataOwner)
michael@0 391 {
michael@0 392 NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
michael@0 393 mImmutable = aOther->mImmutable;
michael@0 394 }
michael@0 395 virtual already_AddRefed<nsIDOMBlob>
michael@0 396 CreateSlice(uint64_t aStart, uint64_t aLength,
michael@0 397 const nsAString& aContentType) MOZ_OVERRIDE;
michael@0 398
michael@0 399 // These classes need to see DataOwner.
michael@0 400 friend class DataOwnerAdapter;
michael@0 401 friend class nsDOMMemoryFileDataOwnerMemoryReporter;
michael@0 402
michael@0 403 class DataOwner MOZ_FINAL : public mozilla::LinkedListElement<DataOwner> {
michael@0 404 public:
michael@0 405 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataOwner)
michael@0 406 DataOwner(void* aMemoryBuffer, uint64_t aLength)
michael@0 407 : mData(aMemoryBuffer)
michael@0 408 , mLength(aLength)
michael@0 409 {
michael@0 410 mozilla::StaticMutexAutoLock lock(sDataOwnerMutex);
michael@0 411
michael@0 412 if (!sDataOwners) {
michael@0 413 sDataOwners = new mozilla::LinkedList<DataOwner>();
michael@0 414 EnsureMemoryReporterRegistered();
michael@0 415 }
michael@0 416 sDataOwners->insertBack(this);
michael@0 417 }
michael@0 418
michael@0 419 private:
michael@0 420 // Private destructor, to discourage deletion outside of Release():
michael@0 421 ~DataOwner() {
michael@0 422 mozilla::StaticMutexAutoLock lock(sDataOwnerMutex);
michael@0 423
michael@0 424 remove();
michael@0 425 if (sDataOwners->isEmpty()) {
michael@0 426 // Free the linked list if it's empty.
michael@0 427 sDataOwners = nullptr;
michael@0 428 }
michael@0 429
michael@0 430 moz_free(mData);
michael@0 431 }
michael@0 432
michael@0 433 public:
michael@0 434 static void EnsureMemoryReporterRegistered();
michael@0 435
michael@0 436 // sDataOwners and sMemoryReporterRegistered may only be accessed while
michael@0 437 // holding sDataOwnerMutex! You also must hold the mutex while touching
michael@0 438 // elements of the linked list that DataOwner inherits from.
michael@0 439 static mozilla::StaticMutex sDataOwnerMutex;
michael@0 440 static mozilla::StaticAutoPtr<mozilla::LinkedList<DataOwner> > sDataOwners;
michael@0 441 static bool sMemoryReporterRegistered;
michael@0 442
michael@0 443 void* mData;
michael@0 444 uint64_t mLength;
michael@0 445 };
michael@0 446
michael@0 447 // Used when backed by a memory store
michael@0 448 nsRefPtr<DataOwner> mDataOwner;
michael@0 449 };
michael@0 450
michael@0 451 class nsDOMFileList MOZ_FINAL : public nsIDOMFileList,
michael@0 452 public nsWrapperCache
michael@0 453 {
michael@0 454 public:
michael@0 455 nsDOMFileList(nsISupports *aParent) : mParent(aParent)
michael@0 456 {
michael@0 457 SetIsDOMBinding();
michael@0 458 }
michael@0 459
michael@0 460 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 461 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMFileList)
michael@0 462
michael@0 463 NS_DECL_NSIDOMFILELIST
michael@0 464
michael@0 465 virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
michael@0 466
michael@0 467 nsISupports* GetParentObject()
michael@0 468 {
michael@0 469 return mParent;
michael@0 470 }
michael@0 471
michael@0 472 void Disconnect()
michael@0 473 {
michael@0 474 mParent = nullptr;
michael@0 475 }
michael@0 476
michael@0 477 bool Append(nsIDOMFile *aFile) { return mFiles.AppendObject(aFile); }
michael@0 478
michael@0 479 bool Remove(uint32_t aIndex) { return mFiles.RemoveObjectAt(aIndex); }
michael@0 480 void Clear() { return mFiles.Clear(); }
michael@0 481
michael@0 482 static nsDOMFileList* FromSupports(nsISupports* aSupports)
michael@0 483 {
michael@0 484 #ifdef DEBUG
michael@0 485 {
michael@0 486 nsCOMPtr<nsIDOMFileList> list_qi = do_QueryInterface(aSupports);
michael@0 487
michael@0 488 // If this assertion fires the QI implementation for the object in
michael@0 489 // question doesn't use the nsIDOMFileList pointer as the nsISupports
michael@0 490 // pointer. That must be fixed, or we'll crash...
michael@0 491 NS_ASSERTION(list_qi == static_cast<nsIDOMFileList*>(aSupports),
michael@0 492 "Uh, fix QI!");
michael@0 493 }
michael@0 494 #endif
michael@0 495
michael@0 496 return static_cast<nsDOMFileList*>(aSupports);
michael@0 497 }
michael@0 498
michael@0 499 nsIDOMFile* Item(uint32_t aIndex)
michael@0 500 {
michael@0 501 return mFiles.SafeObjectAt(aIndex);
michael@0 502 }
michael@0 503 nsIDOMFile* IndexedGetter(uint32_t aIndex, bool& aFound)
michael@0 504 {
michael@0 505 aFound = aIndex < static_cast<uint32_t>(mFiles.Count());
michael@0 506 return aFound ? mFiles.ObjectAt(aIndex) : nullptr;
michael@0 507 }
michael@0 508 uint32_t Length()
michael@0 509 {
michael@0 510 return mFiles.Count();
michael@0 511 }
michael@0 512
michael@0 513 private:
michael@0 514 nsCOMArray<nsIDOMFile> mFiles;
michael@0 515 nsISupports *mParent;
michael@0 516 };
michael@0 517
michael@0 518 class MOZ_STACK_CLASS nsDOMFileInternalUrlHolder {
michael@0 519 public:
michael@0 520 nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal
michael@0 521 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
michael@0 522 ~nsDOMFileInternalUrlHolder();
michael@0 523 nsAutoString mUrl;
michael@0 524 private:
michael@0 525 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
michael@0 526 };
michael@0 527 // This class would take the ownership of aFD and the caller must not close it.
michael@0 528 class nsDOMTemporaryFileBlob : public nsDOMFile
michael@0 529 {
michael@0 530 public:
michael@0 531 nsDOMTemporaryFileBlob(PRFileDesc* aFD, uint64_t aStartPos, uint64_t aLength,
michael@0 532 const nsAString& aContentType)
michael@0 533 : nsDOMFile(aContentType, aLength),
michael@0 534 mLength(aLength),
michael@0 535 mStartPos(aStartPos),
michael@0 536 mContentType(aContentType)
michael@0 537 {
michael@0 538 mFileDescOwner = new nsTemporaryFileInputStream::FileDescOwner(aFD);
michael@0 539 }
michael@0 540
michael@0 541 ~nsDOMTemporaryFileBlob() { }
michael@0 542 NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
michael@0 543
michael@0 544 protected:
michael@0 545 nsDOMTemporaryFileBlob(const nsDOMTemporaryFileBlob* aOther, uint64_t aStart, uint64_t aLength,
michael@0 546 const nsAString& aContentType)
michael@0 547 : nsDOMFile(aContentType, aLength),
michael@0 548 mLength(aLength),
michael@0 549 mStartPos(aStart),
michael@0 550 mFileDescOwner(aOther->mFileDescOwner),
michael@0 551 mContentType(aContentType) { }
michael@0 552
michael@0 553 virtual already_AddRefed<nsIDOMBlob>
michael@0 554 CreateSlice(uint64_t aStart, uint64_t aLength,
michael@0 555 const nsAString& aContentType) MOZ_OVERRIDE;
michael@0 556
michael@0 557 private:
michael@0 558 uint64_t mLength;
michael@0 559 uint64_t mStartPos;
michael@0 560 nsRefPtr<nsTemporaryFileInputStream::FileDescOwner> mFileDescOwner;
michael@0 561 nsString mContentType;
michael@0 562 };
michael@0 563
michael@0 564 #endif

mercurial