summaryrefslogtreecommitdiff
path: root/src/Scripts.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Scripts.zig')
-rw-r--r--src/Scripts.zig85
1 files changed, 18 insertions, 67 deletions
diff --git a/src/Scripts.zig b/src/Scripts.zig
index 3bc90bc..4938318 100644
--- a/src/Scripts.zig
+++ b/src/Scripts.zig
@@ -1,8 +1,18 @@
1//! Scripts Module 1//! Scripts Module
2const Data = struct {
3 s1: []const u16 = undefined,
4 s2: []const u8 = undefined,
5 s3: []const u8 = undefined,
6};
2 7
3s1: []u16 = undefined, 8const scripts = scripts: {
4s2: []u8 = undefined, 9 const data = @import("script");
5s3: []u8 = undefined, 10 break :scripts Data{
11 .s1 = &data.s1,
12 .s2 = &data.s2,
13 .s3 = &data.s3,
14 };
15};
6 16
7/// Scripts enum 17/// Scripts enum
8pub const Script = enum { 18pub const Script = enum {
@@ -178,79 +188,20 @@ pub const Script = enum {
178 Yi, 188 Yi,
179 Zanabazar_Square, 189 Zanabazar_Square,
180}; 190};
181const Scripts = @This();
182
183pub fn init(allocator: Allocator) Allocator.Error!Scripts {
184 var scripts = Scripts{};
185 try scripts.setup(allocator);
186 return scripts;
187}
188
189pub fn setup(scripts: *Scripts, allocator: Allocator) Allocator.Error!void {
190 scripts.setupInner(allocator) catch |err| {
191 switch (err) {
192 error.OutOfMemory => |e| return e,
193 else => unreachable,
194 }
195 };
196}
197
198inline fn setupInner(scripts: *Scripts, allocator: mem.Allocator) !void {
199 const decompressor = compress.flate.inflate.decompressor;
200 const in_bytes = @embedFile("scripts");
201 var in_fbs = std.io.fixedBufferStream(in_bytes);
202 var in_decomp = decompressor(.raw, in_fbs.reader());
203 var reader = in_decomp.reader();
204
205 const endian = builtin.cpu.arch.endian();
206
207 const s1_len: u16 = try reader.readInt(u16, endian);
208 scripts.s1 = try allocator.alloc(u16, s1_len);
209 errdefer allocator.free(scripts.s1);
210 for (0..s1_len) |i| scripts.s1[i] = try reader.readInt(u16, endian);
211
212 const s2_len: u16 = try reader.readInt(u16, endian);
213 scripts.s2 = try allocator.alloc(u8, s2_len);
214 errdefer allocator.free(scripts.s2);
215 _ = try reader.readAll(scripts.s2);
216
217 const s3_len: u16 = try reader.readInt(u8, endian);
218 scripts.s3 = try allocator.alloc(u8, s3_len);
219 errdefer allocator.free(scripts.s3);
220 _ = try reader.readAll(scripts.s3);
221}
222
223pub fn deinit(self: *const Scripts, allocator: mem.Allocator) void {
224 allocator.free(self.s1);
225 allocator.free(self.s2);
226 allocator.free(self.s3);
227}
228 191
229/// Lookup the Script type for `cp`. 192/// Lookup the Script type for `cp`.
230pub fn script(self: Scripts, cp: u21) ?Script { 193pub fn script(cp: u21) ?Script {
231 const byte = self.s3[self.s2[self.s1[cp >> 8] + (cp & 0xff)]]; 194 const byte = scripts.s3[scripts.s2[scripts.s1[cp >> 8] + (cp & 0xff)]];
232 if (byte == 0) return null; 195 if (byte == 0) return null;
233 return @enumFromInt(byte); 196 return @enumFromInt(byte);
234} 197}
235 198
236test "script" { 199test "script" {
237 const self = try init(std.testing.allocator); 200 try testing.expectEqual(Script.Latin, script('A').?);
238 defer self.deinit(std.testing.allocator); 201 // try testing.expectEqual(Script.Deseret, script('𐐌').?);
239 try testing.expectEqual(Script.Latin, self.script('A').?);
240}
241
242fn testAllocator(allocator: Allocator) !void {
243 var prop = try Scripts.init(allocator);
244 prop.deinit(allocator);
245}
246
247test "Allocation failure" {
248 try testing.checkAllAllocationFailures(testing.allocator, testAllocator, .{});
249} 202}
250 203
251const std = @import("std"); 204const std = @import("std");
252const builtin = @import("builtin"); 205const builtin = @import("builtin");
253const compress = std.compress; 206const unicode = std.unicode;
254const mem = std.mem;
255const Allocator = mem.Allocator;
256const testing = std.testing; 207const testing = std.testing;