Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef nsBaseContentStream_h__ |
michael@0 | 7 | #define nsBaseContentStream_h__ |
michael@0 | 8 | |
michael@0 | 9 | #include "nsIAsyncInputStream.h" |
michael@0 | 10 | #include "nsIEventTarget.h" |
michael@0 | 11 | #include "nsCOMPtr.h" |
michael@0 | 12 | |
michael@0 | 13 | //----------------------------------------------------------------------------- |
michael@0 | 14 | // nsBaseContentStream is designed to be subclassed with the intention of being |
michael@0 | 15 | // used to satisfy the nsBaseChannel::OpenContentStream method. |
michael@0 | 16 | // |
michael@0 | 17 | // The subclass typically overrides the default Available, ReadSegments and |
michael@0 | 18 | // CloseWithStatus methods. By default, Read is implemented in terms of |
michael@0 | 19 | // ReadSegments, and Close is implemented in terms of CloseWithStatus. If |
michael@0 | 20 | // CloseWithStatus is overriden, then the subclass will usually want to call |
michael@0 | 21 | // the base class' CloseWithStatus method before returning. |
michael@0 | 22 | // |
michael@0 | 23 | // If the stream is non-blocking, then readSegments may return the exception |
michael@0 | 24 | // NS_BASE_STREAM_WOULD_BLOCK if there is no data available and the stream is |
michael@0 | 25 | // not at the "end-of-file" or already closed. This error code must not be |
michael@0 | 26 | // returned from the Available implementation. When the caller receives this |
michael@0 | 27 | // error code, he may choose to call the stream's AsyncWait method, in which |
michael@0 | 28 | // case the base stream will have a non-null PendingCallback. When the stream |
michael@0 | 29 | // has data or encounters an error, it should be sure to dispatch a pending |
michael@0 | 30 | // callback if one exists (see DispatchCallback). The implementation of the |
michael@0 | 31 | // base stream's CloseWithStatus (and Close) method will ensure that any |
michael@0 | 32 | // pending callback is dispatched. It is the responsibility of the subclass |
michael@0 | 33 | // to ensure that the pending callback is dispatched when it wants to have its |
michael@0 | 34 | // ReadSegments method called again. |
michael@0 | 35 | |
michael@0 | 36 | class nsBaseContentStream : public nsIAsyncInputStream |
michael@0 | 37 | { |
michael@0 | 38 | public: |
michael@0 | 39 | NS_DECL_THREADSAFE_ISUPPORTS |
michael@0 | 40 | NS_DECL_NSIINPUTSTREAM |
michael@0 | 41 | NS_DECL_NSIASYNCINPUTSTREAM |
michael@0 | 42 | |
michael@0 | 43 | nsBaseContentStream(bool nonBlocking) |
michael@0 | 44 | : mStatus(NS_OK) |
michael@0 | 45 | , mNonBlocking(nonBlocking) { |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | nsresult Status() { return mStatus; } |
michael@0 | 49 | bool IsNonBlocking() { return mNonBlocking; } |
michael@0 | 50 | bool IsClosed() { return NS_FAILED(mStatus); } |
michael@0 | 51 | |
michael@0 | 52 | // Called to test if the stream has a pending callback. |
michael@0 | 53 | bool HasPendingCallback() { return mCallback != nullptr; } |
michael@0 | 54 | |
michael@0 | 55 | // The current dispatch target (may be null) for the pending callback if any. |
michael@0 | 56 | nsIEventTarget *CallbackTarget() { return mCallbackTarget; } |
michael@0 | 57 | |
michael@0 | 58 | // Called to dispatch a pending callback. If there is no pending callback, |
michael@0 | 59 | // then this function does nothing. Pass true to this function to cause the |
michael@0 | 60 | // callback to occur asynchronously; otherwise, the callback will happen |
michael@0 | 61 | // before this function returns. |
michael@0 | 62 | void DispatchCallback(bool async = true); |
michael@0 | 63 | |
michael@0 | 64 | // Helper function to make code more self-documenting. |
michael@0 | 65 | void DispatchCallbackSync() { DispatchCallback(false); } |
michael@0 | 66 | |
michael@0 | 67 | protected: |
michael@0 | 68 | virtual ~nsBaseContentStream() {} |
michael@0 | 69 | |
michael@0 | 70 | private: |
michael@0 | 71 | // Called from the base stream's AsyncWait method when a pending callback |
michael@0 | 72 | // is installed on the stream. |
michael@0 | 73 | virtual void OnCallbackPending() {} |
michael@0 | 74 | |
michael@0 | 75 | private: |
michael@0 | 76 | nsCOMPtr<nsIInputStreamCallback> mCallback; |
michael@0 | 77 | nsCOMPtr<nsIEventTarget> mCallbackTarget; |
michael@0 | 78 | nsresult mStatus; |
michael@0 | 79 | bool mNonBlocking; |
michael@0 | 80 | }; |
michael@0 | 81 | |
michael@0 | 82 | #endif // nsBaseContentStream_h__ |