From d2d42bf3ef5490f6fdec73508c2493a666ecee41 Mon Sep 17 00:00:00 2001 From: Sam Atman Date: Wed, 30 Apr 2025 16:48:07 -0400 Subject: Setup variants for all allocating modules This harmonizes the allocating modules in a couple of ways. All can now be constructed by pointer, and all treat various miscellaneous read failures as `unreachable`, which indeed they should be. The README has been updated to inform users of this option. --- src/Scripts.zig | 66 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 26 deletions(-) (limited to 'src/Scripts.zig') diff --git a/src/Scripts.zig b/src/Scripts.zig index 4ad8549..f71a2b5 100644 --- a/src/Scripts.zig +++ b/src/Scripts.zig @@ -1,10 +1,10 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compress = std.compress; -const mem = std.mem; -const testing = std.testing; +//! Scripts Module + +s1: []u16 = undefined, +s2: []u8 = undefined, +s3: []u8 = undefined, -/// Scripts +/// Scripts enum pub const Script = enum { none, Adlam, @@ -172,13 +172,24 @@ pub const Script = enum { Zanabazar_Square, }; -s1: []u16 = undefined, -s2: []u8 = undefined, -s3: []u8 = undefined, +const Scripts = @This(); -const Self = @This(); +pub fn init(allocator: Allocator) Allocator.Error!Scripts { + var scripts = Scripts{}; + try scripts.setup(allocator); + return scripts; +} + +pub fn setup(scripts: *Scripts, allocator: Allocator) Allocator.Error!void { + scripts.setupInner(allocator) catch |err| { + switch (err) { + error.OutOfMemory => |e| return e, + else => unreachable, + } + }; +} -pub fn init(allocator: mem.Allocator) !Self { +inline fn setupInner(scripts: *Scripts, allocator: mem.Allocator) !void { const decompressor = compress.flate.inflate.decompressor; const in_bytes = @embedFile("scripts"); var in_fbs = std.io.fixedBufferStream(in_bytes); @@ -187,34 +198,30 @@ pub fn init(allocator: mem.Allocator) !Self { const endian = builtin.cpu.arch.endian(); - var self = Self{}; - const s1_len: u16 = try reader.readInt(u16, endian); - self.s1 = try allocator.alloc(u16, s1_len); - errdefer allocator.free(self.s1); - for (0..s1_len) |i| self.s1[i] = try reader.readInt(u16, endian); + scripts.s1 = try allocator.alloc(u16, s1_len); + errdefer allocator.free(scripts.s1); + for (0..s1_len) |i| scripts.s1[i] = try reader.readInt(u16, endian); const s2_len: u16 = try reader.readInt(u16, endian); - self.s2 = try allocator.alloc(u8, s2_len); - errdefer allocator.free(self.s2); - _ = try reader.readAll(self.s2); + scripts.s2 = try allocator.alloc(u8, s2_len); + errdefer allocator.free(scripts.s2); + _ = try reader.readAll(scripts.s2); const s3_len: u16 = try reader.readInt(u8, endian); - self.s3 = try allocator.alloc(u8, s3_len); - errdefer allocator.free(self.s3); - _ = try reader.readAll(self.s3); - - return self; + scripts.s3 = try allocator.alloc(u8, s3_len); + errdefer allocator.free(scripts.s3); + _ = try reader.readAll(scripts.s3); } -pub fn deinit(self: *const Self, allocator: mem.Allocator) void { +pub fn deinit(self: *const Scripts, allocator: mem.Allocator) void { allocator.free(self.s1); allocator.free(self.s2); allocator.free(self.s3); } /// Lookup the Script type for `cp`. -pub fn script(self: Self, cp: u21) ?Script { +pub fn script(self: Scripts, cp: u21) ?Script { const byte = self.s3[self.s2[self.s1[cp >> 8] + (cp & 0xff)]]; if (byte == 0) return null; return @enumFromInt(byte); @@ -225,3 +232,10 @@ test "script" { defer self.deinit(std.testing.allocator); try testing.expectEqual(Script.Latin, self.script('A').?); } + +const std = @import("std"); +const builtin = @import("builtin"); +const compress = std.compress; +const mem = std.mem; +const Allocator = mem.Allocator; +const testing = std.testing; -- cgit v1.2.3