Bug 1909986 - For sidebar revamp, only show chatbot entrypoints (context menu, shortc...
[gecko.git] / netwerk / protocol / http / AltDataOutputStreamChild.cpp
blob89e34a4694b8b0e49d0a6a4a55684e8005e38169
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/net/AltDataOutputStreamChild.h"
8 #include "mozilla/Unused.h"
9 #include "nsIInputStream.h"
10 #include "nsStreamUtils.h"
12 namespace mozilla {
13 namespace net {
15 NS_IMPL_ADDREF(AltDataOutputStreamChild)
17 NS_IMETHODIMP_(MozExternalRefCountType) AltDataOutputStreamChild::Release() {
18 MOZ_ASSERT(0 != mRefCnt, "dup release");
19 MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
20 --mRefCnt;
21 NS_LOG_RELEASE(this, mRefCnt, "AltDataOutputStreamChild");
23 if (mRefCnt == 1 && mIPCOpen) {
24 // The only reference left is the IPDL one. After the parent replies back
25 // with a DeleteSelf message, the child will call Send__delete__(this),
26 // decrementing the ref count and triggering the destructor.
27 SendDeleteSelf();
28 return 1;
31 if (mRefCnt == 0) {
32 mRefCnt = 1; /* stabilize */
33 delete this;
34 return 0;
36 return mRefCnt;
39 NS_INTERFACE_MAP_BEGIN(AltDataOutputStreamChild)
40 NS_INTERFACE_MAP_ENTRY(nsIAsyncOutputStream)
41 NS_INTERFACE_MAP_ENTRY(nsIOutputStream)
42 NS_INTERFACE_MAP_ENTRY(nsISupports)
43 NS_INTERFACE_MAP_END
45 AltDataOutputStreamChild::AltDataOutputStreamChild()
46 : mIPCOpen(false), mError(NS_OK), mCallbackFlags(0) {
47 MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
50 void AltDataOutputStreamChild::AddIPDLReference() {
51 MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
52 mIPCOpen = true;
53 AddRef();
56 void AltDataOutputStreamChild::ReleaseIPDLReference() {
57 MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
58 mIPCOpen = false;
60 if (mCallback) {
61 NotifyListener();
64 Release();
67 bool AltDataOutputStreamChild::WriteDataInChunks(
68 const nsDependentCSubstring& data) {
69 const size_t kChunkSize = 128 * 1024;
70 size_t next = std::min(data.Length(), kChunkSize);
71 for (size_t i = 0; i < data.Length();
72 i = next, next = std::min(data.Length(), next + kChunkSize)) {
73 nsCString chunk(Substring(data, i, kChunkSize));
74 if (mIPCOpen && !SendWriteData(chunk)) {
75 mIPCOpen = false;
76 return false;
79 return true;
82 NS_IMETHODIMP
83 AltDataOutputStreamChild::Close() { return CloseWithStatus(NS_OK); }
85 NS_IMETHODIMP
86 AltDataOutputStreamChild::Flush() {
87 if (!mIPCOpen) {
88 return NS_ERROR_NOT_AVAILABLE;
90 if (NS_FAILED(mError)) {
91 return mError;
94 // This is a no-op
95 return NS_OK;
98 NS_IMETHODIMP
99 AltDataOutputStreamChild::StreamStatus() {
100 if (!mIPCOpen) {
101 return NS_ERROR_NOT_AVAILABLE;
103 return mError;
106 NS_IMETHODIMP
107 AltDataOutputStreamChild::Write(const char* aBuf, uint32_t aCount,
108 uint32_t* _retval) {
109 if (!mIPCOpen) {
110 return NS_ERROR_NOT_AVAILABLE;
112 if (NS_FAILED(mError)) {
113 return mError;
115 if (WriteDataInChunks(nsDependentCSubstring(aBuf, aCount))) {
116 *_retval = aCount;
117 return NS_OK;
119 return NS_ERROR_FAILURE;
122 NS_IMETHODIMP
123 AltDataOutputStreamChild::WriteFrom(nsIInputStream* aFromStream,
124 uint32_t aCount, uint32_t* _retval) {
125 return NS_ERROR_NOT_IMPLEMENTED;
128 NS_IMETHODIMP
129 AltDataOutputStreamChild::WriteSegments(nsReadSegmentFun aReader,
130 void* aClosure, uint32_t aCount,
131 uint32_t* _retval) {
132 return NS_ERROR_NOT_IMPLEMENTED;
135 NS_IMETHODIMP
136 AltDataOutputStreamChild::IsNonBlocking(bool* _retval) {
137 *_retval = false;
138 return NS_OK;
141 mozilla::ipc::IPCResult AltDataOutputStreamChild::RecvError(
142 const nsresult& err) {
143 mError = err;
144 return IPC_OK();
147 mozilla::ipc::IPCResult AltDataOutputStreamChild::RecvDeleteSelf() {
148 PAltDataOutputStreamChild::Send__delete__(this);
149 return IPC_OK();
152 // nsIAsyncOutputStream
154 NS_IMETHODIMP
155 AltDataOutputStreamChild::CloseWithStatus(nsresult aStatus) {
156 if (!mIPCOpen) {
157 return NS_ERROR_NOT_AVAILABLE;
159 if (NS_FAILED(mError)) {
160 return mError;
162 Unused << SendClose(aStatus);
164 return NS_OK;
167 NS_IMETHODIMP
168 AltDataOutputStreamChild::AsyncWait(nsIOutputStreamCallback* aCallback,
169 uint32_t aFlags, uint32_t aRequestedCount,
170 nsIEventTarget* aEventTarget) {
171 mCallback = aCallback;
172 mCallbackFlags = aFlags;
173 mCallbackTarget = aEventTarget;
175 if (!mCallback) {
176 return NS_OK;
179 // The stream is blocking so it is writable at any time
180 if (!mIPCOpen || !(aFlags & WAIT_CLOSURE_ONLY)) {
181 NotifyListener();
184 return NS_OK;
187 void AltDataOutputStreamChild::NotifyListener() {
188 MOZ_ASSERT(mCallback);
190 if (!mCallbackTarget) {
191 mCallbackTarget = GetMainThreadSerialEventTarget();
194 nsCOMPtr<nsIOutputStreamCallback> asyncCallback =
195 NS_NewOutputStreamReadyEvent(mCallback, mCallbackTarget);
197 mCallback = nullptr;
198 mCallbackTarget = nullptr;
200 asyncCallback->OnOutputStreamReady(this);
203 } // namespace net
204 } // namespace mozilla