~sircmpwn/hare-compress

bb5978bb65562e4fb889f0cf001fae822c3ae213 — Drew DeVault 1 year, 5 months ago 7130e45
compress::flate: introduce inflate_error

Extracts the inflate-specific error condition from an opaque error
condition in io::error.

Signed-off-by: Drew DeVault <sir@cmpwn.com>
1 files changed, 42 insertions(+), 16 deletions(-)

M compress/flate/inflate.ha
M compress/flate/inflate.ha => compress/flate/inflate.ha +42 -16
@@ 29,13 29,21 @@ export type huffman = struct {
	symbols: [MAXCODES]u16,
};

type inflate_err = enum u8 {
// List of inflate error conditions.
export type inflate_err = enum u8 {
	// Unexpected EOF
	EOF,
	// Invalid block type
	BTYPE,
	// Invalid block length
	LEN,
	// Invalid distance
	DISTANCE,
	// Invalid Huffman code
	CODE,
	// Oversubscribed Huffman code
	HUFFMAN,
	// Invalid dynamic Huffman code table
	TABLE,
};



@@ 250,21 258,23 @@ fn uncompressed_read(d: *decompressor) (void | io::EOF | io::error) = {

fn opaque_strerror(
	data: *errors::opaque_data
) const str = switch (*(data: *inflate_err)) {
case inflate_err::EOF =>
	yield "Unexpected EOF";
case inflate_err::BTYPE =>
	yield "Invalid block type";
case inflate_err::LEN =>
	yield "Invalid block length";
case inflate_err::DISTANCE =>
	yield "Invalid distance";
case inflate_err::CODE =>
	yield "Invalid Huffman code";
case inflate_err::HUFFMAN =>
	yield "Oversubscribed Huffman code";
case inflate_err::TABLE =>
	yield "Invalid dynamic Huffman code table";
) const str = {
	switch (*(data: *inflate_err)) {
	case inflate_err::EOF =>
		return "Unexpected EOF";
	case inflate_err::BTYPE =>
		return "Invalid block type";
	case inflate_err::LEN =>
		return "Invalid block length";
	case inflate_err::DISTANCE =>
		return "Invalid distance";
	case inflate_err::CODE =>
		return "Invalid Huffman code";
	case inflate_err::HUFFMAN =>
		return "Oversubscribed Huffman code";
	case inflate_err::TABLE =>
		return "Invalid dynamic Huffman code table";
	};
};

fn wraperror(err: inflate_err) errors::opaque = {


@@ 275,6 285,22 @@ fn wraperror(err: inflate_err) errors::opaque = {
	return wrapped;
};

// Returns the inflate-specific error for a given [[io::error]], assuming it was
// an inflate error that caused the issue. Otherwise, returns the original I/O
// error.
export fn inflate_error(err: io::error) (inflate_err | io::error) = {
	match (err) {
	case let op: errors::opaque =>
		if (op.strerror != &opaque_strerror) {
			return err;
		};
		const err = &op.data: *inflate_err;
		return *err;
	case let err: io::error =>
		return err;
	};
};

fn dynamic(d: *decompressor) (void | io::EOF | io::error) = {
	const hlit = bits(d, 5)? + 257;
	const hdist = bits(d, 5)? + 1;