Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=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
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef mozilla_dom_FileReader_h
8 : #define mozilla_dom_FileReader_h
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "mozilla/DOMEventTargetHelper.h"
12 :
13 : #include "nsIAsyncInputStream.h"
14 : #include "nsIInterfaceRequestor.h"
15 : #include "nsCOMPtr.h"
16 : #include "nsString.h"
17 : #include "nsWeakReference.h"
18 : #include "WorkerHolder.h"
19 :
20 : #define NS_PROGRESS_EVENT_INTERVAL 50
21 :
22 : class nsITimer;
23 : class nsIEventTarget;
24 :
25 : namespace mozilla {
26 : namespace dom {
27 :
28 : class Blob;
29 : class DOMError;
30 :
31 : namespace workers {
32 : class WorkerPrivate;
33 : }
34 :
35 : extern const uint64_t kUnknownSize;
36 :
37 : class FileReaderDecreaseBusyCounter;
38 :
39 : class FileReader final : public DOMEventTargetHelper,
40 : public nsIInterfaceRequestor,
41 : public nsSupportsWeakReference,
42 : public nsIInputStreamCallback,
43 : public nsITimerCallback,
44 : public workers::WorkerHolder
45 : {
46 : friend class FileReaderDecreaseBusyCounter;
47 :
48 : public:
49 : FileReader(nsIGlobalObject* aGlobal,
50 : workers::WorkerPrivate* aWorkerPrivate);
51 :
52 : NS_DECL_ISUPPORTS_INHERITED
53 :
54 : NS_DECL_NSITIMERCALLBACK
55 : NS_DECL_NSIINPUTSTREAMCALLBACK
56 : NS_DECL_NSIINTERFACEREQUESTOR
57 :
58 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader,
59 : DOMEventTargetHelper)
60 :
61 : virtual JSObject* WrapObject(JSContext* aCx,
62 : JS::Handle<JSObject*> aGivenProto) override;
63 :
64 : // WebIDL
65 : static already_AddRefed<FileReader>
66 : Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
67 0 : void ReadAsArrayBuffer(JSContext* aCx, Blob& aBlob, ErrorResult& aRv)
68 : {
69 0 : ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
70 0 : }
71 :
72 0 : void ReadAsText(Blob& aBlob, const nsAString& aLabel, ErrorResult& aRv)
73 : {
74 0 : ReadFileContent(aBlob, aLabel, FILE_AS_TEXT, aRv);
75 0 : }
76 :
77 0 : void ReadAsDataURL(Blob& aBlob, ErrorResult& aRv)
78 : {
79 0 : ReadFileContent(aBlob, EmptyString(), FILE_AS_DATAURL, aRv);
80 0 : }
81 :
82 : void Abort();
83 :
84 0 : uint16_t ReadyState() const
85 : {
86 0 : return static_cast<uint16_t>(mReadyState);
87 : }
88 :
89 0 : DOMError* GetError() const
90 : {
91 0 : return mError;
92 : }
93 :
94 : void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
95 : ErrorResult& aRv);
96 :
97 0 : IMPL_EVENT_HANDLER(loadstart)
98 0 : IMPL_EVENT_HANDLER(progress)
99 0 : IMPL_EVENT_HANDLER(load)
100 0 : IMPL_EVENT_HANDLER(abort)
101 0 : IMPL_EVENT_HANDLER(error)
102 0 : IMPL_EVENT_HANDLER(loadend)
103 :
104 0 : void ReadAsBinaryString(Blob& aBlob, ErrorResult& aRv)
105 : {
106 0 : ReadFileContent(aBlob, EmptyString(), FILE_AS_BINARY, aRv);
107 0 : }
108 :
109 : // WorkerHolder
110 : bool Notify(workers::Status) override;
111 :
112 : private:
113 : virtual ~FileReader();
114 :
115 : // This must be in sync with dom/webidl/FileReader.webidl
116 : enum eReadyState {
117 : EMPTY = 0,
118 : LOADING = 1,
119 : DONE = 2
120 : };
121 :
122 : enum eDataFormat {
123 : FILE_AS_ARRAYBUFFER,
124 : FILE_AS_BINARY,
125 : FILE_AS_TEXT,
126 : FILE_AS_DATAURL
127 : };
128 :
129 : void RootResultArrayBuffer();
130 :
131 : void ReadFileContent(Blob& aBlob,
132 : const nsAString &aCharset, eDataFormat aDataFormat,
133 : ErrorResult& aRv);
134 : nsresult GetAsText(Blob *aBlob, const nsACString &aCharset,
135 : const char *aFileData, uint32_t aDataLen,
136 : nsAString &aResult);
137 : nsresult GetAsDataURL(Blob *aBlob, const char *aFileData,
138 : uint32_t aDataLen, nsAString &aResult);
139 :
140 : nsresult OnLoadEnd(nsresult aStatus);
141 :
142 : void StartProgressEventTimer();
143 : void ClearProgressEventTimer();
144 :
145 : void FreeDataAndDispatchSuccess();
146 : void FreeDataAndDispatchError();
147 : void FreeDataAndDispatchError(nsresult aRv);
148 : nsresult DispatchProgressEvent(const nsAString& aType);
149 :
150 : nsresult DoAsyncWait();
151 : nsresult DoReadData(uint64_t aCount);
152 :
153 : void OnLoadEndArrayBuffer();
154 :
155 0 : void FreeFileData()
156 : {
157 0 : free(mFileData);
158 0 : mFileData = nullptr;
159 0 : mDataLen = 0;
160 0 : }
161 :
162 : nsresult IncreaseBusyCounter();
163 : void DecreaseBusyCounter();
164 :
165 : void Shutdown();
166 :
167 : char *mFileData;
168 : RefPtr<Blob> mBlob;
169 : nsCString mCharset;
170 : uint32_t mDataLen;
171 :
172 : eDataFormat mDataFormat;
173 :
174 : nsString mResult;
175 :
176 : JS::Heap<JSObject*> mResultArrayBuffer;
177 :
178 : nsCOMPtr<nsITimer> mProgressNotifier;
179 : bool mProgressEventWasDelayed;
180 : bool mTimerIsActive;
181 :
182 : nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
183 : nsCOMPtr<nsIInputStream> mBufferedStream;
184 :
185 : RefPtr<DOMError> mError;
186 :
187 : eReadyState mReadyState;
188 :
189 : uint64_t mTotal;
190 : uint64_t mTransferred;
191 :
192 : nsCOMPtr<nsIEventTarget> mTarget;
193 :
194 : uint64_t mBusyCount;
195 :
196 : // Kept alive with a WorkerHolder.
197 : workers::WorkerPrivate* mWorkerPrivate;
198 : };
199 :
200 : } // dom namespace
201 : } // mozilla namespace
202 :
203 : #endif // mozilla_dom_FileReader_h
|