dom/file/LockedFile.h

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

mercurial