Banjo API 1.0.0-rc.2
Low-level C99 game development API
Loading...
Searching...
No Matches
Data Stream

Macros

#define bj_stream_read_t(stream, type, buffer)
#define bj_stream_skip_t(stream, type)

Typedefs

typedef enum bj_seek_origin bj_seek_origin

Enumerations

enum  bj_seek_origin { BJ_SEEK_BEGIN = 0x00 , BJ_SEEK_CURRENT = 0x01 , BJ_SEEK_END = 0x02 }

Functions

struct bj_streambj_allocate_stream (void)
struct bj_streambj_open_stream_read (const void *data, size_t length)
struct bj_streambj_open_stream_file (const char *path, struct bj_error **error)
void bj_close_stream (struct bj_stream *stream)
size_t bj_read_stream (struct bj_stream *stream, void *dest, size_t count)
size_t bj_get_stream_length (struct bj_stream *stream)
size_t bj_seek_stream (struct bj_stream *stream, ptrdiff_t position, enum bj_seek_origin from)
size_t bj_tell_stream (struct bj_stream *stream)

Detailed Description

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];
bj_read_stream(stream, header, sizeof header);
uint32_t value;
bj_stream_read_t(stream, uint32_t, &value); // reads sizeof(uint32_t) bytes
bj_stream_skip_t(stream, uint32_t); // advance the cursor by 4 bytes
#define bj_stream_read_t(stream, type, buffer)
Reads data of a specified type from the stream into a buffer.
Definition stream.h:206
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.
Definition stream.h:214

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.

Macro Definition Documentation

◆ bj_stream_read_t

#define bj_stream_read_t ( stream,
type,
buffer )
Value:
bj_read_stream(stream, buffer, sizeof(type))

Reads data of a specified type from the stream into a buffer.

Parameters
streamPointer to the stream instance.
typeData type to read.
bufferPointer 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:
bj_read_stream(stream, 0, sizeof(type))

Skips reading data of a specified type from the stream.

Parameters
streamPointer to the stream instance.
typeData type to skip.

Definition at line 214 of file stream.h.

Typedef Documentation

◆ bj_seek_origin

Definition at line 87 of file stream.h.

Enumeration Type Documentation

◆ 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.

Function Documentation

◆ 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
streamPointer 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
streamPointer 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
pathThe file path to open
errorOptional 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
dataPointer to the data buffer.
lengthLength 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
streamPointer to the stream instance.
destPointer to the destination buffer.
countNumber 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()

size_t bj_seek_stream ( struct bj_stream * stream,
ptrdiff_t position,
enum bj_seek_origin from )

Seeks to a new position in the stream relative to a specified origin.

Parameters
streamPointer to the stream instance.
positionOffset for the new position.
fromOrigin 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
streamPointer to the stream instance.
Returns
The current position within the stream.