difftastic/vendor/tree-sitter-hare/example/adler32.ha

86 lines
2.0 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Implements the Adler-32 checksum algorithm. It is a non-cryptographic
// checksum.
use endian;
use hash;
use io;
use strings;
type state = struct {
hash: hash::hash,
a: u32,
b: u32,
};
// Creates a [hash::hash] which computes the Adler-32 checksum algorithm.
export fn adler32() *hash::hash = alloc(state {
hash = hash::hash {
stream = io::stream {
writer = &write,
closer = &close,
...
},
sum = &sum,
reset = &reset,
sz = 4,
},
a = 1,
b = 0,
}): *hash::hash;
fn close(s: *io::stream) void = free(s);
fn write(s: *io::stream, buf: const []u8) (size | io::error) = {
let s = s: *state;
for (let i = 0z; i < len(buf); i += 1) {
s.a = (s.a + buf[i]) % 65521;
s.b = (s.b + s.a) % 65521;
};
return len(buf);
};
fn reset(h: *hash::hash) void = {
let h = h: *state;
h.a = 1;
h.b = 0;
};
fn sum(h: *hash::hash) []u8 = {
let h = h: *state;
let buf: [4]u8 = [0...];
// RFC 1950 specifies that Adler-32 checksums are stored in network
// order.
endian::beputu32(buf, (h.b << 16) | h.a);
return alloc(buf);
};
export fn sum32(h: *hash::hash) u32 = {
assert(h.reset == &reset);
let h = h: *state;
return h.b << 16 | h.a;
};
@test fn adler32() void = {
const vectors: [](str, u32) = [
("", 1),
("hello world", 436929629),
("Hare is a cool language", 1578567727),
("'UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things' - Doug Gwyn", 2140876731),
("'Life is too short to run proprietary software' - Bdale Garbee", 3135706652),
("'The central enemy of reliability is complexity.' - Geer et al", 3170309588),
("'A language that doesnt have everything is actually easier to program in than some that do.' - Dennis Ritchie", 1148528899),
];
let hash = adler32();
defer hash::close(hash);
for (let i = 0z; i < len(vectors); i += 1) {
let vec = vectors[i];
hash::reset(hash);
hash::write(hash, strings::toutf8(vec.0));
let s = hash::sum(hash);
defer free(s);
assert(endian::begetu32(s) == vec.1);
assert(sum32(hash) == vec.1);
};
};