nsBaseContentStream.h 3.4 KB

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