diff options
Diffstat (limited to 'dom/base/FileReader.h')
-rw-r--r-- | dom/base/FileReader.h | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/dom/base/FileReader.h b/dom/base/FileReader.h new file mode 100644 index 000000000..225385e13 --- /dev/null +++ b/dom/base/FileReader.h @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_FileReader_h +#define mozilla_dom_FileReader_h + +#include "mozilla/Attributes.h" +#include "mozilla/DOMEventTargetHelper.h" + +#include "nsIAsyncInputStream.h" +#include "nsIInterfaceRequestor.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsWeakReference.h" +#include "WorkerHolder.h" + +#define NS_PROGRESS_EVENT_INTERVAL 50 + +class nsITimer; +class nsIEventTarget; + +namespace mozilla { +namespace dom { + +class Blob; +class DOMError; + +namespace workers { +class WorkerPrivate; +} + +extern const uint64_t kUnknownSize; + +class FileReaderDecreaseBusyCounter; + +class FileReader final : public DOMEventTargetHelper, + public nsIInterfaceRequestor, + public nsSupportsWeakReference, + public nsIInputStreamCallback, + public nsITimerCallback, + public workers::WorkerHolder +{ + friend class FileReaderDecreaseBusyCounter; + +public: + FileReader(nsIGlobalObject* aGlobal, + workers::WorkerPrivate* aWorkerPrivate); + + NS_DECL_ISUPPORTS_INHERITED + + NS_DECL_NSITIMERCALLBACK + NS_DECL_NSIINPUTSTREAMCALLBACK + NS_DECL_NSIINTERFACEREQUESTOR + + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader, + DOMEventTargetHelper) + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + // WebIDL + static already_AddRefed<FileReader> + Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); + void ReadAsArrayBuffer(JSContext* aCx, Blob& aBlob, ErrorResult& aRv) + { + ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv); + } + + void ReadAsText(Blob& aBlob, const nsAString& aLabel, ErrorResult& aRv) + { + ReadFileContent(aBlob, aLabel, FILE_AS_TEXT, aRv); + } + + void ReadAsDataURL(Blob& aBlob, ErrorResult& aRv) + { + ReadFileContent(aBlob, EmptyString(), FILE_AS_DATAURL, aRv); + } + + void Abort(ErrorResult& aRv); + + uint16_t ReadyState() const + { + return static_cast<uint16_t>(mReadyState); + } + + DOMError* GetError() const + { + return mError; + } + + void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, + ErrorResult& aRv); + + IMPL_EVENT_HANDLER(loadstart) + IMPL_EVENT_HANDLER(progress) + IMPL_EVENT_HANDLER(load) + IMPL_EVENT_HANDLER(abort) + IMPL_EVENT_HANDLER(error) + IMPL_EVENT_HANDLER(loadend) + + void ReadAsBinaryString(Blob& aBlob, ErrorResult& aRv) + { + ReadFileContent(aBlob, EmptyString(), FILE_AS_BINARY, aRv); + } + + // WorkerHolder + bool Notify(workers::Status) override; + +private: + virtual ~FileReader(); + + // This must be in sync with dom/webidl/FileReader.webidl + enum eReadyState { + EMPTY = 0, + LOADING = 1, + DONE = 2 + }; + + enum eDataFormat { + FILE_AS_ARRAYBUFFER, + FILE_AS_BINARY, + FILE_AS_TEXT, + FILE_AS_DATAURL + }; + + void RootResultArrayBuffer(); + + void ReadFileContent(Blob& aBlob, + const nsAString &aCharset, eDataFormat aDataFormat, + ErrorResult& aRv); + nsresult GetAsText(Blob *aBlob, const nsACString &aCharset, + const char *aFileData, uint32_t aDataLen, + nsAString &aResult); + nsresult GetAsDataURL(Blob *aBlob, const char *aFileData, + uint32_t aDataLen, nsAString &aResult); + + nsresult OnLoadEnd(nsresult aStatus); + + void StartProgressEventTimer(); + void ClearProgressEventTimer(); + + void FreeDataAndDispatchSuccess(); + void FreeDataAndDispatchError(); + void FreeDataAndDispatchError(nsresult aRv); + nsresult DispatchProgressEvent(const nsAString& aType); + + nsresult DoAsyncWait(); + nsresult DoReadData(uint64_t aCount); + + void OnLoadEndArrayBuffer(); + + void FreeFileData() + { + free(mFileData); + mFileData = nullptr; + mDataLen = 0; + } + + nsresult IncreaseBusyCounter(); + void DecreaseBusyCounter(); + + void Shutdown(); + + char *mFileData; + RefPtr<Blob> mBlob; + nsCString mCharset; + uint32_t mDataLen; + + eDataFormat mDataFormat; + + nsString mResult; + + JS::Heap<JSObject*> mResultArrayBuffer; + + nsCOMPtr<nsITimer> mProgressNotifier; + bool mProgressEventWasDelayed; + bool mTimerIsActive; + + nsCOMPtr<nsIAsyncInputStream> mAsyncStream; + + RefPtr<DOMError> mError; + + eReadyState mReadyState; + + uint64_t mTotal; + uint64_t mTransferred; + + nsCOMPtr<nsIEventTarget> mTarget; + + uint64_t mBusyCount; + + // Kept alive with a WorkerHolder. + workers::WorkerPrivate* mWorkerPrivate; +}; + +} // dom namespace +} // mozilla namespace + +#endif // mozilla_dom_FileReader_h |