Input/Ouput
#import "std/io"
Input and output is handled by generic stream interface containing callbacks for read, write and seek operations. The stream itself can contain any data needed (i.e. memory buffer, handle to file, etc.), generic functionality is handled via virtual table containing pointers to the implementation of all needed (supported) stream API functions.
Example
#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;
}
std.Stream
Stream :: struct {
vtable: *StreamVTable;
}
File: io.bl
std.StreamVTable
StreamVTable :: struct {
read: *fn (stream: *Stream, dest: *u8, bytes_to_write: s64) (bytes_read: s64, err: Error);
write: *fn (stream: *Stream, src: *u8, bytes_to_read: s64) (bytes: s64, err: Error);
seek: *fn (stream: *Stream, locator: StreamLocator, offset: s64) (position: s64, err: Error);
flush: *fn (stream: *Stream) Error;
}
File: io.bl
std.StreamLocator
StreamLocator :: enum {
CURRENT;
BEGIN;
END;
}
Stream seek offset locator.
File: io.bl
std.write
write :: fn (stream: *Stream, src: *u8, bytes_to_write: s64) (_0: s64, _1: Error) #inline
Write bytes_to_write
count of bytes from the str
into the stream. Returns
count of actually written bytes or an error.
File: io.bl
std.write_data
write_data :: fn (stream: *Stream, data: []u8, bytes_to_write :: ) (_0: s64, _1: Error) #inline
Write the data slice into the stream, the bytes_to_write
can be specified to limit count
of written bytes. Returns count of actually written bytes or an error.
File: io.bl
std.write_string
write_string :: fn (stream: *Stream, str: string_view, bytes_to_write :: ) (_0: s64, _1: Error) #inline
Write the data string into the stream, the bytes_to_write
can be specified to limit count
of written bytes. Returns count of actually written bytes or an error.
File: io.bl
std.write_all
write_all :: fn (stream: *Stream, src: *u8, bytes_to_write: s64) Error
File: io.bl
std.write_value
write_value :: fn (stream: *Stream, v: *?T) Error #inline
File: io.bl
std.write_array
write_array :: fn (stream: *Stream, v: []?T) Error
File: io.bl
std.read
read :: fn (stream: *Stream, dest: *u8, bytes_to_read: s64) (_0: s64, _1: Error) #inline
Read bytes_to_read
count of bytes from the stream into dest
memory. Returns count of actually
read bytes or an error.
File: io.bl
std.read_data
read_data :: fn (stream: *Stream, dest: *[..]u8, bytes_to_read : s64: , buffer_size :: 512) Error
Read bytes_to_read
count of bytes from the stream into dest
dynamic array. Internal buffer size may
be customized by buffer_size
argument.
Return an error in case reading failed.
File: io.bl
std.read_string
read_string :: fn (stream: *Stream, dest: *string, bytes_to_read : s64: , buffer_size :: 512) Error
Read bytes_to_read
count of bytes from the stream into dest
. Internal buffer size may be
customized by buffer_size
argument.
Return and error in case reading failed.
File: io.bl
std.read_all
read_all :: fn (stream: *Stream, dest: *u8, bytes_to_read: s64, buffer_size :: 512) Error
File: io.bl
std.read_value
read_value :: fn (stream: *Stream, v: *?T) Error #inline
File: io.bl
std.read_array
read_array :: fn (stream: *Stream, v: *[..]?T) Error
File: io.bl
std.seek
seek :: fn (stream: *Stream, locator :: , offset : s64: 0) (position: s64, err: Error)
Set the stream pointer position to the offset
value relative to the stream locator
. Returns
the pointer position or an error.
File: io.bl
std.flush
flush :: fn (stream: *Stream) Error
Flush all buffered stream data.
File: io.bl