package wasi:io /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. interface streams { use wasi:poll/poll.{pollable} /// Streams provide a sequence of data and then end; once they end, they /// no longer provide any further data. /// /// For example, a stream reading from a file ends when the stream reaches /// the end of the file. For another example, a stream reading from a /// socket ends when the socket is closed. enum stream-status { /// The stream is open and may produce further data. open, /// When reading, this indicates that the stream will not produce /// further data. /// When writing, this indicates that the stream will no longer be read. /// Further writes are still permitted. ended, } /// An input bytestream. In the future, this will be replaced by handle /// types. /// /// `input-stream`s are *non-blocking* to the extent practical on underlying /// platforms. I/O operations always return promptly; if fewer bytes are /// promptly available than requested, they return the number of bytes promptly /// available, which could even be zero. To wait for data to be available, /// use the `subscribe-to-input-stream` function to obtain a `pollable` which /// can be polled for using `wasi:poll/poll.poll_oneoff`. /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. /// /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type input-stream = u32 /// Perform a non-blocking read from the stream. /// /// This function returns a list of bytes containing the data that was /// read, along with a `stream-status` which, indicates whether further /// reads are expected to produce data. The returned list will contain up to /// `len` bytes; it may return fewer than requested, but not more. An /// empty list and `stream-status:open` indicates no more data is /// available at this time, and that the pollable given by /// `subscribe-to-input-stream` will be ready when more data is available. /// /// Once a stream has reached the end, subsequent calls to `read` or /// `skip` will always report `stream-status:ended` rather than producing more /// data. /// /// When the caller gives a `len` of 0, it represents a request to read 0 /// bytes. This read should always succeed and return an empty list and /// the current `stream-status`. /// /// The `len` parameter is a `u64`, which could represent a list of u8 which /// is not possible to allocate in wasm32, or not desirable to allocate as /// as a return value by the callee. The callee may return a list of bytes /// less than `len` in size while more bytes are available for reading. read: func( this: input-stream, /// The maximum number of bytes to read len: u64 ) -> result, stream-status>> /// Read bytes from a stream, after blocking until at least one byte can /// be read. Except for blocking, identical to `read`. blocking-read: func( this: input-stream, /// The maximum number of bytes to read len: u64 ) -> result, stream-status>> /// Skip bytes from a stream. /// /// This is similar to the `read` function, but avoids copying the /// bytes into the instance. /// /// Once a stream has reached the end, subsequent calls to read or /// `skip` will always report end-of-stream rather than producing more /// data. /// /// This function returns the number of bytes skipped, along with a /// `stream-status` indicating whether the end of the stream was /// reached. The returned value will be at most `len`; it may be less. skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, ) -> result> /// Skip bytes from a stream, after blocking until at least one byte /// can be skipped. Except for blocking behavior, identical to `skip`. blocking-skip: func( this: input-stream, /// The maximum number of bytes to skip. len: u64, ) -> result> /// Create a `pollable` which will resolve once either the specified stream /// has bytes available to read or the other end of the stream has been /// closed. /// The created `pollable` is a child resource of the `input-stream`. /// Implementations may trap if the `input-stream` is dropped before /// all derived `pollable`s created with this function are dropped. subscribe-to-input-stream: func(this: input-stream) -> pollable /// Dispose of the specified `input-stream`, after which it may no longer /// be used. /// Implementations may trap if this `input-stream` is dropped while child /// `pollable` resources are still alive. /// After this `input-stream` is dropped, implementations may report any /// corresponding `output-stream` has `stream-state.closed`. drop-input-stream: func(this: input-stream) /// An output bytestream. In the future, this will be replaced by handle /// types. /// /// `output-stream`s are *non-blocking* to the extent practical on /// underlying platforms. Except where specified otherwise, I/O operations also /// always return promptly, after the number of bytes that can be written /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe-to-output-stream` function to obtain a /// `pollable` which can be polled for using `wasi:poll`. /// /// And at present, it is a `u32` instead of being an actual handle, until /// the wit-bindgen implementation of handles and resources is ready. /// /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). type output-stream = u32 /// An error for output-stream operations. /// /// Contrary to input-streams, a closed output-stream is reported using /// an error. enum write-error { /// The last operation (a write or flush) failed before completion. last-operation-failed, /// The stream is closed: no more input will be accepted by the /// stream. A closed output-stream will return this error on all /// future operations. closed } /// Check readiness for writing. This function never blocks. /// /// Returns the number of bytes permitted for the next call to `write`, /// or an error. Calling `write` with more bytes than this function has /// permitted will trap. /// /// When this function returns 0 bytes, the `subscribe-to-output-stream` /// pollable will become ready when this function will report at least /// 1 byte, or an error. check-write: func( this: output-stream ) -> result /// Perform a write. This function never blocks. /// /// Precondition: check-write gave permit of Ok(n) and contents has a /// length of less than or equal to n. Otherwise, this function will trap. /// /// returns Err(closed) without writing if the stream has closed since /// the last call to check-write provided a permit. write: func( this: output-stream, contents: list ) -> result<_, write-error> /// Perform a write of up to 4096 bytes, and then flush the stream. Block /// until all of these operations are complete, or an error occurs. /// /// This is a convenience wrapper around the use of `check-write`, /// `subscribe-to-output-stream`, `write`, and `flush`, and is implemented /// with the following pseudo-code: /// /// ```text /// let pollable = subscribe-to-output-stream(this); /// while !contents.is_empty() { /// // Wait for the stream to become writable /// poll-oneoff(pollable); /// let Ok(n) = check-write(this); // eliding error handling /// let len = min(n, contents.len()); /// let (chunk, rest) = contents.split_at(len); /// write(this, chunk); // eliding error handling /// contents = rest; /// } /// flush(this); /// // Wait for completion of `flush` /// poll-oneoff(pollable); /// // Check for any errors that arose during `flush` /// let _ = check-write(this); // eliding error handling /// ``` blocking-write-and-flush: func( this: output-stream, contents: list ) -> result<_, write-error> /// Request to flush buffered output. This function never blocks. /// /// This tells the output-stream that the caller intends any buffered /// output to be flushed. the output which is expected to be flushed /// is all that has been passed to `write` prior to this call. /// /// Upon calling this function, the `output-stream` will not accept any /// writes (`check-write` will return `ok(0)`) until the flush has /// completed. The `subscribe-to-output-stream` pollable will become ready /// when the flush has completed and the stream can accept more writes. flush: func( this: output-stream, ) -> result<_, write-error> /// Request to flush buffered output, and block until flush completes /// and stream is ready for writing again. blocking-flush: func( this: output-stream, ) -> result<_, write-error> /// Create a `pollable` which will resolve once the output-stream /// is ready for more writing, or an error has occured. When this /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// error. /// /// If the stream is closed, this pollable is always ready immediately. /// /// The created `pollable` is a child resource of the `output-stream`. /// Implementations may trap if the `output-stream` is dropped before /// all derived `pollable`s created with this function are dropped. subscribe-to-output-stream: func(this: output-stream) -> pollable /// Write zeroes to a stream. /// /// this should be used precisely like `write` with the exact same /// preconditions (must use check-write first), but instead of /// passing a list of bytes, you simply pass the number of zero-bytes /// that should be written. write-zeroes: func( this: output-stream, /// The number of zero-bytes to write len: u64 ) -> result<_, write-error> /// Read from one stream and write to another. /// /// This function returns the number of bytes transferred; it may be less /// than `len`. /// /// Unlike other I/O functions, this function blocks until all the data /// read from the input stream has been written to the output stream. splice: func( this: output-stream, /// The stream to read from src: input-stream, /// The number of bytes to splice len: u64, ) -> result> /// Read from one stream and write to another, with blocking. /// /// This is similar to `splice`, except that it blocks until at least /// one byte can be read. blocking-splice: func( this: output-stream, /// The stream to read from src: input-stream, /// The number of bytes to splice len: u64, ) -> result> /// Forward the entire contents of an input stream to an output stream. /// /// This function repeatedly reads from the input stream and writes /// the data to the output stream, until the end of the input stream /// is reached, or an error is encountered. /// /// Unlike other I/O functions, this function blocks until the end /// of the input stream is seen and all the data has been written to /// the output stream. /// /// This function returns the number of bytes transferred, and the status of /// the output stream. forward: func( this: output-stream, /// The stream to read from src: input-stream ) -> result> /// Dispose of the specified `output-stream`, after which it may no longer /// be used. /// Implementations may trap if this `output-stream` is dropped while /// child `pollable` resources are still alive. /// After this `output-stream` is dropped, implementations may report any /// corresponding `input-stream` has `stream-state.closed`. drop-output-stream: func(this: output-stream) }