difftastic/vendored_parsers/tree-sitter-hare/example/limit.ha

61 lines
1.5 KiB
Plaintext

use strings;
type limited_stream = struct {
stream: stream,
source: *stream,
limit: size,
};
fn limited_stream_new(source: *stream, limit: size) *limited_stream = {
return alloc(limited_stream {
stream = stream {
name = strings::dup(source.name),
closer = &limited_close,
...
},
source = source,
limit = limit,
});
};
// Create an overlay stream that only allows a limited amount of bytes to be
// read from the underlying stream.
export fn limitreader(source: *stream, limit: size) *stream = {
let stream = limited_stream_new(source, limit);
stream.stream.reader = &limited_read;
return &stream.stream;
};
// Create an overlay stream that only allows a limited amount of bytes to be
// written to the underlying stream.
export fn limitwriter(source: *stream, limit: size) *stream = {
let stream = limited_stream_new(source, limit);
stream.stream.writer = &limited_write;
return &stream.stream;
};
fn limited_read(s: *stream, buf: []u8) (size | EOF | error) = {
let stream = s: *limited_stream;
if (len(buf) > stream.limit) {
buf = buf[..stream.limit];
};
stream.limit -= len(buf);
return read(stream.source, buf);
};
fn limited_write(s: *stream, buf: const []u8) (size | error) = {
let stream = s: *limited_stream;
let slice = if (len(buf) > stream.limit) {
buf[..stream.limit];
} else {
buf[..];
};
stream.limit -= len(slice);
return write(stream.source, slice);
};
fn limited_close(s: *stream) void = {
free(s.name);
free(s);
};