~sircmpwn/hare-tar

565d2a246c99644a5576718349496829da6d5cd3 — Ember Sawady 1 year, 13 days ago d1120d0
format::tar: make use of io::readall

Signed-off-by: Ember Sawady <ecs@d2evs.net>
2 files changed, 6 insertions(+), 34 deletions(-)

M reader.ha
M types.ha
M reader.ha => reader.ha +5 -28
@@ 32,26 32,12 @@ export fn read(src: io::handle) reader = {
// Note that reading from the header will modify the file size.
export fn next(rd: *reader) (entry | error | io::EOF) = {
	static let buf: [BLOCKSZ]u8 = [0...];
	match (io::read(rd.src, buf)?) {
	case let z: size =>
		if (z != len(buf)) {
			return truncated;
		};
	case io::EOF =>
		return truncated;
	};
	io::readall(rd.src, buf)?;

	if (zeroed(buf)) {
		match (io::read(rd.src, buf)?) {
		case let z: size =>
			if (z != len(buf)) {
				return truncated;
			};
		case io::EOF =>
			return truncated;
		};
		io::readall(rd.src, buf)?;
		if (!zeroed(buf)) {
			return truncated;
			return invalid;
		};
		return io::EOF;
	};


@@ 148,18 134,9 @@ fn file_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
	ent.remain -= z;

	// Read until we reach the block size
	static let buf: [BLOCKSZ]u8 = [0...];
	if (ent.remain == 0 && ent.orig % BLOCKSZ != 0) {
		let remain = BLOCKSZ - (ent.orig % BLOCKSZ);
		for (remain > 0) {
			match (io::read(ent.src, buf[..remain])?) {
			case let z: size =>
				remain -= z;
			case io::EOF =>
				// TODO: Set a truncated flag or something
				break;
			};
		};
		static let buf: [BLOCKSZ]u8 = [0...];
		io::readall(ent.src, buf[..BLOCKSZ - (ent.orig % BLOCKSZ)])?;
	};

	return z;

M types.ha => types.ha +1 -6
@@ 43,20 43,15 @@ export type entry_type = enum u8 {
	FIFO,
};

// Returned if the source file size is not aligned on [[BLOCKSZ]].
export type truncated = !void;

// Returned if the source file does not contain a valid ustar archive.
export type invalid = !void;

// Tagged union of all possible error types.
export type error = !(truncated | invalid | io::error);
export type error = !(invalid | io::error);

// Converts an [[error]] to a human-friendly representation.
export fn strerror(err: error) const str = {
	match (err) {
	case truncated =>
		return "Tar file is truncated";
	case invalid =>
		return "Tar file is invalid";
	case let err: io::error =>