netwerk/base/src/nsBaseContentStream.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:5070c35966bf
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 #include "nsBaseContentStream.h"
7 #include "nsStreamUtils.h"
8
9 //-----------------------------------------------------------------------------
10
11 void
12 nsBaseContentStream::DispatchCallback(bool async)
13 {
14 if (!mCallback)
15 return;
16
17 // It's important to clear mCallback and mCallbackTarget up-front because the
18 // OnInputStreamReady implementation may call our AsyncWait method.
19
20 nsCOMPtr<nsIInputStreamCallback> callback;
21 if (async) {
22 callback = NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget);
23 mCallback = nullptr;
24 } else {
25 callback.swap(mCallback);
26 }
27 mCallbackTarget = nullptr;
28
29 callback->OnInputStreamReady(this);
30 }
31
32 //-----------------------------------------------------------------------------
33 // nsBaseContentStream::nsISupports
34
35 NS_IMPL_ADDREF(nsBaseContentStream)
36 NS_IMPL_RELEASE(nsBaseContentStream)
37
38 // We only support nsIAsyncInputStream when we are in non-blocking mode.
39 NS_INTERFACE_MAP_BEGIN(nsBaseContentStream)
40 NS_INTERFACE_MAP_ENTRY(nsIInputStream)
41 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream, mNonBlocking)
42 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
43 NS_INTERFACE_MAP_END_THREADSAFE
44
45 //-----------------------------------------------------------------------------
46 // nsBaseContentStream::nsIInputStream
47
48 NS_IMETHODIMP
49 nsBaseContentStream::Close()
50 {
51 return IsClosed() ? NS_OK : CloseWithStatus(NS_BASE_STREAM_CLOSED);
52 }
53
54 NS_IMETHODIMP
55 nsBaseContentStream::Available(uint64_t *result)
56 {
57 *result = 0;
58 return mStatus;
59 }
60
61 NS_IMETHODIMP
62 nsBaseContentStream::Read(char *buf, uint32_t count, uint32_t *result)
63 {
64 return ReadSegments(NS_CopySegmentToBuffer, buf, count, result);
65 }
66
67 NS_IMETHODIMP
68 nsBaseContentStream::ReadSegments(nsWriteSegmentFun fun, void *closure,
69 uint32_t count, uint32_t *result)
70 {
71 *result = 0;
72
73 if (mStatus == NS_BASE_STREAM_CLOSED)
74 return NS_OK;
75
76 // No data yet
77 if (!IsClosed() && IsNonBlocking())
78 return NS_BASE_STREAM_WOULD_BLOCK;
79
80 return mStatus;
81 }
82
83 NS_IMETHODIMP
84 nsBaseContentStream::IsNonBlocking(bool *result)
85 {
86 *result = mNonBlocking;
87 return NS_OK;
88 }
89
90 //-----------------------------------------------------------------------------
91 // nsBaseContentStream::nsIAsyncInputStream
92
93 NS_IMETHODIMP
94 nsBaseContentStream::CloseWithStatus(nsresult status)
95 {
96 if (IsClosed())
97 return NS_OK;
98
99 NS_ENSURE_ARG(NS_FAILED(status));
100 mStatus = status;
101
102 DispatchCallback();
103 return NS_OK;
104 }
105
106 NS_IMETHODIMP
107 nsBaseContentStream::AsyncWait(nsIInputStreamCallback *callback,
108 uint32_t flags, uint32_t requestedCount,
109 nsIEventTarget *target)
110 {
111 // Our _only_ consumer is nsInputStreamPump, so we simplify things here by
112 // making assumptions about how we will be called.
113 NS_ASSERTION(target, "unexpected parameter");
114 NS_ASSERTION(flags == 0, "unexpected parameter");
115 NS_ASSERTION(requestedCount == 0, "unexpected parameter");
116
117 #ifdef DEBUG
118 bool correctThread;
119 target->IsOnCurrentThread(&correctThread);
120 NS_ASSERTION(correctThread, "event target must be on the current thread");
121 #endif
122
123 mCallback = callback;
124 mCallbackTarget = target;
125
126 if (!mCallback)
127 return NS_OK;
128
129 // If we're already closed, then dispatch this callback immediately.
130 if (IsClosed()) {
131 DispatchCallback();
132 return NS_OK;
133 }
134
135 OnCallbackPending();
136 return NS_OK;
137 }

mercurial