@@ -134,58 +134,115 @@ interface streams {
134
134
/// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources).
135
135
type output-stream = u32
136
136
137
- /// Perform a non-blocking write of bytes to a stream.
137
+ /// An error for output- stream operations .
138
138
///
139
- /// This function returns a `u64` and a `stream-status` . The `u64` indicates
140
- /// the number of bytes from `buf` that were written, which may be less than
141
- /// the length of `buf` . The `stream-status` indicates if further writes to
142
- /// the stream are expected to be read.
139
+ /// Contrary to input-streams, a closed output-stream is reported using
140
+ /// an error.
141
+ enum write-error {
142
+ /// The last operation (a write or flush) failed before completion.
143
+ last-operation-failed ,
144
+ /// The stream is closed: no more input will be accepted by the
145
+ /// stream. A closed output-stream will return this error on all
146
+ /// future operations.
147
+ closed
148
+ }
149
+ /// Check readiness for writing. This function never blocks.
150
+ ///
151
+ /// Returns the number of bytes permitted for the next call to `write` ,
152
+ /// or an error. Calling `write` with more bytes than this function has
153
+ /// permitted will trap.
154
+ ///
155
+ /// When this function returns 0 bytes, the `subscribe-to-output-stream`
156
+ /// pollable will become ready when this function will report at least
157
+ /// 1 byte, or an error.
158
+ check-write : func (
159
+ this : output-stream
160
+ ) -> result <u64 , write-error >
161
+
162
+ /// Perform a write. This function never blocks.
143
163
///
144
- /// When the returned `stream-status` is `open` , the `u64` return value may
145
- /// be less than the length of `buf` . This indicates that no more bytes may
146
- /// be written to the stream promptly. In that case the
147
- /// `subscribe-to-output-stream` pollable will indicate when additional bytes
148
- /// may be promptly written.
164
+ /// Precondition: check-write gave permit of Ok(n) and contents has a
165
+ /// length of less than or equal to n. Otherwise, this function will trap.
149
166
///
150
- /// Writing an empty list must return a non-error result with `0` for the
151
- /// `u64` return value, and the current `stream-status` .
167
+ /// returns Err(closed) without writing if the stream has closed since
168
+ /// the last call to check-write provided a permit .
152
169
write : func (
153
170
this : output-stream ,
154
- /// Data to write
155
- buf : list <u8 >
156
- ) -> result <tuple <u64 , stream-status >>
171
+ contents : list <u8 >
172
+ ) -> result <_ , write-error >
157
173
158
- /// Blocking write of bytes to a stream.
174
+ /// Perform a write of up to 4096 bytes, and then flush the stream. Block
175
+ /// until all of these operations are complete, or an error occurs.
159
176
///
160
- /// This is similar to `write` , except that it blocks until at least one
161
- /// byte can be written.
162
- blocking-write : func (
163
- this : output-stream ,
164
- /// Data to write
165
- buf : list <u8 >
166
- ) -> result <tuple <u64 , stream-status >>
177
+ /// This is a convenience wrapper around the use of `check-write` ,
178
+ /// `subscribe-to-output-stream` , `write` , and `flush` , and is implemented
179
+ /// with the following pseudo-code:
180
+ ///
181
+ /// `` `text
182
+ /// let pollable = subscribe-to-output-stream(this);
183
+ /// while !contents.is_empty() {
184
+ /// // Wait for the stream to become writable
185
+ /// poll-oneoff(pollable);
186
+ /// let Ok(n) = check-write(this); // eliding error handling
187
+ /// let len = min(n, contents.len());
188
+ /// let (chunk, rest) = contents.split_at(len);
189
+ /// write(this, chunk); // eliding error handling
190
+ /// contents = rest;
191
+ /// }
192
+ /// flush(this);
193
+ /// // Wait for completion of `flush`
194
+ /// poll-oneoff(pollable);
195
+ /// // Check for any errors that arose during `flush`
196
+ /// let _ = check-write(this); // eliding error handling
197
+ /// `` `
198
+ blocking-write-and-flush : func (
199
+ this : output-stream ,
200
+ contents : list <u8 >
201
+ ) -> result <_ , write-error >
167
202
168
- /// Write multiple zero-bytes to a stream .
203
+ /// Request to flush buffered output. This function never blocks .
169
204
///
170
- /// This function returns a `u64` indicating the number of zero-bytes
171
- /// that were written; it may be less than `len` . Equivelant to a call to
172
- /// `write` with a list of zeroes of the given length.
173
- write-zeroes : func (
205
+ /// This tells the output-stream that the caller intends any buffered
206
+ /// output to be flushed. the output which is expected to be flushed
207
+ /// is all that has been passed to `write` prior to this call.
208
+ ///
209
+ /// Upon calling this function, the `output-stream` will not accept any
210
+ /// writes (`check-write` will return `ok(0)` ) until the flush has
211
+ /// completed. The `subscribe-to-output-stream` pollable will become ready
212
+ /// when the flush has completed and the stream can accept more writes.
213
+ flush : func (
174
214
this : output-stream ,
175
- /// The number of zero-bytes to write
176
- len : u64
177
- ) -> result <tuple <u64 , stream-status >>
215
+ ) -> result <_ , write-error >
216
+
217
+ /// Request to flush buffered output, and block until flush completes
218
+ /// and stream is ready for writing again.
219
+ blocking-flush : func (
220
+ this : output-stream ,
221
+ ) -> result <_ , write-error >
222
+
223
+ /// Create a `pollable` which will resolve once the output-stream
224
+ /// is ready for more writing, or an error has occured. When this
225
+ /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an
226
+ /// error.
227
+ ///
228
+ /// If the stream is closed, this pollable is always ready immediately.
229
+ ///
230
+ /// The created `pollable` is a child resource of the `output-stream` .
231
+ /// Implementations may trap if the `output-stream` is dropped before
232
+ /// all derived `pollable` s created with this function are dropped.
233
+ subscribe-to-output-stream : func (this : output-stream ) -> pollable
178
234
179
- /// Write multiple zero bytes to a stream, with blocking .
235
+ /// Write zeroes to a stream.
180
236
///
181
- /// This is similar to `write-zeroes` , except that it blocks until at least
182
- /// one byte can be written. Equivelant to a call to `blocking-write` with
183
- /// a list of zeroes of the given length.
184
- blocking-write-zeroes : func (
237
+ /// this should be used precisely like `write` with the exact same
238
+ /// preconditions (must use check-write first), but instead of
239
+ /// passing a list of bytes, you simply pass the number of zero-bytes
240
+ /// that should be written.
241
+ write-zeroes : func (
185
242
this : output-stream ,
186
- /// The number of zero bytes to write
243
+ /// The number of zero- bytes to write
187
244
len : u64
188
- ) -> result <tuple < u64 , stream-status > >
245
+ ) -> result <_ , write-error >
189
246
190
247
/// Read from one stream and write to another.
191
248
///
@@ -232,16 +289,6 @@ interface streams {
232
289
src : input-stream
233
290
) -> result <tuple <u64 , stream-status >>
234
291
235
- /// Create a `pollable` which will resolve once either the specified stream
236
- /// is ready to accept bytes or the `stream-state` has become closed.
237
- ///
238
- /// Once the stream-state is closed, this pollable is always ready
239
- /// immediately.
240
- ///
241
- /// The created `pollable` is a child resource of the `output-stream` .
242
- /// Implementations may trap if the `output-stream` is dropped before
243
- /// all derived `pollable` s created with this function are dropped.
244
- subscribe-to-output-stream : func (this : output-stream ) -> pollable
245
292
246
293
/// Dispose of the specified `output-stream` , after which it may no longer
247
294
/// be used.
0 commit comments