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