io.um

interface Reader

Reader allows reading a stream of bytes.

type Reader* = interface {
// Read up to `max` bytes from the stream and return them. If `max` is 0,
// read all available bytes. The returned array can be smaller than `max`,
// if not enough data is available.
read(max: uint = 0): []uint8
}

interface Writer

Allows writing a stream of bytes.

type Writer* = interface {
// Write an array of bytes into the data stream. Returns the number of
// bytes written.
write(data: []uint8): uint
}

interface ReaderWriter

An interface allowing both reading and writing.

type ReaderWriter* = interface {
Reader
Writer
}

fn mkMemory

Creates a ReaderWriter with a memory buffer. data is the initial data, which can be empty.

fn mkMemory*(data: []uint8): ReaderWriter {

fn mkFile

Creates a ReaderWriter for a file.

NOTE: While the returned interface is ReaderWriter, the actual behavior depends on the file mode.

fn mkFile*(f: std::File): ReaderWriter {


import (
	"std.um"
)

type ReaderHeader* = struct {
	c__readable: ^void
	c__read: ^void
}

//~~interface Reader
// Reader allows reading a stream of bytes.
type Reader* = interface {
	// Read up to `max` bytes from the stream and return them. If `max` is 0,
	// read all available bytes. The returned array can be smaller than `max`,
	// if not enough data is available.
	read(max: uint = 0): []uint8
}
//~~

type WriterHeader* = struct {
	__padding: ^void
	c__write: ^void
}

//~~interface Writer
// Allows writing a stream of bytes.
type Writer* = interface {
	// Write an array of bytes into the data stream. Returns the number of
	// bytes written.
	write(data: []uint8): uint
}
//~~

//~~interface ReaderWriter
// An interface allowing both reading and writing.
type ReaderWriter* = interface {
	Reader
	Writer
}
//~~

type ReaderWriterHeader* = struct {
	c__read: ^void
	c__write: ^void
}

type Memory = struct {
	header: ReaderWriterHeader
	data: ^uint8
	cap: uint
	writePtr: uint
	readPtr: uint
}

fn um__memory__init(mem: ^Memory, data: ^uint8, len: uint)
fn um__memory__read(mem: ^Memory, max: uint, typeofbytes: ^void, out: ^[]uint8)
fn um__memory__write(mem: ^Memory, data: ^[]uint8): uint

fn (m: ^Memory) read(max: uint = 0): []uint8 {
	var data: []uint8
	um__memory__read(m, max, typeptr([]uint8), &data)
	return data
}

fn (m: ^Memory) write(data: []uint8): uint {
	return um__memory__write(m, &data)
}

//~~fn mkMemory
// Creates a ReaderWriter with a memory buffer. `data` is the initial data,
// which can be empty.
fn mkMemory*(data: []uint8): ReaderWriter {
//~~
	mem := Memory {}
	if len(data) == 0 {
		mem.cap = 32
		um__memory__init(&mem, null, 0)
	} else {
		um__memory__init(&mem, &data[0], len(data))
	}

	return mem
}

type File = struct {
	header: ReaderWriterHeader
	file: std::File
}

fn um__file__init(f: ^File)
fn um__file__write(f: ^File, data: ^[]uint8): uint
fn um__file__read(f: ^File, max: uint, typeofbytes: ^void, out: ^[]uint8)

fn (f: ^File) read(max: uint = 0): []uint8 {
	var data: []uint8
	um__file__read(f, max, typeptr([]uint8), &data)
	return data
}

fn (f: ^File) write(data: []uint8): uint {
	return um__file__write(f, &data)
}

//~~fn mkFile
// Creates a ReaderWriter for a file.
//
// NOTE: While the returned interface is `ReaderWriter`, the actual behavior
// depends on the file mode.
fn mkFile*(f: std::File): ReaderWriter {
//~~
	fil := File { file: f }
	um__file__init(&fil)
	return fil
}

fn main() {
	mem := mkMemory([]uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
	printf("mem.read(2) = %v\n", mem.read(2))
	printf("mem.write({1, 2, 3})\n")
	mem.write({ 1, 2, 3 })
	printf("mem.read() = %v\n", mem.read())
	printf("mem.write({1, 2, 3})\n")
	mem.write({ 1, 2, 3 })
	printf("mem.read() = %v\n", mem.read())
	
	f := std::fopen("umbox.json", "r").item0
	frw := mkFile(f)
	printf("frw.read() = %v\n", str([]char(frw.read())))
	std::fclose(f)
}