Input and Output
Plywood provides a composable I/O system built around Stream and Pipe classes. Streams provide buffered, high-level read/write operations, while pipes represent the underlying I/O mechanisms (files, sockets, memory buffers).
Standard I/O
These functions provide access to the standard input, output, and error streams.
Stream | getStdIn(ConsoleMode mode) |
Stream | getStdOut(ConsoleMode mode) |
Stream | getStdErr(ConsoleMode mode) |
| - | |
Pipe* | getStdInPipe() |
Pipe* | getStdOutPipe() |
Pipe* | getStdErrPipe() |
Stream getStdIn(ConsoleMode mode)Returns a stream for reading from standard input. Pass
BINARYfor binary mode.Stream getStdOut(ConsoleMode mode)Returns a stream for writing to standard output. Pass
BINARYfor binary mode.Stream getStdErr(ConsoleMode mode)Returns a stream for writing to standard error.
Pipe* getStdInPipe()
Pipe* getStdOutPipe()
Pipe* getStdErrPipe()Returns the raw pipe objects for standard I/O. These are singletons and should not be freed.
Stream
A Stream wraps a Pipe and provides buffered I/O operations. Streams handle the details of buffering data for efficient reads and writes.
| Stream() |
| Stream(Pipe* pipe, bool isPipeOwner) |
| Stream(Stream&& other) |
| ~Stream() |
Stream& | operator=(Stream&& other) |
bool | isOpen() |
explicit | operator bool() |
void | close() |
bool | makeReadable(u32 minBytes) |
bool | makeWritable(u32 minBytes) |
bool | hasRemainingBytes() const |
u32 | numRemainingBytes() const |
StringView | viewRemainingBytes() const |
MutStringView | viewRemainingBytesMut() |
void | flush(bool toDevice) |
char | peekByte() |
char | readByte() |
u32 | read(MutStringView dst) |
u32 | skip(u32 numBytes) |
bool | write(char c) |
u32 | write(StringView bytes) |
void | format(StringView fmt, const Args& args) |
u64 | getSeekPos() |
void | seekTo(u64 seekPos) |
Stream()Constructs an empty stream that is not connected to any pipe.
Stream(Pipe* pipe, bool isPipeOwner)Constructs a stream from a pipe. If
isPipeOwneris true, the stream will destroy the pipe when closed.Stream(Stream&& other)Move constructor.
Stream& operator=(Stream&& other)Move assignment.
bool isOpen()Returns
trueif the stream is connected to a valid pipe.explicit operator bool()Same as
isOpen().void close()Flushes and closes the stream. If the stream owns the pipe, the pipe is destroyed.
bool makeReadable(u32 minBytes)Ensures at least
minBytesare available in the read buffer. Returnsfalseif end-of-file is reached.bool makeWritable(u32 minBytes)Ensures at least
minBytesof space are available in the write buffer.bool hasRemainingBytes()Returns
trueif there are any bytes remaining in the read buffer.u32 numRemainingBytes() constReturns the number of bytes currently available in the read buffer.
StringView viewRemainingBytes() constReturns a view of the bytes currently in the read buffer.
MutStringView viewRemainingBytesMut()Returns a mutable view of the read buffer.
void flush(bool toDevice)Writes any buffered data to the underlying pipe. If
toDeviceis true, also flushes the pipe to the physical device.char peekByte()Returns the next byte in the input stream, or
0if at end-of-file.char readByte()Reads and returns a single byte.
u32 read(MutStringView dst)Reads up to
dst.numBytesbytes intodst. Returns the number of bytes actually read.u32 skip(u32 numBytes)Skips up to
numBytesin the input. Returns the number of bytes actually skipped.bool write(char c)Writes a single byte.
u32 write(StringView bytes)Writes the given bytes to the stream. Returns the number of bytes written.
void format(StringView fmt, const Args& args)Writes formatted text using
{}placeholders.u64 getSeekPos()Returns the current seek position in the stream.
void seekTo(u64 seekPos)Seeks to the specified position. Only works with seekable pipes.
Remember to write '\n' for newlines. There's no endl like C++ iostreams—use flush to force output.
MemStream
A MemStream writes to an in-memory buffer that grows as needed. This is useful for building strings or serializing data.
ViewStream
A ViewStream reads from a fixed memory buffer (a StringView). This is useful for parsing strings or data already in memory.
Pipe
Pipe is the abstract base class for all I/O providers. Concrete implementations include file pipes, socket pipes, and memory pipes. You rarely need to work with pipes directly—use Stream instead.
virtual | ~Pipe() |
virtual u32 | read(MutStringView buf) |
virtual bool | write(StringView buf) |
virtual void | flush(bool toDevice) |
virtual u64 | getFileSize() |
virtual void | seekTo(s64 offset) |
u32 | getFlags() const |
virtual ~Pipe()Virtual destructor for proper cleanup of derived classes.
virtual u32 read(MutStringView buf)Reads up to
buf.numBytesbytes intobuf. Returns the number of bytes actually read. Returns 0 at end-of-file.virtual bool write(StringView buf)Writes the bytes in
buf. Returnstrueon success.virtual void flush(bool toDevice)Flushes any buffered writes. If
toDeviceis true, ensures data reaches the physical device.virtual u64 getFileSize()Returns the total size of the underlying file, or 0 if not applicable.
virtual void seekTo(s64 offset)Seeks to the specified byte offset. Only supported by seekable pipes.
u32 getFlags() constReturns the pipe's capability flags (readable, writable, seekable, etc.).