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