InStream

InStream performs buffered input from an arbitrary input source. The underlying input can either come from an InPipe or from memory.

InStream is similar to FILE in C or std::istream in C++. It maintains an internal input buffer on the heap, and provides functions to quickly read small amounts of data incrementally, making it suitable for application-level parsing of text and binary formats. InPipe, on the other hand, is a lower-level class more akin to a Unix file descriptor.

If the InStream's underlying input comes from an InPipe, the internal input buffer is managed by a ChunkListNode, and you can call getCursor() at any time to create a ChunkCursor. You can then rewind the InStream to an earlier point using rewind(), or copy some data between two ChunkCursors into a single contiguous memory buffer.

Every InStream is also a StringReader, and you can cast an InStream to a StringReader at any time by calling strReader(). The main reason why InStream and StringReader are separate classes is to help express intention in the code. InStream is mainly intended to read binary data and StringReader is mainly intended to read text, but the two classes are interchangeable.

Header File

#include <ply-runtime/io/InStream.h>

Also included from <ply-runtime/Base.h>.

Data Members

u8* curByte [code]

A pointer to the next byte in the input buffer. If this pointer is equal to endByte, it is not safe to read from the pointer. Use member functions such as tryMakeBytesAvailable() to ensure that this pointer can be read safely.

u8* endByte [code]

A pointer to the last byte in the input buffer. This pointer does not necessarily represent the end of the input stream; for example, it still might be possible to read more data from the underlying InPipe, or to advance to the next chunk in a ChunkList, by calling tryMakeBytesAvailable().

Member Functions

InStream() [code]

Constructs an empty InStream. You can replace it with a valid InStream later using move assignment.

InStream(InStream&& other) [code]

Move constructor.

InStream(OptionallyOwned<InPipe>&& inPipe, u32 chunkSizeExp = DefaultChunkSizeExp) [code]

Constructs an InStream from an InPipe. If inPipe is an owned pointer, the InStream takes ownership of the InPipe and will automatically destroy it in its destructor. If inPipe is a borrowed pointer, the InStream does not take ownership of the InPipe.

void operator=(InStream&& other) [code]

Move assignment operator.

bool isView() const [code]

Return true if the InStream is reading from a fixed memory buffer. Typically this means that the InStream was created from a derived class such as ViewInStream or StringViewReader.

bool atEOF() const [code]

Returns true if no further data can be read from the stream, such as when the end of-file is encountered. This function also returns true if there's an error in the underlying InPipe that prevents further reading, such as when a network socket is closed prematurely.

s32 numBytesAvailable() const [code]

Returns the number of bytes between curByte and endByte. Equivalent to viewAvailable().numBytes.

ConstBufferView viewAvailable() const [code]

Returns the memory region between curByte and endByte as a ConstBufferView.

u64 getSeekPos() const [code]

Returns a number that increases each time a byte is read from the InStream. If the underlying InPipe is a file, this number typically corresponds to the file offset.

ChunkCursor getCursor() const [code]

Returns a ChunkCursor at the current input position. The ChunkCursor increments the reference count of the InStream's internal ChunkListNode, preventing it from being destroyed when reading past the end of the chunk. This function is used internally by StringReader::readString in order to copy some region of the input to a String. In particular, StringReader::readString<fmt::Line> returns a single line of input as a String even if it originally spanned multiple ChunkListNodes.

void rewind(ChunkCursor cursor) [code]

Rewinds the InStream back to a previously saved position. This also clears the InStream's end-of-file status.

u32 tryMakeBytesAvailable(u32 numBytes = 1) [code]

Attempts to make at least numBytes available to read contiguously at curByte. Returns the number of bytes actually made available. If the underlying InPipe is waiting for data, this function will block until at least numBytes bytes arrive. If EOF/error is encountered, the return value will be less than numBytes; otherwise, it will be greater than or equal to numBytes.

char peekByte(u32 index = 0) const [code]

Equivalent to curByte[index], with bounds checking performed on index at runtime. The caller is responsible for ensuring that it's safe to read from the input buffer at this index by calling tryMakeBytesAvailable() beforehand.

if (ins->tryMakeBytesAvailable() && ins->peekByte() == '.') {
    // Handle this input character...
    ins->advanceByte();
}
void advanceByte(u32 numBytes = 1) [code]

Equivalent to curByte += numBytes, with bounds checking performed on numBytes at runtime. The caller is responsible for ensuring that there are actually numBytes available in the input buffer by calling tryMakeBytesAvailable() beforehand.

u8 readByte() [code]

Reads and returns the next byte from the input stream, or 0 if no more bytes are available. Use atEOF() to determine whether the read was actually successful.

bool read(BufferView dst) [code]

Attempts to fill dst with data from the input stream. If the underlying InPipe is waiting for data, this function will block until dst is filled. Returns true if the buffer is filled successfully. If EOF/error is encountered before dst can be filled, the remainder of dst is filled with zeros and false is returned.

Buffer readRemainingContents() [code]

Reads all the remaining data from the input stream and returns the contents as a Buffer.

ViewInStream* asViewInStream() [code]
const ViewInStream* asViewInStream() const [code]
StringReader* asStringReader() [code]
StringViewReader* asStringViewReader() [code]

Casts the InStream to various other types. It's always legal to call asStringReader(), but it's only legal to call the other functions if isView() returns true.