1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/public/nsDOMFile.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,564 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsDOMFile_h__ 1.10 +#define nsDOMFile_h__ 1.11 + 1.12 +#include "mozilla/Attributes.h" 1.13 +#include "nsICharsetDetectionObserver.h" 1.14 +#include "nsIFile.h" 1.15 +#include "nsIDOMFile.h" 1.16 +#include "nsIDOMFileList.h" 1.17 +#include "nsIInputStream.h" 1.18 +#include "nsIJSNativeInitializer.h" 1.19 +#include "nsIMutable.h" 1.20 +#include "nsCOMArray.h" 1.21 +#include "nsCOMPtr.h" 1.22 +#include "nsString.h" 1.23 +#include "nsIXMLHttpRequest.h" 1.24 +#include "nsAutoPtr.h" 1.25 +#include "nsFileStreams.h" 1.26 +#include "nsTemporaryFileInputStream.h" 1.27 + 1.28 +#include "mozilla/GuardObjects.h" 1.29 +#include "mozilla/LinkedList.h" 1.30 +#include <stdint.h> 1.31 +#include "mozilla/StaticMutex.h" 1.32 +#include "mozilla/StaticPtr.h" 1.33 +#include "mozilla/dom/DOMError.h" 1.34 +#include "mozilla/dom/indexedDB/FileInfo.h" 1.35 +#include "mozilla/dom/indexedDB/FileManager.h" 1.36 +#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h" 1.37 +#include "nsWrapperCache.h" 1.38 +#include "nsCycleCollectionParticipant.h" 1.39 + 1.40 +class nsIFile; 1.41 +class nsIInputStream; 1.42 +class nsIClassInfo; 1.43 + 1.44 +class nsDOMFileBase : public nsIDOMFile, 1.45 + public nsIXHRSendable, 1.46 + public nsIMutable 1.47 +{ 1.48 +public: 1.49 + typedef mozilla::dom::indexedDB::FileInfo FileInfo; 1.50 + 1.51 + virtual already_AddRefed<nsIDOMBlob> 1.52 + CreateSlice(uint64_t aStart, uint64_t aLength, 1.53 + const nsAString& aContentType) = 0; 1.54 + 1.55 + virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >* 1.56 + GetSubBlobs() const { return nullptr; } 1.57 + 1.58 + NS_DECL_NSIDOMBLOB 1.59 + NS_DECL_NSIDOMFILE 1.60 + NS_DECL_NSIXHRSENDABLE 1.61 + NS_DECL_NSIMUTABLE 1.62 + 1.63 + void 1.64 + SetLazyData(const nsAString& aName, const nsAString& aContentType, 1.65 + uint64_t aLength, uint64_t aLastModifiedDate) 1.66 + { 1.67 + NS_ASSERTION(aLength, "must have length"); 1.68 + 1.69 + mName = aName; 1.70 + mContentType = aContentType; 1.71 + mLength = aLength; 1.72 + mLastModificationDate = aLastModifiedDate; 1.73 + mIsFile = !aName.IsVoid(); 1.74 + } 1.75 + 1.76 + bool IsSizeUnknown() const 1.77 + { 1.78 + return mLength == UINT64_MAX; 1.79 + } 1.80 + 1.81 + bool IsDateUnknown() const 1.82 + { 1.83 + return mIsFile && mLastModificationDate == UINT64_MAX; 1.84 + } 1.85 + 1.86 +protected: 1.87 + nsDOMFileBase(const nsAString& aName, const nsAString& aContentType, 1.88 + uint64_t aLength, uint64_t aLastModifiedDate) 1.89 + : mIsFile(true), mImmutable(false), mContentType(aContentType), 1.90 + mName(aName), mStart(0), mLength(aLength), mLastModificationDate(aLastModifiedDate) 1.91 + { 1.92 + // Ensure non-null mContentType by default 1.93 + mContentType.SetIsVoid(false); 1.94 + } 1.95 + 1.96 + nsDOMFileBase(const nsAString& aName, const nsAString& aContentType, 1.97 + uint64_t aLength) 1.98 + : mIsFile(true), mImmutable(false), mContentType(aContentType), 1.99 + mName(aName), mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX) 1.100 + { 1.101 + // Ensure non-null mContentType by default 1.102 + mContentType.SetIsVoid(false); 1.103 + } 1.104 + 1.105 + nsDOMFileBase(const nsAString& aContentType, uint64_t aLength) 1.106 + : mIsFile(false), mImmutable(false), mContentType(aContentType), 1.107 + mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX) 1.108 + { 1.109 + // Ensure non-null mContentType by default 1.110 + mContentType.SetIsVoid(false); 1.111 + } 1.112 + 1.113 + nsDOMFileBase(const nsAString& aContentType, uint64_t aStart, 1.114 + uint64_t aLength) 1.115 + : mIsFile(false), mImmutable(false), mContentType(aContentType), 1.116 + mStart(aStart), mLength(aLength), mLastModificationDate(UINT64_MAX) 1.117 + { 1.118 + NS_ASSERTION(aLength != UINT64_MAX, 1.119 + "Must know length when creating slice"); 1.120 + // Ensure non-null mContentType by default 1.121 + mContentType.SetIsVoid(false); 1.122 + } 1.123 + 1.124 + virtual ~nsDOMFileBase() {} 1.125 + 1.126 + virtual bool IsStoredFile() const 1.127 + { 1.128 + return false; 1.129 + } 1.130 + 1.131 + virtual bool IsWholeFile() const 1.132 + { 1.133 + NS_NOTREACHED("Should only be called on dom blobs backed by files!"); 1.134 + return false; 1.135 + } 1.136 + 1.137 + virtual bool IsSnapshot() const 1.138 + { 1.139 + return false; 1.140 + } 1.141 + 1.142 + FileInfo* GetFileInfo() const 1.143 + { 1.144 + NS_ASSERTION(IsStoredFile(), "Should only be called on stored files!"); 1.145 + NS_ASSERTION(!mFileInfos.IsEmpty(), "Must have at least one file info!"); 1.146 + 1.147 + return mFileInfos.ElementAt(0); 1.148 + } 1.149 + 1.150 + bool mIsFile; 1.151 + bool mImmutable; 1.152 + 1.153 + nsString mContentType; 1.154 + nsString mName; 1.155 + nsString mPath; // The path relative to a directory chosen by the user 1.156 + 1.157 + uint64_t mStart; 1.158 + uint64_t mLength; 1.159 + 1.160 + uint64_t mLastModificationDate; 1.161 + 1.162 + // Protected by IndexedDatabaseManager::FileMutex() 1.163 + nsTArray<nsRefPtr<FileInfo> > mFileInfos; 1.164 +}; 1.165 + 1.166 +class nsDOMFile : public nsDOMFileBase 1.167 +{ 1.168 +public: 1.169 + nsDOMFile(const nsAString& aName, const nsAString& aContentType, 1.170 + uint64_t aLength, uint64_t aLastModifiedDate) 1.171 + : nsDOMFileBase(aName, aContentType, aLength, aLastModifiedDate) 1.172 + { } 1.173 + 1.174 + nsDOMFile(const nsAString& aName, const nsAString& aContentType, 1.175 + uint64_t aLength) 1.176 + : nsDOMFileBase(aName, aContentType, aLength) 1.177 + { } 1.178 + 1.179 + nsDOMFile(const nsAString& aContentType, uint64_t aLength) 1.180 + : nsDOMFileBase(aContentType, aLength) 1.181 + { } 1.182 + 1.183 + nsDOMFile(const nsAString& aContentType, uint64_t aStart, uint64_t aLength) 1.184 + : nsDOMFileBase(aContentType, aStart, aLength) 1.185 + { } 1.186 + 1.187 + NS_DECL_THREADSAFE_ISUPPORTS 1.188 +}; 1.189 + 1.190 +class nsDOMFileCC : public nsDOMFileBase 1.191 +{ 1.192 +public: 1.193 + nsDOMFileCC(const nsAString& aName, const nsAString& aContentType, 1.194 + uint64_t aLength) 1.195 + : nsDOMFileBase(aName, aContentType, aLength) 1.196 + { } 1.197 + 1.198 + nsDOMFileCC(const nsAString& aContentType, uint64_t aLength) 1.199 + : nsDOMFileBase(aContentType, aLength) 1.200 + { } 1.201 + 1.202 + nsDOMFileCC(const nsAString& aContentType, uint64_t aStart, uint64_t aLength) 1.203 + : nsDOMFileBase(aContentType, aStart, aLength) 1.204 + { } 1.205 + 1.206 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.207 + 1.208 + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMFileCC, nsIDOMFile) 1.209 +}; 1.210 + 1.211 +class nsDOMFileFile : public nsDOMFile 1.212 +{ 1.213 +public: 1.214 + // Create as a file 1.215 + nsDOMFileFile(nsIFile *aFile) 1.216 + : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX), 1.217 + mFile(aFile), mWholeFile(true), mStoredFile(false) 1.218 + { 1.219 + NS_ASSERTION(mFile, "must have file"); 1.220 + // Lazily get the content type and size 1.221 + mContentType.SetIsVoid(true); 1.222 + mFile->GetLeafName(mName); 1.223 + } 1.224 + 1.225 + nsDOMFileFile(nsIFile *aFile, FileInfo *aFileInfo) 1.226 + : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX), 1.227 + mFile(aFile), mWholeFile(true), mStoredFile(true) 1.228 + { 1.229 + NS_ASSERTION(mFile, "must have file"); 1.230 + NS_ASSERTION(aFileInfo, "must have file info"); 1.231 + // Lazily get the content type and size 1.232 + mContentType.SetIsVoid(true); 1.233 + mFile->GetLeafName(mName); 1.234 + 1.235 + mFileInfos.AppendElement(aFileInfo); 1.236 + } 1.237 + 1.238 + // Create as a file 1.239 + nsDOMFileFile(const nsAString& aName, const nsAString& aContentType, 1.240 + uint64_t aLength, nsIFile *aFile) 1.241 + : nsDOMFile(aName, aContentType, aLength, UINT64_MAX), 1.242 + mFile(aFile), mWholeFile(true), mStoredFile(false) 1.243 + { 1.244 + NS_ASSERTION(mFile, "must have file"); 1.245 + } 1.246 + 1.247 + nsDOMFileFile(const nsAString& aName, const nsAString& aContentType, 1.248 + uint64_t aLength, nsIFile *aFile, uint64_t aLastModificationDate) 1.249 + : nsDOMFile(aName, aContentType, aLength, aLastModificationDate), 1.250 + mFile(aFile), mWholeFile(true), mStoredFile(false) 1.251 + { 1.252 + NS_ASSERTION(mFile, "must have file"); 1.253 + } 1.254 + 1.255 + // Create as a file with custom name 1.256 + nsDOMFileFile(nsIFile *aFile, const nsAString& aName, 1.257 + const nsAString& aContentType) 1.258 + : nsDOMFile(aName, aContentType, UINT64_MAX, UINT64_MAX), 1.259 + mFile(aFile), mWholeFile(true), mStoredFile(false) 1.260 + { 1.261 + NS_ASSERTION(mFile, "must have file"); 1.262 + if (aContentType.IsEmpty()) { 1.263 + // Lazily get the content type and size 1.264 + mContentType.SetIsVoid(true); 1.265 + } 1.266 + } 1.267 + 1.268 + // Create as a stored file 1.269 + nsDOMFileFile(const nsAString& aName, const nsAString& aContentType, 1.270 + uint64_t aLength, nsIFile* aFile, 1.271 + FileInfo* aFileInfo) 1.272 + : nsDOMFile(aName, aContentType, aLength, UINT64_MAX), 1.273 + mFile(aFile), mWholeFile(true), mStoredFile(true) 1.274 + { 1.275 + NS_ASSERTION(mFile, "must have file"); 1.276 + mFileInfos.AppendElement(aFileInfo); 1.277 + } 1.278 + 1.279 + // Create as a stored blob 1.280 + nsDOMFileFile(const nsAString& aContentType, uint64_t aLength, 1.281 + nsIFile* aFile, FileInfo* aFileInfo) 1.282 + : nsDOMFile(aContentType, aLength), 1.283 + mFile(aFile), mWholeFile(true), mStoredFile(true) 1.284 + { 1.285 + NS_ASSERTION(mFile, "must have file"); 1.286 + mFileInfos.AppendElement(aFileInfo); 1.287 + } 1.288 + 1.289 + // Create as a file to be later initialized 1.290 + nsDOMFileFile() 1.291 + : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX), 1.292 + mWholeFile(true), mStoredFile(false) 1.293 + { 1.294 + // Lazily get the content type and size 1.295 + mContentType.SetIsVoid(true); 1.296 + mName.SetIsVoid(true); 1.297 + } 1.298 + 1.299 + // Overrides 1.300 + NS_IMETHOD GetSize(uint64_t* aSize) MOZ_OVERRIDE; 1.301 + NS_IMETHOD GetType(nsAString& aType) MOZ_OVERRIDE; 1.302 + NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE; 1.303 + NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate) MOZ_OVERRIDE; 1.304 + NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE; 1.305 + NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE; 1.306 + 1.307 + void SetPath(const nsAString& aFullPath); 1.308 + 1.309 +protected: 1.310 + // Create slice 1.311 + nsDOMFileFile(const nsDOMFileFile* aOther, uint64_t aStart, uint64_t aLength, 1.312 + const nsAString& aContentType) 1.313 + : nsDOMFile(aContentType, aOther->mStart + aStart, aLength), 1.314 + mFile(aOther->mFile), mWholeFile(false), 1.315 + mStoredFile(aOther->mStoredFile) 1.316 + { 1.317 + NS_ASSERTION(mFile, "must have file"); 1.318 + mImmutable = aOther->mImmutable; 1.319 + 1.320 + if (mStoredFile) { 1.321 + FileInfo* fileInfo; 1.322 + 1.323 + using mozilla::dom::indexedDB::IndexedDatabaseManager; 1.324 + 1.325 + if (IndexedDatabaseManager::IsClosed()) { 1.326 + fileInfo = aOther->GetFileInfo(); 1.327 + } 1.328 + else { 1.329 + mozilla::MutexAutoLock lock(IndexedDatabaseManager::FileMutex()); 1.330 + fileInfo = aOther->GetFileInfo(); 1.331 + } 1.332 + 1.333 + mFileInfos.AppendElement(fileInfo); 1.334 + } 1.335 + } 1.336 + 1.337 + virtual already_AddRefed<nsIDOMBlob> 1.338 + CreateSlice(uint64_t aStart, uint64_t aLength, 1.339 + const nsAString& aContentType) MOZ_OVERRIDE; 1.340 + 1.341 + virtual bool IsStoredFile() const MOZ_OVERRIDE 1.342 + { 1.343 + return mStoredFile; 1.344 + } 1.345 + 1.346 + virtual bool IsWholeFile() const MOZ_OVERRIDE 1.347 + { 1.348 + return mWholeFile; 1.349 + } 1.350 + 1.351 + nsCOMPtr<nsIFile> mFile; 1.352 + bool mWholeFile; 1.353 + bool mStoredFile; 1.354 +}; 1.355 + 1.356 +/** 1.357 + * This class may be used off the main thread, and in particular, its 1.358 + * constructor and destructor may not run on the same thread. Be careful! 1.359 + */ 1.360 +class nsDOMMemoryFile : public nsDOMFile 1.361 +{ 1.362 +public: 1.363 + // Create as file 1.364 + nsDOMMemoryFile(void *aMemoryBuffer, 1.365 + uint64_t aLength, 1.366 + const nsAString& aName, 1.367 + const nsAString& aContentType) 1.368 + : nsDOMFile(aName, aContentType, aLength, UINT64_MAX), 1.369 + mDataOwner(new DataOwner(aMemoryBuffer, aLength)) 1.370 + { 1.371 + NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data"); 1.372 + } 1.373 + 1.374 + // Create as blob 1.375 + nsDOMMemoryFile(void *aMemoryBuffer, 1.376 + uint64_t aLength, 1.377 + const nsAString& aContentType) 1.378 + : nsDOMFile(aContentType, aLength), 1.379 + mDataOwner(new DataOwner(aMemoryBuffer, aLength)) 1.380 + { 1.381 + NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data"); 1.382 + } 1.383 + 1.384 + NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE; 1.385 + 1.386 + NS_IMETHOD_(bool) IsMemoryFile(void) MOZ_OVERRIDE; 1.387 + 1.388 +protected: 1.389 + // Create slice 1.390 + nsDOMMemoryFile(const nsDOMMemoryFile* aOther, uint64_t aStart, 1.391 + uint64_t aLength, const nsAString& aContentType) 1.392 + : nsDOMFile(aContentType, aOther->mStart + aStart, aLength), 1.393 + mDataOwner(aOther->mDataOwner) 1.394 + { 1.395 + NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data"); 1.396 + mImmutable = aOther->mImmutable; 1.397 + } 1.398 + virtual already_AddRefed<nsIDOMBlob> 1.399 + CreateSlice(uint64_t aStart, uint64_t aLength, 1.400 + const nsAString& aContentType) MOZ_OVERRIDE; 1.401 + 1.402 + // These classes need to see DataOwner. 1.403 + friend class DataOwnerAdapter; 1.404 + friend class nsDOMMemoryFileDataOwnerMemoryReporter; 1.405 + 1.406 + class DataOwner MOZ_FINAL : public mozilla::LinkedListElement<DataOwner> { 1.407 + public: 1.408 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataOwner) 1.409 + DataOwner(void* aMemoryBuffer, uint64_t aLength) 1.410 + : mData(aMemoryBuffer) 1.411 + , mLength(aLength) 1.412 + { 1.413 + mozilla::StaticMutexAutoLock lock(sDataOwnerMutex); 1.414 + 1.415 + if (!sDataOwners) { 1.416 + sDataOwners = new mozilla::LinkedList<DataOwner>(); 1.417 + EnsureMemoryReporterRegistered(); 1.418 + } 1.419 + sDataOwners->insertBack(this); 1.420 + } 1.421 + 1.422 + private: 1.423 + // Private destructor, to discourage deletion outside of Release(): 1.424 + ~DataOwner() { 1.425 + mozilla::StaticMutexAutoLock lock(sDataOwnerMutex); 1.426 + 1.427 + remove(); 1.428 + if (sDataOwners->isEmpty()) { 1.429 + // Free the linked list if it's empty. 1.430 + sDataOwners = nullptr; 1.431 + } 1.432 + 1.433 + moz_free(mData); 1.434 + } 1.435 + 1.436 + public: 1.437 + static void EnsureMemoryReporterRegistered(); 1.438 + 1.439 + // sDataOwners and sMemoryReporterRegistered may only be accessed while 1.440 + // holding sDataOwnerMutex! You also must hold the mutex while touching 1.441 + // elements of the linked list that DataOwner inherits from. 1.442 + static mozilla::StaticMutex sDataOwnerMutex; 1.443 + static mozilla::StaticAutoPtr<mozilla::LinkedList<DataOwner> > sDataOwners; 1.444 + static bool sMemoryReporterRegistered; 1.445 + 1.446 + void* mData; 1.447 + uint64_t mLength; 1.448 + }; 1.449 + 1.450 + // Used when backed by a memory store 1.451 + nsRefPtr<DataOwner> mDataOwner; 1.452 +}; 1.453 + 1.454 +class nsDOMFileList MOZ_FINAL : public nsIDOMFileList, 1.455 + public nsWrapperCache 1.456 +{ 1.457 +public: 1.458 + nsDOMFileList(nsISupports *aParent) : mParent(aParent) 1.459 + { 1.460 + SetIsDOMBinding(); 1.461 + } 1.462 + 1.463 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.464 + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMFileList) 1.465 + 1.466 + NS_DECL_NSIDOMFILELIST 1.467 + 1.468 + virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE; 1.469 + 1.470 + nsISupports* GetParentObject() 1.471 + { 1.472 + return mParent; 1.473 + } 1.474 + 1.475 + void Disconnect() 1.476 + { 1.477 + mParent = nullptr; 1.478 + } 1.479 + 1.480 + bool Append(nsIDOMFile *aFile) { return mFiles.AppendObject(aFile); } 1.481 + 1.482 + bool Remove(uint32_t aIndex) { return mFiles.RemoveObjectAt(aIndex); } 1.483 + void Clear() { return mFiles.Clear(); } 1.484 + 1.485 + static nsDOMFileList* FromSupports(nsISupports* aSupports) 1.486 + { 1.487 +#ifdef DEBUG 1.488 + { 1.489 + nsCOMPtr<nsIDOMFileList> list_qi = do_QueryInterface(aSupports); 1.490 + 1.491 + // If this assertion fires the QI implementation for the object in 1.492 + // question doesn't use the nsIDOMFileList pointer as the nsISupports 1.493 + // pointer. That must be fixed, or we'll crash... 1.494 + NS_ASSERTION(list_qi == static_cast<nsIDOMFileList*>(aSupports), 1.495 + "Uh, fix QI!"); 1.496 + } 1.497 +#endif 1.498 + 1.499 + return static_cast<nsDOMFileList*>(aSupports); 1.500 + } 1.501 + 1.502 + nsIDOMFile* Item(uint32_t aIndex) 1.503 + { 1.504 + return mFiles.SafeObjectAt(aIndex); 1.505 + } 1.506 + nsIDOMFile* IndexedGetter(uint32_t aIndex, bool& aFound) 1.507 + { 1.508 + aFound = aIndex < static_cast<uint32_t>(mFiles.Count()); 1.509 + return aFound ? mFiles.ObjectAt(aIndex) : nullptr; 1.510 + } 1.511 + uint32_t Length() 1.512 + { 1.513 + return mFiles.Count(); 1.514 + } 1.515 + 1.516 +private: 1.517 + nsCOMArray<nsIDOMFile> mFiles; 1.518 + nsISupports *mParent; 1.519 +}; 1.520 + 1.521 +class MOZ_STACK_CLASS nsDOMFileInternalUrlHolder { 1.522 +public: 1.523 + nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal 1.524 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM); 1.525 + ~nsDOMFileInternalUrlHolder(); 1.526 + nsAutoString mUrl; 1.527 +private: 1.528 + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 1.529 +}; 1.530 +// This class would take the ownership of aFD and the caller must not close it. 1.531 +class nsDOMTemporaryFileBlob : public nsDOMFile 1.532 +{ 1.533 +public: 1.534 + nsDOMTemporaryFileBlob(PRFileDesc* aFD, uint64_t aStartPos, uint64_t aLength, 1.535 + const nsAString& aContentType) 1.536 + : nsDOMFile(aContentType, aLength), 1.537 + mLength(aLength), 1.538 + mStartPos(aStartPos), 1.539 + mContentType(aContentType) 1.540 + { 1.541 + mFileDescOwner = new nsTemporaryFileInputStream::FileDescOwner(aFD); 1.542 + } 1.543 + 1.544 + ~nsDOMTemporaryFileBlob() { } 1.545 + NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE; 1.546 + 1.547 +protected: 1.548 + nsDOMTemporaryFileBlob(const nsDOMTemporaryFileBlob* aOther, uint64_t aStart, uint64_t aLength, 1.549 + const nsAString& aContentType) 1.550 + : nsDOMFile(aContentType, aLength), 1.551 + mLength(aLength), 1.552 + mStartPos(aStart), 1.553 + mFileDescOwner(aOther->mFileDescOwner), 1.554 + mContentType(aContentType) { } 1.555 + 1.556 + virtual already_AddRefed<nsIDOMBlob> 1.557 + CreateSlice(uint64_t aStart, uint64_t aLength, 1.558 + const nsAString& aContentType) MOZ_OVERRIDE; 1.559 + 1.560 +private: 1.561 + uint64_t mLength; 1.562 + uint64_t mStartPos; 1.563 + nsRefPtr<nsTemporaryFileInputStream::FileDescOwner> mFileDescOwner; 1.564 + nsString mContentType; 1.565 +}; 1.566 + 1.567 +#endif