summaryrefslogtreecommitdiff
path: root/src/Scripts.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Scripts.zig82
1 files changed, 18 insertions, 64 deletions
diff --git a/src/Scripts.zig b/src/Scripts.zig
index 719b01f..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,76 +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 in_bytes = @embedFile("scripts");
200 var in_fbs = std.io.fixedBufferStream(in_bytes);
201 var reader = in_fbs.reader();
202
203 const endian = builtin.cpu.arch.endian();
204
205 const s1_len: u16 = try reader.readInt(u16, endian);
206 scripts.s1 = try allocator.alloc(u16, s1_len);
207 errdefer allocator.free(scripts.s1);
208 for (0..s1_len) |i| scripts.s1[i] = try reader.readInt(u16, endian);
209
210 const s2_len: u16 = try reader.readInt(u16, endian);
211 scripts.s2 = try allocator.alloc(u8, s2_len);
212 errdefer allocator.free(scripts.s2);
213 _ = try reader.readAll(scripts.s2);
214
215 const s3_len: u16 = try reader.readInt(u8, endian);
216 scripts.s3 = try allocator.alloc(u8, s3_len);
217 errdefer allocator.free(scripts.s3);
218 _ = try reader.readAll(scripts.s3);
219}
220
221pub fn deinit(self: *const Scripts, allocator: mem.Allocator) void {
222 allocator.free(self.s1);
223 allocator.free(self.s2);
224 allocator.free(self.s3);
225}
226 191
227/// Lookup the Script type for `cp`. 192/// Lookup the Script type for `cp`.
228pub fn script(self: Scripts, cp: u21) ?Script { 193pub fn script(cp: u21) ?Script {
229 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)]];
230 if (byte == 0) return null; 195 if (byte == 0) return null;
231 return @enumFromInt(byte); 196 return @enumFromInt(byte);
232} 197}
233 198
234test "script" { 199test "script" {
235 const self = try init(std.testing.allocator); 200 try testing.expectEqual(Script.Latin, script('A').?);
236 defer self.deinit(std.testing.allocator); 201 // try testing.expectEqual(Script.Deseret, script('𐐌').?);
237 try testing.expectEqual(Script.Latin, self.script('A').?);
238}
239
240fn testAllocator(allocator: Allocator) !void {
241 var prop = try Scripts.init(allocator);
242 prop.deinit(allocator);
243}
244
245test "Allocation failure" {
246 try testing.checkAllAllocationFailures(testing.allocator, testAllocator, .{});
247} 202}
248 203
249const std = @import("std"); 204const std = @import("std");
250const builtin = @import("builtin"); 205const builtin = @import("builtin");
251const mem = std.mem; 206const unicode = std.unicode;
252const Allocator = mem.Allocator;
253const testing = std.testing; 207const testing = std.testing;