Read bytes one chunk at a time from either a file or an in-memory buffer, with the same API for both.
A stream is a moving cursor over a sequence of bytes: you ask for the next N bytes, the cursor advances, you ask again, and so on until you reach the end. It's the same idea as FILE* from the C standard library, except a bj_stream can be backed by either an actual file on disk or a pointer to bytes you already have in memory, and you read it the same way regardless.
The point of having one type that does both is so a parser can be written once. Banjo's BMP loader is the same code whether it's reading a file at runtime or reading an embedded byte array during a unit test. You're likely to want the same flexibility in your own asset loaders.
Streams are read-only (no write API) and seekable (you can move the cursor backwards and forwards).
Open a stream from bytes or from a file
- bj_open_stream_read wraps an existing buffer: (data_pointer, length). The stream does not copy the bytes; it remembers your pointer and reads from it directly, so you have to keep the buffer alive until the stream is closed.
- bj_open_stream_file opens a file path. The whole file is read into an internal buffer at open time (so the file handle itself is released immediately), and subsequent reads happen from that buffer.
Either way, release with bj_close_stream when you're done.
Read bytes
uint8_t header[14];
uint32_t value;
#define bj_stream_read_t(stream, type, buffer)
Reads data of a specified type from the stream into a buffer.
size_t bj_read_stream(struct bj_stream *stream, void *dest, size_t count)
Reads data from the stream into a destination buffer.
#define bj_stream_skip_t(stream, type)
Skips reading data of a specified type from the stream.
bj_stream_read_t and bj_stream_skip_t are macros that derive the byte count from a C type, useful when you're parsing fixed binary headers (BMP, WAV, …).
Random access
bj_seek_stream moves the cursor; bj_tell_stream tells you where it currently is; bj_get_stream_length tells you the total size of the underlying data. Seeking past either end is clamped to the boundary rather than failing, so you can't accidentally walk off the buffer.
Any read returns the actual number of bytes transferred. If that's less than you asked for, you've hit the end of the stream.
◆ bj_stream_read_t
| #define bj_stream_read_t |
( |
| stream, |
|
|
| type, |
|
|
| buffer ) |
Value:
Reads data of a specified type from the stream into a buffer.
- Parameters
-
| stream | Pointer to the stream instance. |
| type | Data type to read. |
| buffer | Pointer to the buffer to store the read data. |
Definition at line 206 of file stream.h.
◆ bj_stream_skip_t
| #define bj_stream_skip_t |
( |
| stream, |
|
|
| type ) |
Value:
Skips reading data of a specified type from the stream.
- Parameters
-
| stream | Pointer to the stream instance. |
| type | Data type to skip. |
Definition at line 214 of file stream.h.
◆ bj_seek_origin
◆ bj_seek_origin
Position in a bj_stream to use for origin.
| Enumerator |
|---|
| BJ_SEEK_BEGIN | The beginning of the stream.
|
| BJ_SEEK_CURRENT | The current position of the stream.
|
| BJ_SEEK_END | The end of the stream.
|
Definition at line 81 of file stream.h.
◆ bj_allocate_stream()
| struct bj_stream * bj_allocate_stream |
( |
void | | ) |
|
Allocate a new bj_stream object.
- Returns
- A pointer to a new bj_stream
- Memory Management
The object pointed by the returned value must be deleted using bj_free.
◆ bj_close_stream()
| void bj_close_stream |
( |
struct bj_stream * | stream | ) |
|
Deletes a struct bj_stream object and releases associated memory.
- Parameters
-
| stream | Pointer to the struct bj_stream object to delete. |
◆ bj_get_stream_length()
| size_t bj_get_stream_length |
( |
struct bj_stream * | stream | ) |
|
Get the size of the stream.
- Parameters
-
| stream | Pointer to the stream instance. |
- Returns
- The size of the stream, in bytes
◆ bj_open_stream_file()
| struct bj_stream * bj_open_stream_file |
( |
const char * | path, |
|
|
struct bj_error ** | error ) |
Creates a new struct bj_stream for reading from a file.
- Parameters
-
| path | The file path to open |
| error | Optional error object |
- Returns
- A pointer to the new bj_stream, or 0 on error.
The file memory is entirely copied to internal memory buffer.
◆ bj_open_stream_read()
| struct bj_stream * bj_open_stream_read |
( |
const void * | data, |
|
|
size_t | length ) |
Creates a new struct bj_stream for reading from a memory buffer.
- Parameters
-
| data | Pointer to the data buffer. |
| length | Length of the data buffer in bytes. |
- Returns
- A pointer to the newly created struct bj_stream object.
◆ bj_read_stream()
| size_t bj_read_stream |
( |
struct bj_stream * | stream, |
|
|
void * | dest, |
|
|
size_t | count ) |
Reads data from the stream into a destination buffer.
- Parameters
-
| stream | Pointer to the stream instance. |
| dest | Pointer to the destination buffer. |
| count | Number of bytes to read. |
- Returns
- Number of bytes actually read.
The function advances the stream position by count bytes. If fewer bytes than count are read, the end of the stream is reached.
- Memory Safety
This function does not perform any memory bounds checking. It is the caller's responsibility to ensure dest has enough space to hold count bytes.
◆ bj_seek_stream()
Seeks to a new position in the stream relative to a specified origin.
- Parameters
-
| stream | Pointer to the stream instance. |
| position | Offset for the new position. |
| from | Origin relative to which the position should be calculated. |
- Returns
- The new position within the stream after seeking.
The function clamps the new position to stay within the valid range of the stream, from 0 to the length of the stream.
◆ bj_tell_stream()
| size_t bj_tell_stream |
( |
struct bj_stream * | stream | ) |
|
Returns the current position of the cursor in the stream.
- Parameters
-
| stream | Pointer to the stream instance. |
- Returns
- The current position within the stream.