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"
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");
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.
32 mRefCnt
= 1; /* stabilize */
39 NS_INTERFACE_MAP_BEGIN(AltDataOutputStreamChild
)
40 NS_INTERFACE_MAP_ENTRY(nsIAsyncOutputStream
)
41 NS_INTERFACE_MAP_ENTRY(nsIOutputStream
)
42 NS_INTERFACE_MAP_ENTRY(nsISupports
)
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");
56 void AltDataOutputStreamChild::ReleaseIPDLReference() {
57 MOZ_ASSERT(mIPCOpen
, "Attempt to release nonexistent IPDL reference");
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
)) {
83 AltDataOutputStreamChild::Close() { return CloseWithStatus(NS_OK
); }
86 AltDataOutputStreamChild::Flush() {
88 return NS_ERROR_NOT_AVAILABLE
;
90 if (NS_FAILED(mError
)) {
99 AltDataOutputStreamChild::StreamStatus() {
101 return NS_ERROR_NOT_AVAILABLE
;
107 AltDataOutputStreamChild::Write(const char* aBuf
, uint32_t aCount
,
110 return NS_ERROR_NOT_AVAILABLE
;
112 if (NS_FAILED(mError
)) {
115 if (WriteDataInChunks(nsDependentCSubstring(aBuf
, aCount
))) {
119 return NS_ERROR_FAILURE
;
123 AltDataOutputStreamChild::WriteFrom(nsIInputStream
* aFromStream
,
124 uint32_t aCount
, uint32_t* _retval
) {
125 return NS_ERROR_NOT_IMPLEMENTED
;
129 AltDataOutputStreamChild::WriteSegments(nsReadSegmentFun aReader
,
130 void* aClosure
, uint32_t aCount
,
132 return NS_ERROR_NOT_IMPLEMENTED
;
136 AltDataOutputStreamChild::IsNonBlocking(bool* _retval
) {
141 mozilla::ipc::IPCResult
AltDataOutputStreamChild::RecvError(
142 const nsresult
& err
) {
147 mozilla::ipc::IPCResult
AltDataOutputStreamChild::RecvDeleteSelf() {
148 PAltDataOutputStreamChild::Send__delete__(this);
152 // nsIAsyncOutputStream
155 AltDataOutputStreamChild::CloseWithStatus(nsresult aStatus
) {
157 return NS_ERROR_NOT_AVAILABLE
;
159 if (NS_FAILED(mError
)) {
162 Unused
<< SendClose(aStatus
);
168 AltDataOutputStreamChild::AsyncWait(nsIOutputStreamCallback
* aCallback
,
169 uint32_t aFlags
, uint32_t aRequestedCount
,
170 nsIEventTarget
* aEventTarget
) {
171 mCallback
= aCallback
;
172 mCallbackFlags
= aFlags
;
173 mCallbackTarget
= aEventTarget
;
179 // The stream is blocking so it is writable at any time
180 if (!mIPCOpen
|| !(aFlags
& WAIT_CLOSURE_ONLY
)) {
187 void AltDataOutputStreamChild::NotifyListener() {
188 MOZ_ASSERT(mCallback
);
190 if (!mCallbackTarget
) {
191 mCallbackTarget
= GetMainThreadSerialEventTarget();
194 nsCOMPtr
<nsIOutputStreamCallback
> asyncCallback
=
195 NS_NewOutputStreamReadyEvent(mCallback
, mCallbackTarget
);
198 mCallbackTarget
= nullptr;
200 asyncCallback
->OnOutputStreamReady(this);
204 } // namespace mozilla