Compile using blc my-file-name.bl
and run ./out
.
#import "std/io"
// Custom stream implementation based on std.Stream.
MyStream :: struct #base std.Stream {
// Preallocated static buffer.
buffer: [64]u8;
// Current position in the buffer array.
position: s64;
}
// Virtual table of the stream setting up stream API functions. Our implementation
// does not support seeking, so the seek function is null.
MY_STRAM_VTABLE :: std.StreamVTable.{
read = auto &my_read,
write = auto &my_write
};
// Actual read function implementation.
my_read :: fn (stream: *MyStream, dest: *u8, bytes_to_read: s64) (s64, Error) {
using std;
size := min(stream.position, bytes_to_read);
stream.position -= size;
if stream.position < 0 {
size -= stream.position;
stream.position = 0;
}
if size > 0 {
memcpy(dest, &stream.buffer[stream.position], auto size);
}
return size, OK;
}
// Actual write function implementation.
my_write :: fn (stream: *MyStream, src: *u8, bytes_to_write: s64) (s64, Error) {
size :: std.min(stream.buffer.len - stream.position, bytes_to_write);
if size > 0 {
// size may be zero even in case the buffer is full.
memcpy(&stream.buffer[stream.position], src, auto size);
stream.position += size;
}
return size, OK;
}
init_stream :: fn (stream: *MyStream) {
stream.vtable = &MY_STRAM_VTABLE;
stream.position = 0;
}
main :: fn () s32 {
using std;
stream: MyStream #noinit;
init_stream(&stream);
// Use of the IO API.
write_string(&stream, "Hello");
write_string(&stream, "World");
str := str_new();
defer str_delete(&str);
read_string(&stream, &str);
print("%\n", str);
return 0;
}