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/. */
6 #ifndef SimpleChannel_h
7 #define SimpleChannel_h
9 #include "mozilla/ResultExtensions.h"
10 #include "mozilla/UniquePtr.h"
11 #include "nsBaseChannel.h"
12 #include "nsIChildChannel.h"
13 #include "mozilla/net/PSimpleChannelChild.h"
20 class nsIStreamListener
;
23 //-----------------------------------------------------------------------------
27 using InputStreamOrReason
= Result
<nsCOMPtr
<nsIInputStream
>, nsresult
>;
28 using NotNullRequest
= NotNull
<nsCOMPtr
<nsIRequest
>>;
29 using NotNullCancelable
= NotNull
<nsCOMPtr
<nsICancelable
>>;
30 using RequestOrCancelable
= Variant
<NotNullRequest
, NotNullCancelable
>;
31 using RequestOrReason
= Result
<RequestOrCancelable
, nsresult
>;
35 class SimpleChannelCallbacks
{
37 virtual InputStreamOrReason
OpenContentStream(bool async
,
38 nsIChannel
* channel
) = 0;
40 virtual RequestOrReason
StartAsyncRead(nsIStreamListener
* stream
,
41 nsIChannel
* channel
) = 0;
43 virtual ~SimpleChannelCallbacks() = default;
46 template <typename F1
, typename F2
, typename T
>
47 class SimpleChannelCallbacksImpl final
: public SimpleChannelCallbacks
{
49 SimpleChannelCallbacksImpl(F1
&& aStartAsyncRead
, F2
&& aOpenContentStream
,
51 : mStartAsyncRead(aStartAsyncRead
),
52 mOpenContentStream(aOpenContentStream
),
55 virtual ~SimpleChannelCallbacksImpl() = default;
57 virtual InputStreamOrReason
OpenContentStream(bool async
,
58 nsIChannel
* channel
) override
{
59 return mOpenContentStream(async
, channel
, mContext
);
62 virtual RequestOrReason
StartAsyncRead(nsIStreamListener
* listener
,
63 nsIChannel
* channel
) override
{
64 return mStartAsyncRead(listener
, channel
, mContext
);
69 F2 mOpenContentStream
;
73 class SimpleChannel
: public nsBaseChannel
{
75 explicit SimpleChannel(UniquePtr
<SimpleChannelCallbacks
>&& aCallbacks
);
78 virtual ~SimpleChannel() = default;
80 virtual nsresult
OpenContentStream(bool async
, nsIInputStream
** streamOut
,
81 nsIChannel
** channel
) override
;
83 virtual nsresult
BeginAsyncRead(nsIStreamListener
* listener
,
85 nsICancelable
** cancelableRequest
) override
;
88 UniquePtr
<SimpleChannelCallbacks
> mCallbacks
;
91 class SimpleChannelChild final
: public SimpleChannel
,
92 public nsIChildChannel
,
93 public PSimpleChannelChild
{
95 explicit SimpleChannelChild(UniquePtr
<SimpleChannelCallbacks
>&& aCallbacks
);
97 NS_DECL_ISUPPORTS_INHERITED
98 NS_DECL_NSICHILDCHANNEL
101 virtual ~SimpleChannelChild() = default;
104 already_AddRefed
<nsIChannel
> NS_NewSimpleChannelInternal(
105 nsIURI
* aURI
, nsILoadInfo
* aLoadInfo
,
106 UniquePtr
<SimpleChannelCallbacks
>&& aCallbacks
);
109 } // namespace mozilla
112 * Creates a simple channel which wraps an input stream created by the given
113 * callbacks. The callbacks are not called until the underlying AsyncOpen or
114 * Open methods are called, and correspond to the nsBaseChannel::StartAsyncRead
115 * and nsBaseChannel::OpenContentStream methods of the same names.
117 * The last two arguments of each callback are the created channel instance,
118 * and the ref-counted context object passed to NS_NewSimpleChannel. A strong
119 * reference to that object is guaranteed to be kept alive until after a
120 * callback successfully completes.
122 template <typename T
, typename F1
, typename F2
>
123 inline already_AddRefed
<nsIChannel
> NS_NewSimpleChannel(
124 nsIURI
* aURI
, nsILoadInfo
* aLoadInfo
, T
* context
, F1
&& aStartAsyncRead
,
125 F2
&& aOpenContentStream
) {
126 using namespace mozilla
;
128 auto callbacks
= MakeUnique
<net::SimpleChannelCallbacksImpl
<F1
, F2
, T
>>(
129 std::forward
<F1
>(aStartAsyncRead
), std::forward
<F2
>(aOpenContentStream
),
132 return net::NS_NewSimpleChannelInternal(aURI
, aLoadInfo
,
133 std::move(callbacks
));
136 template <typename T
, typename F1
>
137 inline already_AddRefed
<nsIChannel
> NS_NewSimpleChannel(nsIURI
* aURI
,
138 nsILoadInfo
* aLoadInfo
,
140 F1
&& aStartAsyncRead
) {
141 using namespace mozilla
;
143 auto openContentStream
= [](bool async
, nsIChannel
* channel
, T
* context
) {
144 return Err(NS_ERROR_NOT_IMPLEMENTED
);
147 return NS_NewSimpleChannel(aURI
, aLoadInfo
, context
,
148 std::forward
<F1
>(aStartAsyncRead
),
149 std::move(openContentStream
));
152 #endif // SimpleChannel_h