Line data Source code
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 :
6 : #ifndef SimpleChannel_h
7 : #define SimpleChannel_h
8 :
9 : #include "mozilla/Result.h"
10 : #include "mozilla/UniquePtr.h"
11 : #include "nsCOMPtr.h"
12 :
13 : class nsIChannel;
14 : class nsIInputStream;
15 : class nsILoadInfo;
16 : class nsIRequest;
17 : class nsIStreamListener;
18 : class nsIURI;
19 :
20 : //-----------------------------------------------------------------------------
21 :
22 : namespace mozilla {
23 :
24 : using InputStreamOrReason = Result<nsCOMPtr<nsIInputStream>, nsresult>;
25 : using RequestOrReason = Result<nsCOMPtr<nsIRequest>, nsresult>;
26 :
27 : namespace net {
28 :
29 0 : class SimpleChannelCallbacks
30 : {
31 : public:
32 : virtual InputStreamOrReason OpenContentStream(bool async, nsIChannel* channel) = 0;
33 :
34 : virtual RequestOrReason StartAsyncRead(nsIStreamListener* stream, nsIChannel* channel) = 0;
35 :
36 0 : virtual ~SimpleChannelCallbacks() {}
37 : };
38 :
39 : template <typename F1, typename F2, typename T>
40 : class SimpleChannelCallbacksImpl final : public SimpleChannelCallbacks
41 : {
42 : public:
43 0 : SimpleChannelCallbacksImpl(F1&& aStartAsyncRead, F2&& aOpenContentStream, T* context)
44 : : mStartAsyncRead(aStartAsyncRead)
45 : , mOpenContentStream(aOpenContentStream)
46 0 : , mContext(context)
47 0 : {}
48 :
49 0 : virtual ~SimpleChannelCallbacksImpl() {}
50 :
51 0 : virtual InputStreamOrReason OpenContentStream(bool async, nsIChannel* channel) override
52 : {
53 0 : return mOpenContentStream(async, channel, mContext);
54 : }
55 :
56 0 : virtual RequestOrReason StartAsyncRead(nsIStreamListener* listener, nsIChannel* channel) override
57 : {
58 0 : return mStartAsyncRead(listener, channel, mContext);
59 : }
60 :
61 : private:
62 : F1 mStartAsyncRead;
63 : F2 mOpenContentStream;
64 : RefPtr<T> mContext;
65 : };
66 :
67 : already_AddRefed<nsIChannel>
68 : NS_NewSimpleChannelInternal(nsIURI* aURI, nsILoadInfo* aLoadInfo, UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
69 :
70 : } // namespace net
71 : } // namespace mozilla
72 :
73 : /**
74 : * Creates a simple channel which wraps an input stream created by the given
75 : * callbacks. The callbacks are not called until the underlying AsyncOpen2 or
76 : * Open2 methods are called, and correspond to the nsBaseChannel::StartAsyncRead
77 : * and nsBaseChannel::OpenContentStream methods of the same names.
78 : *
79 : * The last two arguments of each callback are the created channel instance,
80 : * and the ref-counted context object passed to NS_NewSimpleChannel. A strong
81 : * reference to that object is guaranteed to be kept alive until after a
82 : * callback successfully completes.
83 : */
84 : template <typename T, typename F1, typename F2>
85 : inline already_AddRefed<nsIChannel>
86 0 : NS_NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo, T* context, F1&& aStartAsyncRead, F2&& aOpenContentStream)
87 : {
88 : using namespace mozilla;
89 :
90 : auto callbacks = MakeUnique<net::SimpleChannelCallbacksImpl<F1, F2, T>>(
91 0 : Move(aStartAsyncRead), Move(aOpenContentStream), context);
92 :
93 0 : return net::NS_NewSimpleChannelInternal(aURI, aLoadInfo, Move(callbacks));
94 : }
95 :
96 : template <typename T, typename F1>
97 : inline already_AddRefed<nsIChannel>
98 0 : NS_NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo, T* context, F1&& aStartAsyncRead)
99 : {
100 : using namespace mozilla;
101 :
102 0 : auto openContentStream = [] (bool async, nsIChannel* channel, T* context) {
103 : return Err(NS_ERROR_NOT_IMPLEMENTED);
104 0 : };
105 :
106 : return NS_NewSimpleChannel(
107 0 : aURI, aLoadInfo, context, Move(aStartAsyncRead), Move(openContentStream));
108 : }
109 :
110 : #endif // SimpleChannel_h
|