/* -*- 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