Line data Source code
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/. */
6 :
7 : #ifndef nsStreamUtils_h__
8 : #define nsStreamUtils_h__
9 :
10 : #include "nsCOMPtr.h"
11 : #include "nsStringFwd.h"
12 : #include "nsIInputStream.h"
13 : #include "nsTArray.h"
14 :
15 : class nsIOutputStream;
16 : class nsIInputStreamCallback;
17 : class nsIOutputStreamCallback;
18 : class nsIEventTarget;
19 :
20 : /**
21 : * A "one-shot" proxy of the OnInputStreamReady callback. The resulting
22 : * proxy object's OnInputStreamReady function may only be called once! The
23 : * proxy object ensures that the real notify object will be free'd on the
24 : * thread corresponding to the given event target regardless of what thread
25 : * the proxy object is destroyed on.
26 : *
27 : * This function is designed to be used to implement AsyncWait when the
28 : * aTarget parameter is non-null.
29 : */
30 : extern already_AddRefed<nsIInputStreamCallback>
31 : NS_NewInputStreamReadyEvent(const char* aName,
32 : nsIInputStreamCallback* aNotify,
33 : nsIEventTarget* aTarget);
34 :
35 : /**
36 : * A "one-shot" proxy of the OnOutputStreamReady callback. The resulting
37 : * proxy object's OnOutputStreamReady function may only be called once! The
38 : * proxy object ensures that the real notify object will be free'd on the
39 : * thread corresponding to the given event target regardless of what thread
40 : * the proxy object is destroyed on.
41 : *
42 : * This function is designed to be used to implement AsyncWait when the
43 : * aTarget parameter is non-null.
44 : */
45 : extern already_AddRefed<nsIOutputStreamCallback>
46 : NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback* aNotify,
47 : nsIEventTarget* aTarget);
48 :
49 : /* ------------------------------------------------------------------------- */
50 :
51 : enum nsAsyncCopyMode {
52 : NS_ASYNCCOPY_VIA_READSEGMENTS,
53 : NS_ASYNCCOPY_VIA_WRITESEGMENTS
54 : };
55 :
56 : /**
57 : * This function is called when a new chunk of data has been copied. The
58 : * reported count is the size of the current chunk.
59 : */
60 : typedef void (* nsAsyncCopyProgressFun)(void* closure, uint32_t count);
61 :
62 : /**
63 : * This function is called when the async copy process completes. The reported
64 : * status is NS_OK on success and some error code on failure.
65 : */
66 : typedef void (* nsAsyncCopyCallbackFun)(void* closure, nsresult status);
67 :
68 : /**
69 : * This function asynchronously copies data from the source to the sink. All
70 : * data transfer occurs on the thread corresponding to the given event target.
71 : * A null event target is not permitted.
72 : *
73 : * The copier handles blocking or non-blocking streams transparently. If a
74 : * stream operation returns NS_BASE_STREAM_WOULD_BLOCK, then the stream will
75 : * be QI'd to nsIAsync{In,Out}putStream and its AsyncWait method will be used
76 : * to determine when to resume copying.
77 : *
78 : * Source and sink are closed by default when copying finishes or when error
79 : * occurs. Caller can prevent closing source or sink by setting aCloseSource
80 : * or aCloseSink to false.
81 : *
82 : * Caller can obtain aCopierCtx to be able to cancel copying.
83 : */
84 : extern nsresult
85 : NS_AsyncCopy(nsIInputStream* aSource,
86 : nsIOutputStream* aSink,
87 : nsIEventTarget* aTarget,
88 : nsAsyncCopyMode aMode = NS_ASYNCCOPY_VIA_READSEGMENTS,
89 : uint32_t aChunkSize = 4096,
90 : nsAsyncCopyCallbackFun aCallbackFun = nullptr,
91 : void* aCallbackClosure = nullptr,
92 : bool aCloseSource = true,
93 : bool aCloseSink = true,
94 : nsISupports** aCopierCtx = nullptr,
95 : nsAsyncCopyProgressFun aProgressCallbackFun = nullptr);
96 :
97 : /**
98 : * This function cancels copying started by function NS_AsyncCopy.
99 : *
100 : * @param aCopierCtx
101 : * Copier context returned by NS_AsyncCopy.
102 : * @param aReason
103 : * A failure code indicating why the operation is being canceled.
104 : * It is an error to pass a success code.
105 : */
106 : extern nsresult
107 : NS_CancelAsyncCopy(nsISupports* aCopierCtx, nsresult aReason);
108 :
109 : /**
110 : * This function copies all of the available data from the stream (up to at
111 : * most aMaxCount bytes) into the given buffer. The buffer is truncated at
112 : * the start of the function.
113 : *
114 : * If an error occurs while reading from the stream or while attempting to
115 : * resize the buffer, then the corresponding error code is returned from this
116 : * function, and any data that has already been read will be returned in the
117 : * output buffer. This allows one to use this function with a non-blocking
118 : * input stream that may return NS_BASE_STREAM_WOULD_BLOCK if it only has
119 : * partial data available.
120 : *
121 : * @param aSource
122 : * The input stream to read.
123 : * @param aMaxCount
124 : * The maximum number of bytes to consume from the stream. Pass the
125 : * value UINT32_MAX to consume the entire stream. The number of
126 : * bytes actually read is given by the length of aBuffer upon return.
127 : * @param aBuffer
128 : * The string object that will contain the stream data upon return.
129 : * Note: The data copied to the string may contain null bytes and may
130 : * contain non-ASCII values.
131 : */
132 : extern nsresult
133 : NS_ConsumeStream(nsIInputStream* aSource, uint32_t aMaxCount,
134 : nsACString& aBuffer);
135 :
136 : /**
137 : * This function tests whether or not the input stream is buffered. A buffered
138 : * input stream is one that implements readSegments. The test for this is to
139 : * 1/ check whether the input stream implements nsIBufferedInputStream;
140 : * 2/ if not, call readSegments, without actually consuming any data from the
141 : * stream, to verify that it functions.
142 : *
143 : * NOTE: If the stream is non-blocking and has no data available yet, then this
144 : * test will fail. In that case, we return false even though the test is not
145 : * really conclusive.
146 : *
147 : * PERFORMANCE NOTE: If the stream does not implement nsIBufferedInputStream,
148 : * calling readSegments may cause I/O. Therefore, you should avoid calling
149 : * this function from the main thread.
150 : *
151 : * @param aInputStream
152 : * The input stream to test.
153 : */
154 : extern bool
155 : NS_InputStreamIsBuffered(nsIInputStream* aInputStream);
156 :
157 : /**
158 : * This function tests whether or not the output stream is buffered. A
159 : * buffered output stream is one that implements writeSegments. The test for
160 : * this is to:
161 : * 1/ check whether the output stream implements nsIBufferedOutputStream;
162 : * 2/ if not, call writeSegments, without actually writing any data into
163 : * the stream, to verify that it functions.
164 : *
165 : * NOTE: If the stream is non-blocking and has no available space yet, then
166 : * this test will fail. In that case, we return false even though the test is
167 : * not really conclusive.
168 : *
169 : * PERFORMANCE NOTE: If the stream does not implement nsIBufferedOutputStream,
170 : * calling writeSegments may cause I/O. Therefore, you should avoid calling
171 : * this function from the main thread.
172 : *
173 : * @param aOutputStream
174 : * The output stream to test.
175 : */
176 : extern bool
177 : NS_OutputStreamIsBuffered(nsIOutputStream* aOutputStream);
178 :
179 : /**
180 : * This function is intended to be passed to nsIInputStream::ReadSegments to
181 : * copy data from the nsIInputStream into a nsIOutputStream passed as the
182 : * aClosure parameter to the ReadSegments function.
183 : *
184 : * @see nsIInputStream.idl for a description of this function's parameters.
185 : */
186 : extern nsresult
187 : NS_CopySegmentToStream(nsIInputStream* aInputStream, void* aClosure,
188 : const char* aFromSegment, uint32_t aToOffset,
189 : uint32_t aCount, uint32_t* aWriteCount);
190 :
191 : /**
192 : * This function is intended to be passed to nsIInputStream::ReadSegments to
193 : * copy data from the nsIInputStream into a character buffer passed as the
194 : * aClosure parameter to the ReadSegments function. The character buffer
195 : * must be at least as large as the aCount parameter passed to ReadSegments.
196 : *
197 : * @see nsIInputStream.idl for a description of this function's parameters.
198 : */
199 : extern nsresult
200 : NS_CopySegmentToBuffer(nsIInputStream* aInputStream, void* aClosure,
201 : const char* aFromSegment, uint32_t aToOffset,
202 : uint32_t aCount, uint32_t* aWriteCount);
203 :
204 : /**
205 : * This function is intended to be passed to nsIOutputStream::WriteSegments to
206 : * copy data into the nsIOutputStream from a character buffer passed as the
207 : * aClosure parameter to the WriteSegments function.
208 : *
209 : * @see nsIOutputStream.idl for a description of this function's parameters.
210 : */
211 : extern nsresult
212 : NS_CopySegmentToBuffer(nsIOutputStream* aOutputStream, void* aClosure,
213 : char* aToSegment, uint32_t aFromOffset,
214 : uint32_t aCount, uint32_t* aReadCount);
215 :
216 : /**
217 : * This function is intended to be passed to nsIInputStream::ReadSegments to
218 : * discard data from the nsIInputStream. This can be used to efficiently read
219 : * data from the stream without actually copying any bytes.
220 : *
221 : * @see nsIInputStream.idl for a description of this function's parameters.
222 : */
223 : extern nsresult
224 : NS_DiscardSegment(nsIInputStream* aInputStream, void* aClosure,
225 : const char* aFromSegment, uint32_t aToOffset,
226 : uint32_t aCount, uint32_t* aWriteCount);
227 :
228 : /**
229 : * This function is intended to be passed to nsIInputStream::ReadSegments to
230 : * adjust the aInputStream parameter passed to a consumer's WriteSegmentFun.
231 : * The aClosure parameter must be a pointer to a nsWriteSegmentThunk object.
232 : * The mStream and mClosure members of that object will be passed to the mFun
233 : * function, with the remainder of the parameters being what are passed to
234 : * NS_WriteSegmentThunk.
235 : *
236 : * This function comes in handy when implementing ReadSegments in terms of an
237 : * inner stream's ReadSegments.
238 : */
239 : extern nsresult
240 : NS_WriteSegmentThunk(nsIInputStream* aInputStream, void* aClosure,
241 : const char* aFromSegment, uint32_t aToOffset,
242 : uint32_t aCount, uint32_t* aWriteCount);
243 :
244 0 : struct MOZ_STACK_CLASS nsWriteSegmentThunk
245 : {
246 : nsCOMPtr<nsIInputStream> mStream;
247 : nsWriteSegmentFun mFun;
248 : void* mClosure;
249 : };
250 :
251 : /**
252 : * Read data from aInput and store in aDest. A non-zero aKeep will keep that
253 : * many bytes from aDest (from the end). New data is appended after the kept
254 : * bytes (if any). aDest's new length on returning from this function is
255 : * aKeep + aNewBytes and is guaranteed to be less than or equal to aDest's
256 : * current capacity.
257 : * @param aDest the array to fill
258 : * @param aInput the stream to read from
259 : * @param aKeep number of bytes to keep (0 <= aKeep <= aDest.Length())
260 : * @param aNewBytes (out) number of bytes read from aInput or zero if Read()
261 : * failed
262 : * @return the result from aInput->Read(...)
263 : */
264 : extern nsresult
265 : NS_FillArray(FallibleTArray<char>& aDest, nsIInputStream* aInput,
266 : uint32_t aKeep, uint32_t* aNewBytes);
267 :
268 : /**
269 : * Return true if the given stream can be directly cloned.
270 : */
271 : extern bool
272 : NS_InputStreamIsCloneable(nsIInputStream* aSource);
273 :
274 : /**
275 : * Clone the provided source stream in the most efficient way possible. This
276 : * first attempts to QI to nsICloneableInputStream to use Clone(). If that is
277 : * not supported or its cloneable attribute is false, then a fallback clone is
278 : * provided by copying the source to a pipe. In this case the caller must
279 : * replace the source stream with the resulting replacement stream. The clone
280 : * and the replacement stream are then cloneable using nsICloneableInputStream
281 : * without duplicating memory. This fallback clone using the pipe is only
282 : * performed if a replacement stream parameter is also passed in.
283 : * @param aSource The input stream to clone.
284 : * @param aCloneOut Required out parameter to hold resulting clone.
285 : * @param aReplacementOut Optional out parameter to hold stream to replace
286 : * original source stream after clone. If not
287 : * provided then the fallback clone process is not
288 : * supported and a non-cloneable source will result
289 : * in failure. Replacement streams are non-blocking.
290 : * @return NS_OK on successful clone. Error otherwise.
291 : */
292 : extern nsresult
293 : NS_CloneInputStream(nsIInputStream* aSource, nsIInputStream** aCloneOut,
294 : nsIInputStream** aReplacementOut = nullptr);
295 :
296 : #endif // !nsStreamUtils_h__
|