|
const std = @import("../../../std.zig"); const math = std.math; const mem = std.mem; const Allocator = std.mem.Allocator; const ArrayListUnmanaged = std.ArrayListUnmanaged; |
LzAccumBufferAn accumulating buffer for LZ sequences |
pub const LzAccumBuffer = struct { buf: ArrayListUnmanaged(u8), memlimit: usize, len: usize, const Self = @This(); |
init()Buffer Buffer memory limit Total number of bytes sent through the buffer |
pub fn init(memlimit: usize) Self { return Self{ .buf = .{}, .memlimit = memlimit, .len = 0, }; } |
appendByte() |
pub fn appendByte(self: *Self, allocator: Allocator, byte: u8) !void { try self.buf.append(allocator, byte); self.len += 1; } |
reset()Reset the internal dictionary |
pub fn reset(self: *Self, writer: anytype) !void { try writer.writeAll(self.buf.items); self.buf.clearRetainingCapacity(); self.len = 0; } |
lastOr()Retrieve the last byte or return a default |
pub fn lastOr(self: Self, lit: u8) u8 { const buf_len = self.buf.items.len; return if (buf_len == 0) lit else self.buf.items[buf_len - 1]; } |
lastN()Retrieve the n-th last byte |
pub fn lastN(self: Self, dist: usize) !u8 { const buf_len = self.buf.items.len; if (dist > buf_len) { return error.CorruptInput; } return self.buf.items[buf_len - dist]; } |
appendLiteral()Append a literal |
pub fn appendLiteral( self: *Self, allocator: Allocator, lit: u8, writer: anytype, ) !void { _ = writer; if (self.len >= self.memlimit) { return error.CorruptInput; } try self.buf.append(allocator, lit); self.len += 1; } |
appendLz()Fetch an LZ sequence (length, distance) from inside the buffer |
pub fn appendLz( self: *Self, allocator: Allocator, len: usize, dist: usize, writer: anytype, ) !void { _ = writer; const buf_len = self.buf.items.len; if (dist > buf_len) { return error.CorruptInput; } var offset = buf_len - dist; var i: usize = 0; while (i < len) : (i += 1) { const x = self.buf.items[offset]; try self.buf.append(allocator, x); offset += 1; } self.len += len; } |
finish() |
pub fn finish(self: *Self, writer: anytype) !void { try writer.writeAll(self.buf.items); self.buf.clearRetainingCapacity(); } |
deinit() |
pub fn deinit(self: *Self, allocator: Allocator) void { self.buf.deinit(allocator); self.* = undefined; } }; |
LzCircularBufferA circular buffer for LZ sequences |
pub const LzCircularBuffer = struct { buf: ArrayListUnmanaged(u8), dict_size: usize, memlimit: usize, cursor: usize, len: usize, const Self = @This(); |
init()Circular buffer Length of the buffer Buffer memory limit Current position Total number of bytes sent through the buffer |
pub fn init(dict_size: usize, memlimit: usize) Self { return Self{ .buf = .{}, .dict_size = dict_size, .memlimit = memlimit, .cursor = 0, .len = 0, }; } |
get() |
pub fn get(self: Self, index: usize) u8 { return if (0 <= index and index < self.buf.items.len) self.buf.items[index] else 0; } |
set() |
pub fn set(self: *Self, allocator: Allocator, index: usize, value: u8) !void { if (index >= self.memlimit) { return error.CorruptInput; } try self.buf.ensureTotalCapacity(allocator, index + 1); while (self.buf.items.len < index) { self.buf.appendAssumeCapacity(0); } self.buf.appendAssumeCapacity(value); } |
lastOr()Retrieve the last byte or return a default |
pub fn lastOr(self: Self, lit: u8) u8 { return if (self.len == 0) lit else self.get((self.dict_size + self.cursor - 1) % self.dict_size); } |
lastN()Retrieve the n-th last byte |
pub fn lastN(self: Self, dist: usize) !u8 { if (dist > self.dict_size or dist > self.len) { return error.CorruptInput; } const offset = (self.dict_size + self.cursor - dist) % self.dict_size; return self.get(offset); } |
appendLiteral()Append a literal |
pub fn appendLiteral( self: *Self, allocator: Allocator, lit: u8, writer: anytype, ) !void { try self.set(allocator, self.cursor, lit); self.cursor += 1; self.len += 1; // Flush the circular buffer to the output if (self.cursor == self.dict_size) { try writer.writeAll(self.buf.items); self.cursor = 0; } } |
appendLz()Fetch an LZ sequence (length, distance) from inside the buffer |
pub fn appendLz( self: *Self, allocator: Allocator, len: usize, dist: usize, writer: anytype, ) !void { if (dist > self.dict_size or dist > self.len) { return error.CorruptInput; } var offset = (self.dict_size + self.cursor - dist) % self.dict_size; var i: usize = 0; while (i < len) : (i += 1) { const x = self.get(offset); try self.appendLiteral(allocator, x, writer); offset += 1; if (offset == self.dict_size) { offset = 0; } } } |
finish() |
pub fn finish(self: *Self, writer: anytype) !void { if (self.cursor > 0) { try writer.writeAll(self.buf.items[0..self.cursor]); self.cursor = 0; } } |
deinit() |
pub fn deinit(self: *Self, allocator: Allocator) void { self.buf.deinit(allocator); self.* = undefined; } }; |
Generated by zstd-browse2 on 2023-11-04 14:12:30 -0400. |