~sircmpwn/hare-tar

00103d1a3d7f2fed23d23cd2465bb632d617cb15 — Drew DeVault 2 years ago 93e3aa7
format::tar: implement seek within entries
1 files changed, 33 insertions(+), 0 deletions(-)

M reader.ha
M reader.ha => reader.ha +33 -0
@@ 113,6 113,7 @@ export fn skip(ent: *entry) (void | io::error) = {

const file_vtable: io::vtable = io::vtable {
	reader = &file_read,
	seeker = &file_seek,
	...
};



@@ 154,6 155,38 @@ fn file_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
	return z;
};

fn file_seek(
	s: *io::stream,
	off: io::off,
	w: io::whence,
) (io::off | io::error) = {
	let ent = s: *ent_reader;
	assert(ent.vtable == &file_vtable);

	const orig = ent.orig: io::off;
	const cur = (ent.orig - ent.remain): io::off;
	let new = switch (w) {
	case io::whence::SET =>
		yield off;
	case io::whence::CUR =>
		yield cur + off;
	case io::whence::END =>
		yield orig + off;
	};

	if (new < 0) {
		new = 0;
	} else if (new > orig) {
		new = orig;
	};

	const rel = new - cur;
	io::seek(ent.src, rel, io::whence::CUR)?;

	ent.remain = (orig - new): size;
	return new;
};

fn readstr(rd: *bufio::memstream, ln: size) str = {
	const buf = match (bufio::borrowedread(rd, ln)) {
	case let buf: []u8 =>