summaryrefslogtreecommitdiff
path: root/src/Scripts.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Scripts.zig')
-rw-r--r--src/Scripts.zig66
1 files changed, 40 insertions, 26 deletions
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 @@
1const std = @import("std"); 1//! Scripts Module
2const builtin = @import("builtin"); 2
3const compress = std.compress; 3s1: []u16 = undefined,
4const mem = std.mem; 4s2: []u8 = undefined,
5const testing = std.testing; 5s3: []u8 = undefined,
6 6
7/// Scripts 7/// Scripts enum
8pub const Script = enum { 8pub const Script = enum {
9 none, 9 none,
10 Adlam, 10 Adlam,
@@ -172,13 +172,24 @@ pub const Script = enum {
172 Zanabazar_Square, 172 Zanabazar_Square,
173}; 173};
174 174
175s1: []u16 = undefined, 175const Scripts = @This();
176s2: []u8 = undefined,
177s3: []u8 = undefined,
178 176
179const Self = @This(); 177pub fn init(allocator: Allocator) Allocator.Error!Scripts {
178 var scripts = Scripts{};
179 try scripts.setup(allocator);
180 return scripts;
181}
182
183pub fn setup(scripts: *Scripts, allocator: Allocator) Allocator.Error!void {
184 scripts.setupInner(allocator) catch |err| {
185 switch (err) {
186 error.OutOfMemory => |e| return e,
187 else => unreachable,
188 }
189 };
190}
180 191
181pub fn init(allocator: mem.Allocator) !Self { 192inline fn setupInner(scripts: *Scripts, allocator: mem.Allocator) !void {
182 const decompressor = compress.flate.inflate.decompressor; 193 const decompressor = compress.flate.inflate.decompressor;
183 const in_bytes = @embedFile("scripts"); 194 const in_bytes = @embedFile("scripts");
184 var in_fbs = std.io.fixedBufferStream(in_bytes); 195 var in_fbs = std.io.fixedBufferStream(in_bytes);
@@ -187,34 +198,30 @@ pub fn init(allocator: mem.Allocator) !Self {
187 198
188 const endian = builtin.cpu.arch.endian(); 199 const endian = builtin.cpu.arch.endian();
189 200
190 var self = Self{};
191
192 const s1_len: u16 = try reader.readInt(u16, endian); 201 const s1_len: u16 = try reader.readInt(u16, endian);
193 self.s1 = try allocator.alloc(u16, s1_len); 202 scripts.s1 = try allocator.alloc(u16, s1_len);
194 errdefer allocator.free(self.s1); 203 errdefer allocator.free(scripts.s1);
195 for (0..s1_len) |i| self.s1[i] = try reader.readInt(u16, endian); 204 for (0..s1_len) |i| scripts.s1[i] = try reader.readInt(u16, endian);
196 205
197 const s2_len: u16 = try reader.readInt(u16, endian); 206 const s2_len: u16 = try reader.readInt(u16, endian);
198 self.s2 = try allocator.alloc(u8, s2_len); 207 scripts.s2 = try allocator.alloc(u8, s2_len);
199 errdefer allocator.free(self.s2); 208 errdefer allocator.free(scripts.s2);
200 _ = try reader.readAll(self.s2); 209 _ = try reader.readAll(scripts.s2);
201 210
202 const s3_len: u16 = try reader.readInt(u8, endian); 211 const s3_len: u16 = try reader.readInt(u8, endian);
203 self.s3 = try allocator.alloc(u8, s3_len); 212 scripts.s3 = try allocator.alloc(u8, s3_len);
204 errdefer allocator.free(self.s3); 213 errdefer allocator.free(scripts.s3);
205 _ = try reader.readAll(self.s3); 214 _ = try reader.readAll(scripts.s3);
206
207 return self;
208} 215}
209 216
210pub fn deinit(self: *const Self, allocator: mem.Allocator) void { 217pub fn deinit(self: *const Scripts, allocator: mem.Allocator) void {
211 allocator.free(self.s1); 218 allocator.free(self.s1);
212 allocator.free(self.s2); 219 allocator.free(self.s2);
213 allocator.free(self.s3); 220 allocator.free(self.s3);
214} 221}
215 222
216/// Lookup the Script type for `cp`. 223/// Lookup the Script type for `cp`.
217pub fn script(self: Self, cp: u21) ?Script { 224pub fn script(self: Scripts, cp: u21) ?Script {
218 const byte = self.s3[self.s2[self.s1[cp >> 8] + (cp & 0xff)]]; 225 const byte = self.s3[self.s2[self.s1[cp >> 8] + (cp & 0xff)]];
219 if (byte == 0) return null; 226 if (byte == 0) return null;
220 return @enumFromInt(byte); 227 return @enumFromInt(byte);
@@ -225,3 +232,10 @@ test "script" {
225 defer self.deinit(std.testing.allocator); 232 defer self.deinit(std.testing.allocator);
226 try testing.expectEqual(Script.Latin, self.script('A').?); 233 try testing.expectEqual(Script.Latin, self.script('A').?);
227} 234}
235
236const std = @import("std");
237const builtin = @import("builtin");
238const compress = std.compress;
239const mem = std.mem;
240const Allocator = mem.Allocator;
241const testing = std.testing;