summaryrefslogtreecommitdiff
path: root/src/PropsData.zig
diff options
context:
space:
mode:
authorGravatar Jose Colon Rodriguez2024-03-28 10:06:00 -0400
committerGravatar Jose Colon Rodriguez2024-03-28 10:06:00 -0400
commit74be85ac145cc6de5d03348e07be8d982c2211cb (patch)
treeb3b5f2080235e5cf73d2be080fb70583567dfb2b /src/PropsData.zig
parentScriptsData and made all Datas const (diff)
downloadzg-74be85ac145cc6de5d03348e07be8d982c2211cb.tar.gz
zg-74be85ac145cc6de5d03348e07be8d982c2211cb.tar.xz
zg-74be85ac145cc6de5d03348e07be8d982c2211cb.zip
PropsData and errdefers for init fns
Diffstat (limited to 'src/PropsData.zig')
-rw-r--r--src/PropsData.zig123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/PropsData.zig b/src/PropsData.zig
new file mode 100644
index 0000000..252462e
--- /dev/null
+++ b/src/PropsData.zig
@@ -0,0 +1,123 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compress = std.compress;
4const mem = std.mem;
5const testing = std.testing;
6
7allocator: mem.Allocator,
8core_s1: []u16 = undefined,
9core_s2: []u8 = undefined,
10props_s1: []u16 = undefined,
11props_s2: []u8 = undefined,
12
13const Self = @This();
14
15pub fn init(allocator: mem.Allocator) !Self {
16 const decompressor = compress.deflate.decompressor;
17 const endian = builtin.cpu.arch.endian();
18
19 // Process DerivedCoreProperties.txt
20 const core_bytes = @embedFile("core_props");
21 var core_fbs = std.io.fixedBufferStream(core_bytes);
22 var core_decomp = try decompressor(allocator, core_fbs.reader(), null);
23 defer core_decomp.deinit();
24 var core_reader = core_decomp.reader();
25
26 var self = Self{ .allocator = allocator };
27
28 const core_stage_1_len: u16 = try core_reader.readInt(u16, endian);
29 self.core_s1 = try allocator.alloc(u16, core_stage_1_len);
30 errdefer allocator.free(self.core_s1);
31 for (0..core_stage_1_len) |i| self.core_s1[i] = try core_reader.readInt(u16, endian);
32
33 const core_stage_2_len: u16 = try core_reader.readInt(u16, endian);
34 self.core_s2 = try allocator.alloc(u8, core_stage_2_len);
35 errdefer allocator.free(self.core_s2);
36 _ = try core_reader.readAll(self.core_s2);
37
38 // Process PropList.txt
39 const props_bytes = @embedFile("props");
40 var props_fbs = std.io.fixedBufferStream(props_bytes);
41 var props_decomp = try decompressor(allocator, props_fbs.reader(), null);
42 defer props_decomp.deinit();
43 var props_reader = props_decomp.reader();
44
45 const stage_1_len: u16 = try props_reader.readInt(u16, endian);
46 self.props_s1 = try allocator.alloc(u16, stage_1_len);
47 errdefer allocator.free(self.props_s1);
48 for (0..stage_1_len) |i| self.props_s1[i] = try props_reader.readInt(u16, endian);
49
50 const stage_2_len: u16 = try props_reader.readInt(u16, endian);
51 self.props_s2 = try allocator.alloc(u8, stage_2_len);
52 errdefer allocator.free(self.props_s2);
53 _ = try props_reader.readAll(self.props_s2);
54
55 return self;
56}
57
58pub fn deinit(self: *const Self) void {
59 self.allocator.free(self.core_s1);
60 self.allocator.free(self.core_s2);
61 self.allocator.free(self.props_s1);
62 self.allocator.free(self.props_s2);
63}
64
65/// True if `cp` is a mathematical symbol.
66pub inline fn isMath(self: Self, cp: u21) bool {
67 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 1 == 1;
68}
69
70/// True if `cp` is an alphabetic character.
71pub inline fn isAlphabetic(self: Self, cp: u21) bool {
72 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 2 == 2;
73}
74
75/// True if `cp` is a valid identifier start character.
76pub inline fn isIdStart(self: Self, cp: u21) bool {
77 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 4 == 4;
78}
79
80/// True if `cp` is a valid identifier continuation character.
81pub inline fn isIdContinue(self: Self, cp: u21) bool {
82 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 8 == 8;
83}
84
85/// True if `cp` is a valid extended identifier start character.
86pub inline fn isXidStart(self: Self, cp: u21) bool {
87 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 16 == 16;
88}
89
90/// True if `cp` is a valid extended identifier continuation character.
91pub inline fn isXidContinue(self: Self, cp: u21) bool {
92 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 32 == 32;
93}
94
95/// True if `cp` is a whitespace character.
96pub inline fn isWhitespace(self: Self, cp: u21) bool {
97 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 1 == 1;
98}
99
100/// True if `cp` is a hexadecimal digit.
101pub inline fn isHexDigit(self: Self, cp: u21) bool {
102 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 2 == 2;
103}
104
105/// True if `cp` is a diacritic mark.
106pub inline fn isDiacritic(self: Self, cp: u21) bool {
107 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 4 == 4;
108}
109
110test "Props" {
111 const self = try init(testing.allocator);
112 defer self.deinit();
113
114 try testing.expect(self.isHexDigit('F'));
115 try testing.expect(self.isHexDigit('a'));
116 try testing.expect(self.isHexDigit('8'));
117 try testing.expect(!self.isHexDigit('z'));
118
119 try testing.expect(self.isDiacritic('\u{301}'));
120 try testing.expect(self.isAlphabetic('A'));
121 try testing.expect(!self.isAlphabetic('3'));
122 try testing.expect(self.isMath('+'));
123}