nsBaseContentStream.h (3393B)
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 nsBaseContentStream_h__ 7 #define nsBaseContentStream_h__ 8 9 #include "nsIAsyncInputStream.h" 10 #include "nsIEventTarget.h" 11 #include "nsCOMPtr.h" 12 13 //----------------------------------------------------------------------------- 14 // nsBaseContentStream is designed to be subclassed with the intention of being 15 // used to satisfy the nsBaseChannel::OpenContentStream method. 16 // 17 // The subclass typically overrides the default Available, ReadSegments and 18 // CloseWithStatus methods. By default, Read is implemented in terms of 19 // ReadSegments, and Close is implemented in terms of CloseWithStatus. If 20 // CloseWithStatus is overriden, then the subclass will usually want to call 21 // the base class' CloseWithStatus method before returning. 22 // 23 // If the stream is non-blocking, then readSegments may return the exception 24 // NS_BASE_STREAM_WOULD_BLOCK if there is no data available and the stream is 25 // not at the "end-of-file" or already closed. This error code must not be 26 // returned from the Available implementation. When the caller receives this 27 // error code, he may choose to call the stream's AsyncWait method, in which 28 // case the base stream will have a non-null PendingCallback. When the stream 29 // has data or encounters an error, it should be sure to dispatch a pending 30 // callback if one exists (see DispatchCallback). The implementation of the 31 // base stream's CloseWithStatus (and Close) method will ensure that any 32 // pending callback is dispatched. It is the responsibility of the subclass 33 // to ensure that the pending callback is dispatched when it wants to have its 34 // ReadSegments method called again. 35 36 class nsBaseContentStream : public nsIAsyncInputStream { 37 public: 38 NS_DECL_THREADSAFE_ISUPPORTS 39 NS_DECL_NSIINPUTSTREAM 40 NS_DECL_NSIASYNCINPUTSTREAM 41 42 explicit nsBaseContentStream(bool nonBlocking) 43 : mStatus(NS_OK), mNonBlocking(nonBlocking) {} 44 45 nsresult Status() { return mStatus; } 46 bool IsNonBlocking() { return mNonBlocking; } 47 bool IsClosed() { return NS_FAILED(mStatus); } 48 49 // Called to test if the stream has a pending callback. 50 bool HasPendingCallback() { return mCallback != nullptr; } 51 52 // The current dispatch target (may be null) for the pending callback if any. 53 nsIEventTarget* CallbackTarget() { return mCallbackTarget; } 54 55 // Called to dispatch a pending callback. If there is no pending callback, 56 // then this function does nothing. Pass true to this function to cause the 57 // callback to occur asynchronously; otherwise, the callback will happen 58 // before this function returns. 59 void DispatchCallback(bool async = true); 60 61 // Helper function to make code more self-documenting. 62 void DispatchCallbackSync() { DispatchCallback(false); } 63 64 protected: 65 virtual ~nsBaseContentStream() = default; 66 67 private: 68 // Called from the base stream's AsyncWait method when a pending callback 69 // is installed on the stream. 70 virtual void OnCallbackPending() {} 71 72 private: 73 nsCOMPtr<nsIInputStreamCallback> mCallback; 74 nsCOMPtr<nsIEventTarget> mCallbackTarget; 75 nsresult mStatus; 76 bool mNonBlocking; 77 }; 78 79 #endif // nsBaseContentStream_h__