michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsStreamUtils_h__ michael@0: #define nsStreamUtils_h__ michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsStringFwd.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class nsIOutputStream; michael@0: class nsIInputStreamCallback; michael@0: class nsIOutputStreamCallback; michael@0: class nsIEventTarget; michael@0: michael@0: /** michael@0: * A "one-shot" proxy of the OnInputStreamReady callback. The resulting michael@0: * proxy object's OnInputStreamReady function may only be called once! The michael@0: * proxy object ensures that the real notify object will be free'd on the michael@0: * thread corresponding to the given event target regardless of what thread michael@0: * the proxy object is destroyed on. michael@0: * michael@0: * This function is designed to be used to implement AsyncWait when the michael@0: * aTarget parameter is non-null. michael@0: */ michael@0: extern already_AddRefed michael@0: NS_NewInputStreamReadyEvent(nsIInputStreamCallback *aNotify, michael@0: nsIEventTarget *aTarget); michael@0: michael@0: /** michael@0: * A "one-shot" proxy of the OnOutputStreamReady callback. The resulting michael@0: * proxy object's OnOutputStreamReady function may only be called once! The michael@0: * proxy object ensures that the real notify object will be free'd on the michael@0: * thread corresponding to the given event target regardless of what thread michael@0: * the proxy object is destroyed on. michael@0: * michael@0: * This function is designed to be used to implement AsyncWait when the michael@0: * aTarget parameter is non-null. michael@0: */ michael@0: extern already_AddRefed michael@0: NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback *aNotify, michael@0: nsIEventTarget *aTarget); michael@0: michael@0: /* ------------------------------------------------------------------------- */ michael@0: michael@0: enum nsAsyncCopyMode { michael@0: NS_ASYNCCOPY_VIA_READSEGMENTS, michael@0: NS_ASYNCCOPY_VIA_WRITESEGMENTS michael@0: }; michael@0: michael@0: /** michael@0: * This function is called when a new chunk of data has been copied. The michael@0: * reported count is the size of the current chunk. michael@0: */ michael@0: typedef void (* nsAsyncCopyProgressFun)(void *closure, uint32_t count); michael@0: michael@0: /** michael@0: * This function is called when the async copy process completes. The reported michael@0: * status is NS_OK on success and some error code on failure. michael@0: */ michael@0: typedef void (* nsAsyncCopyCallbackFun)(void *closure, nsresult status); michael@0: michael@0: /** michael@0: * This function asynchronously copies data from the source to the sink. All michael@0: * data transfer occurs on the thread corresponding to the given event target. michael@0: * A null event target is not permitted. michael@0: * michael@0: * The copier handles blocking or non-blocking streams transparently. If a michael@0: * stream operation returns NS_BASE_STREAM_WOULD_BLOCK, then the stream will michael@0: * be QI'd to nsIAsync{In,Out}putStream and its AsyncWait method will be used michael@0: * to determine when to resume copying. michael@0: * michael@0: * Source and sink are closed by default when copying finishes or when error michael@0: * occurs. Caller can prevent closing source or sink by setting aCloseSource michael@0: * or aCloseSink to false. michael@0: * michael@0: * Caller can obtain aCopierCtx to be able to cancel copying. michael@0: */ michael@0: extern nsresult michael@0: NS_AsyncCopy(nsIInputStream *aSource, michael@0: nsIOutputStream *aSink, michael@0: nsIEventTarget *aTarget, michael@0: nsAsyncCopyMode aMode = NS_ASYNCCOPY_VIA_READSEGMENTS, michael@0: uint32_t aChunkSize = 4096, michael@0: nsAsyncCopyCallbackFun aCallbackFun = nullptr, michael@0: void *aCallbackClosure = nullptr, michael@0: bool aCloseSource = true, michael@0: bool aCloseSink = true, michael@0: nsISupports **aCopierCtx = nullptr, michael@0: nsAsyncCopyProgressFun aProgressCallbackFun = nullptr); michael@0: michael@0: /** michael@0: * This function cancels copying started by function NS_AsyncCopy. michael@0: * michael@0: * @param aCopierCtx michael@0: * Copier context returned by NS_AsyncCopy. michael@0: * @param aReason michael@0: * A failure code indicating why the operation is being canceled. michael@0: * It is an error to pass a success code. michael@0: */ michael@0: extern nsresult michael@0: NS_CancelAsyncCopy(nsISupports *aCopierCtx, nsresult aReason); michael@0: michael@0: /** michael@0: * This function copies all of the available data from the stream (up to at michael@0: * most aMaxCount bytes) into the given buffer. The buffer is truncated at michael@0: * the start of the function. michael@0: * michael@0: * If an error occurs while reading from the stream or while attempting to michael@0: * resize the buffer, then the corresponding error code is returned from this michael@0: * function, and any data that has already been read will be returned in the michael@0: * output buffer. This allows one to use this function with a non-blocking michael@0: * input stream that may return NS_BASE_STREAM_WOULD_BLOCK if it only has michael@0: * partial data available. michael@0: * michael@0: * @param aSource michael@0: * The input stream to read. michael@0: * @param aMaxCount michael@0: * The maximum number of bytes to consume from the stream. Pass the michael@0: * value UINT32_MAX to consume the entire stream. The number of michael@0: * bytes actually read is given by the length of aBuffer upon return. michael@0: * @param aBuffer michael@0: * The string object that will contain the stream data upon return. michael@0: * Note: The data copied to the string may contain null bytes and may michael@0: * contain non-ASCII values. michael@0: */ michael@0: extern nsresult michael@0: NS_ConsumeStream(nsIInputStream *aSource, uint32_t aMaxCount, michael@0: nsACString &aBuffer); michael@0: michael@0: /** michael@0: * This function tests whether or not the input stream is buffered. A buffered michael@0: * input stream is one that implements readSegments. The test for this is to michael@0: * 1/ check whether the input stream implements nsIBufferedInputStream; michael@0: * 2/ if not, call readSegments, without actually consuming any data from the michael@0: * stream, to verify that it functions. michael@0: * michael@0: * NOTE: If the stream is non-blocking and has no data available yet, then this michael@0: * test will fail. In that case, we return false even though the test is not michael@0: * really conclusive. michael@0: * michael@0: * PERFORMANCE NOTE: If the stream does not implement nsIBufferedInputStream, michael@0: * calling readSegments may cause I/O. Therefore, you should avoid calling michael@0: * this function from the main thread. michael@0: * michael@0: * @param aInputStream michael@0: * The input stream to test. michael@0: */ michael@0: extern bool michael@0: NS_InputStreamIsBuffered(nsIInputStream *aInputStream); michael@0: michael@0: /** michael@0: * This function tests whether or not the output stream is buffered. A michael@0: * buffered output stream is one that implements writeSegments. The test for michael@0: * this is to: michael@0: * 1/ check whether the output stream implements nsIBufferedOutputStream; michael@0: * 2/ if not, call writeSegments, without actually writing any data into michael@0: * the stream, to verify that it functions. michael@0: * michael@0: * NOTE: If the stream is non-blocking and has no available space yet, then michael@0: * this test will fail. In that case, we return false even though the test is michael@0: * not really conclusive. michael@0: * michael@0: * PERFORMANCE NOTE: If the stream does not implement nsIBufferedOutputStream, michael@0: * calling writeSegments may cause I/O. Therefore, you should avoid calling michael@0: * this function from the main thread. michael@0: * michael@0: * @param aOutputStream michael@0: * The output stream to test. michael@0: */ michael@0: extern bool michael@0: NS_OutputStreamIsBuffered(nsIOutputStream *aOutputStream); michael@0: michael@0: /** michael@0: * This function is intended to be passed to nsIInputStream::ReadSegments to michael@0: * copy data from the nsIInputStream into a nsIOutputStream passed as the michael@0: * aClosure parameter to the ReadSegments function. michael@0: * michael@0: * @see nsIInputStream.idl for a description of this function's parameters. michael@0: */ michael@0: extern NS_METHOD michael@0: NS_CopySegmentToStream(nsIInputStream *aInputStream, void *aClosure, michael@0: const char *aFromSegment, uint32_t aToOffset, michael@0: uint32_t aCount, uint32_t *aWriteCount); michael@0: michael@0: /** michael@0: * This function is intended to be passed to nsIInputStream::ReadSegments to michael@0: * copy data from the nsIInputStream into a character buffer passed as the michael@0: * aClosure parameter to the ReadSegments function. The character buffer michael@0: * must be at least as large as the aCount parameter passed to ReadSegments. michael@0: * michael@0: * @see nsIInputStream.idl for a description of this function's parameters. michael@0: */ michael@0: extern NS_METHOD michael@0: NS_CopySegmentToBuffer(nsIInputStream *aInputStream, void *aClosure, michael@0: const char *aFromSegment, uint32_t aToOffset, michael@0: uint32_t aCount, uint32_t *aWriteCount); michael@0: michael@0: /** michael@0: * This function is intended to be passed to nsIOutputStream::WriteSegments to michael@0: * copy data into the nsIOutputStream from a character buffer passed as the michael@0: * aClosure parameter to the WriteSegments function. michael@0: * michael@0: * @see nsIOutputStream.idl for a description of this function's parameters. michael@0: */ michael@0: extern NS_METHOD michael@0: NS_CopySegmentToBuffer(nsIOutputStream *aOutputStream, void *aClosure, michael@0: char *aToSegment, uint32_t aFromOffset, michael@0: uint32_t aCount, uint32_t *aReadCount); michael@0: michael@0: /** michael@0: * This function is intended to be passed to nsIInputStream::ReadSegments to michael@0: * discard data from the nsIInputStream. This can be used to efficiently read michael@0: * data from the stream without actually copying any bytes. michael@0: * michael@0: * @see nsIInputStream.idl for a description of this function's parameters. michael@0: */ michael@0: extern NS_METHOD michael@0: NS_DiscardSegment(nsIInputStream *aInputStream, void *aClosure, michael@0: const char *aFromSegment, uint32_t aToOffset, michael@0: uint32_t aCount, uint32_t *aWriteCount); michael@0: michael@0: /** michael@0: * This function is intended to be passed to nsIInputStream::ReadSegments to michael@0: * adjust the aInputStream parameter passed to a consumer's WriteSegmentFun. michael@0: * The aClosure parameter must be a pointer to a nsWriteSegmentThunk object. michael@0: * The mStream and mClosure members of that object will be passed to the mFun michael@0: * function, with the remainder of the parameters being what are passed to michael@0: * NS_WriteSegmentThunk. michael@0: * michael@0: * This function comes in handy when implementing ReadSegments in terms of an michael@0: * inner stream's ReadSegments. michael@0: */ michael@0: extern NS_METHOD michael@0: NS_WriteSegmentThunk(nsIInputStream *aInputStream, void *aClosure, michael@0: const char *aFromSegment, uint32_t aToOffset, michael@0: uint32_t aCount, uint32_t *aWriteCount); michael@0: michael@0: struct nsWriteSegmentThunk { michael@0: nsIInputStream *mStream; michael@0: nsWriteSegmentFun mFun; michael@0: void *mClosure; michael@0: }; michael@0: michael@0: /** michael@0: * Read data from aInput and store in aDest. A non-zero aKeep will keep that michael@0: * many bytes from aDest (from the end). New data is appended after the kept michael@0: * bytes (if any). aDest's new length on returning from this function is michael@0: * aKeep + aNewBytes and is guaranteed to be less than or equal to aDest's michael@0: * current capacity. michael@0: * @param aDest the array to fill michael@0: * @param aInput the stream to read from michael@0: * @param aKeep number of bytes to keep (0 <= aKeep <= aDest.Length()) michael@0: * @param aNewBytes (out) number of bytes read from aInput or zero if Read() michael@0: * failed michael@0: * @return the result from aInput->Read(...) michael@0: */ michael@0: extern NS_METHOD michael@0: NS_FillArray(FallibleTArray &aDest, nsIInputStream *aInput, michael@0: uint32_t aKeep, uint32_t *aNewBytes); michael@0: michael@0: #endif // !nsStreamUtils_h__