mirror of https://github.com/Wilfred/difftastic/
61 lines
1.5 KiB
Plaintext
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);
|
|
};
|