summaryrefslogtreecommitdiff
path: root/xpcom/io/nsIPipe.idl
blob: 3442f1734c01f2ca72d292a4868c3e988bf06335 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"

interface nsIAsyncInputStream;
interface nsIAsyncOutputStream;

/**
 * nsIPipe represents an in-process buffer that can be read using nsIInputStream
 * and written using nsIOutputStream.  The reader and writer of a pipe do not
 * have to be on the same thread.  As a result, the pipe is an ideal mechanism
 * to bridge data exchange between two threads.  For example, a worker thread
 * might write data to a pipe from which the main thread will read.
 *
 * Each end of the pipe can be either blocking or non-blocking.  Recall that a
 * non-blocking stream will return NS_BASE_STREAM_WOULD_BLOCK if it cannot be
 * read or written to without blocking the calling thread.  For example, if you
 * try to read from an empty pipe that has not yet been closed, then if that
 * pipe's input end is non-blocking, then the read call will fail immediately
 * with NS_BASE_STREAM_WOULD_BLOCK as the error condition.  However, if that
 * pipe's input end is blocking, then the read call will not return until the
 * pipe has data or until the pipe is closed.  This example presumes that the
 * pipe is being filled asynchronously on some background thread.
 *
 * The pipe supports nsIAsyncInputStream and nsIAsyncOutputStream, which give
 * the user of a non-blocking pipe the ability to wait for the pipe to become
 * ready again.  For example, in the case of an empty non-blocking pipe, the
 * user can call AsyncWait on the input end of the pipe to be notified when 
 * the pipe has data to read (or when the pipe becomes closed).
 *
 * NS_NewPipe2 and NS_NewPipe provide convenient pipe constructors.  In most
 * cases nsIPipe is not actually used.  It is usually enough to just get
 * references to the pipe's input and output end.  In which case, the pipe is
 * automatically closed when the respective pipe ends are released.
 */
[scriptable, uuid(25d0de93-685e-4ea4-95d3-d884e31df63c)]
interface nsIPipe : nsISupports
{
    /**
     * initialize this pipe
     *
     * @param nonBlockingInput
     *        true specifies non-blocking input stream behavior
     * @param nonBlockingOutput
     *        true specifies non-blocking output stream behavior
     * @param segmentSize
     *        specifies the segment size in bytes (pass 0 to use default value)
     * @param segmentCount
     *        specifies the max number of segments (pass 0 to use default
     *        value).   Passing UINT32_MAX here causes the pipe to have
     *        "infinite" space.  This mode can be useful in some cases, but
     *        should always be used with caution.  The default value for this
     *        parameter is a finite value.
     */
    [must_use] void init(in boolean nonBlockingInput,
                         in boolean nonBlockingOutput,
                         in unsigned long segmentSize,
                         in unsigned long segmentCount);

    /**
     * The pipe's input end, which also implements nsISearchableInputStream.
     * Getting fails if the pipe hasn't been initialized.
     */
    [must_use] readonly attribute nsIAsyncInputStream inputStream;

    /**
     * The pipe's output end. Getting fails if the pipe hasn't been
     * initialized.
     */
    [must_use] readonly attribute nsIAsyncOutputStream outputStream;
};

/**
 * XXX this interface doesn't really belong in here.  It is here because
 * currently nsPipeInputStream is the only implementation of this interface.
 */
[scriptable, uuid(8C39EF62-F7C9-11d4-98F5-001083010E9B)] 
interface nsISearchableInputStream : nsISupports
{
    /**
     * Searches for a string in the input stream. Since the stream has a notion
     * of EOF, it is possible that the string may at some time be in the 
     * buffer, but is is not currently found up to some offset. Consequently,
     * both the found and not found cases return an offset:
     *    if found, return offset where it was found
     *    if not found, return offset of the first byte not searched
     * In the case the stream is at EOF and the string is not found, the first
     * byte not searched will correspond to the length of the buffer.
     */
    void search(in string forString, 
                in boolean ignoreCase, 
                out boolean found,
                out unsigned long offsetSearchedTo);
};

%{C++

class nsIInputStream;
class nsIOutputStream;

/**
 * NS_NewPipe2
 *
 * This function supersedes NS_NewPipe.  It differs from NS_NewPipe in two
 * major ways:
 *  (1) returns nsIAsyncInputStream and nsIAsyncOutputStream, so it is
 *      not necessary to QI in order to access these interfaces.
 *  (2) the size of the pipe is determined by the number of segments
 *      times the size of each segment.
 *
 * @param pipeIn
 *        resulting input end of the pipe
 * @param pipeOut
 *        resulting output end of the pipe
 * @param nonBlockingInput
 *        true specifies non-blocking input stream behavior
 * @param nonBlockingOutput
 *        true specifies non-blocking output stream behavior
 * @param segmentSize
 *        specifies the segment size in bytes (pass 0 to use default value)
 * @param segmentCount
 *        specifies the max number of segments (pass 0 to use default value)
 *        passing UINT32_MAX here causes the pipe to have "infinite" space.
 *        this mode can be useful in some cases, but should always be used with
 *        caution.  the default value for this parameter is a finite value.
 */
extern [[nodiscard]] nsresult
NS_NewPipe2(nsIAsyncInputStream **pipeIn,
            nsIAsyncOutputStream **pipeOut,
            bool nonBlockingInput = false,
            bool nonBlockingOutput = false,
            uint32_t segmentSize = 0,
            uint32_t segmentCount = 0);

/**
 * NS_NewPipe
 *
 * Preserved for backwards compatibility.  Plus, this interface is more
 * amiable in certain contexts (e.g., when you don't need the pipe's async
 * capabilities).
 *
 * @param pipeIn
 *        resulting input end of the pipe
 * @param pipeOut
 *        resulting output end of the pipe
 * @param segmentSize
 *        specifies the segment size in bytes (pass 0 to use default value)
 * @param maxSize
 *        specifies the max size of the pipe (pass 0 to use default value)
 *        number of segments is maxSize / segmentSize, and maxSize must be a
 *        multiple of segmentSize.  passing UINT32_MAX here causes the
 *        pipe to have "infinite" space.  this mode can be useful in some
 *        cases, but should always be used with caution.  the default value
 *        for this parameter is a finite value.
 * @param nonBlockingInput
 *        true specifies non-blocking input stream behavior
 * @param nonBlockingOutput
 *        true specifies non-blocking output stream behavior
 */
extern [[nodiscard]] nsresult
NS_NewPipe(nsIInputStream **pipeIn,
           nsIOutputStream **pipeOut,
           uint32_t segmentSize = 0,
           uint32_t maxSize = 0,
           bool nonBlockingInput = false,
           bool nonBlockingOutput = false);

%}