Line data Source code
1 : #include "mozilla/net/AltDataOutputStreamChild.h"
2 : #include "mozilla/Unused.h"
3 : #include "nsIInputStream.h"
4 :
5 : namespace mozilla {
6 : namespace net {
7 :
8 0 : NS_IMPL_ADDREF(AltDataOutputStreamChild)
9 :
10 0 : NS_IMETHODIMP_(MozExternalRefCountType) AltDataOutputStreamChild::Release()
11 : {
12 0 : NS_PRECONDITION(0 != mRefCnt, "dup release");
13 0 : MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
14 0 : --mRefCnt;
15 0 : NS_LOG_RELEASE(this, mRefCnt, "AltDataOutputStreamChild");
16 :
17 0 : if (mRefCnt == 1 && mIPCOpen) {
18 : // The only reference left is the IPDL one. After the parent replies back
19 : // with a DeleteSelf message, the child will call Send__delete__(this),
20 : // decrementing the ref count and triggering the destructor.
21 0 : SendDeleteSelf();
22 0 : return 1;
23 : }
24 :
25 0 : if (mRefCnt == 0) {
26 0 : mRefCnt = 1; /* stabilize */
27 0 : delete this;
28 0 : return 0;
29 : }
30 0 : return mRefCnt;
31 : }
32 :
33 0 : NS_INTERFACE_MAP_BEGIN(AltDataOutputStreamChild)
34 0 : NS_INTERFACE_MAP_ENTRY(nsIOutputStream)
35 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
36 0 : NS_INTERFACE_MAP_END
37 :
38 0 : AltDataOutputStreamChild::AltDataOutputStreamChild()
39 : : mIPCOpen(false)
40 0 : , mError(NS_OK)
41 : {
42 0 : MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
43 0 : }
44 :
45 0 : AltDataOutputStreamChild::~AltDataOutputStreamChild()
46 : {
47 0 : }
48 :
49 : void
50 0 : AltDataOutputStreamChild::AddIPDLReference()
51 : {
52 0 : MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
53 0 : mIPCOpen = true;
54 0 : AddRef();
55 0 : }
56 :
57 : void
58 0 : AltDataOutputStreamChild::ReleaseIPDLReference()
59 : {
60 0 : MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
61 0 : mIPCOpen = false;
62 0 : Release();
63 0 : }
64 :
65 : bool
66 0 : AltDataOutputStreamChild::WriteDataInChunks(const nsCString& data)
67 : {
68 0 : const uint32_t kChunkSize = 128*1024;
69 0 : uint32_t next = std::min(data.Length(), kChunkSize);
70 0 : for (uint32_t i = 0; i < data.Length();
71 0 : i = next, next = std::min(data.Length(), next + kChunkSize)) {
72 0 : nsCString chunk(Substring(data, i, kChunkSize));
73 0 : if (mIPCOpen && !SendWriteData(chunk)) {
74 0 : mIPCOpen = false;
75 0 : return false;
76 : }
77 : }
78 0 : return true;
79 : }
80 :
81 : NS_IMETHODIMP
82 0 : AltDataOutputStreamChild::Close()
83 : {
84 0 : if (!mIPCOpen) {
85 0 : return NS_ERROR_NOT_AVAILABLE;
86 : }
87 0 : if (NS_FAILED(mError)) {
88 0 : return mError;
89 : }
90 0 : Unused << SendClose();
91 0 : return NS_OK;
92 : }
93 :
94 : NS_IMETHODIMP
95 0 : AltDataOutputStreamChild::Flush()
96 : {
97 0 : if (!mIPCOpen) {
98 0 : return NS_ERROR_NOT_AVAILABLE;
99 : }
100 0 : if (NS_FAILED(mError)) {
101 0 : return mError;
102 : }
103 :
104 : // This is a no-op
105 0 : return NS_OK;
106 : }
107 :
108 : NS_IMETHODIMP
109 0 : AltDataOutputStreamChild::Write(const char * aBuf, uint32_t aCount, uint32_t *_retval)
110 : {
111 0 : if (!mIPCOpen) {
112 0 : return NS_ERROR_NOT_AVAILABLE;
113 : }
114 0 : if (NS_FAILED(mError)) {
115 0 : return mError;
116 : }
117 0 : if (WriteDataInChunks(nsCString(aBuf, aCount))) {
118 0 : *_retval = aCount;
119 0 : return NS_OK;
120 : }
121 0 : return NS_ERROR_FAILURE;
122 : }
123 :
124 : NS_IMETHODIMP
125 0 : AltDataOutputStreamChild::WriteFrom(nsIInputStream *aFromStream, uint32_t aCount, uint32_t *_retval)
126 : {
127 0 : return NS_ERROR_NOT_IMPLEMENTED;
128 : }
129 :
130 : NS_IMETHODIMP
131 0 : AltDataOutputStreamChild::WriteSegments(nsReadSegmentFun aReader, void *aClosure, uint32_t aCount, uint32_t *_retval)
132 : {
133 0 : return NS_ERROR_NOT_IMPLEMENTED;
134 : }
135 :
136 : NS_IMETHODIMP
137 0 : AltDataOutputStreamChild::IsNonBlocking(bool *_retval)
138 : {
139 0 : *_retval = false;
140 0 : return NS_OK;
141 : }
142 :
143 : mozilla::ipc::IPCResult
144 0 : AltDataOutputStreamChild::RecvError(const nsresult& err)
145 : {
146 0 : mError = err;
147 0 : return IPC_OK();
148 : }
149 :
150 : mozilla::ipc::IPCResult
151 0 : AltDataOutputStreamChild::RecvDeleteSelf()
152 : {
153 0 : PAltDataOutputStreamChild::Send__delete__(this);
154 0 : return IPC_OK();
155 : }
156 :
157 : } // namespace net
158 : } // namespace mozilla
|