summaryrefslogtreecommitdiff
path: root/src/Properties.zig
diff options
context:
space:
mode:
authorGravatar Sam Atman2025-04-30 16:48:07 -0400
committerGravatar Sam Atman2025-04-30 16:48:07 -0400
commitd2d42bf3ef5490f6fdec73508c2493a666ecee41 (patch)
tree377794be59ece4118ca2449b705b8e7cc646abc0 /src/Properties.zig
parentUpdate README.md to new API (diff)
downloadzg-d2d42bf3ef5490f6fdec73508c2493a666ecee41.tar.gz
zg-d2d42bf3ef5490f6fdec73508c2493a666ecee41.tar.xz
zg-d2d42bf3ef5490f6fdec73508c2493a666ecee41.zip
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.
Diffstat (limited to 'src/Properties.zig')
-rw-r--r--src/Properties.zig98
1 files changed, 56 insertions, 42 deletions
diff --git a/src/Properties.zig b/src/Properties.zig
index 46920be..f7e57ec 100644
--- a/src/Properties.zig
+++ b/src/Properties.zig
@@ -1,8 +1,4 @@
1const std = @import("std"); 1//! Properties module
2const builtin = @import("builtin");
3const compress = std.compress;
4const mem = std.mem;
5const testing = std.testing;
6 2
7core_s1: []u16 = undefined, 3core_s1: []u16 = undefined,
8core_s2: []u8 = undefined, 4core_s2: []u8 = undefined,
@@ -11,9 +7,24 @@ props_s2: []u8 = undefined,
11num_s1: []u16 = undefined, 7num_s1: []u16 = undefined,
12num_s2: []u8 = undefined, 8num_s2: []u8 = undefined,
13 9
14const Self = @This(); 10const Properties = @This();
11
12pub fn init(allocator: Allocator) Allocator.Error!Properties {
13 var props = Properties{};
14 try props.setup(allocator);
15 return props;
16}
17
18pub fn setup(props: *Properties, allocator: Allocator) Allocator.Error!void {
19 props.setupInner(allocator) catch |err| {
20 switch (err) {
21 error.OutOfMemory => |e| return e,
22 else => unreachable,
23 }
24 };
25}
15 26
16pub fn init(allocator: mem.Allocator) !Self { 27inline fn setupInner(props: *Properties, allocator: Allocator) !void {
17 const decompressor = compress.flate.inflate.decompressor; 28 const decompressor = compress.flate.inflate.decompressor;
18 const endian = builtin.cpu.arch.endian(); 29 const endian = builtin.cpu.arch.endian();
19 30
@@ -23,17 +34,15 @@ pub fn init(allocator: mem.Allocator) !Self {
23 var core_decomp = decompressor(.raw, core_fbs.reader()); 34 var core_decomp = decompressor(.raw, core_fbs.reader());
24 var core_reader = core_decomp.reader(); 35 var core_reader = core_decomp.reader();
25 36
26 var self = Self{};
27
28 const core_stage_1_len: u16 = try core_reader.readInt(u16, endian); 37 const core_stage_1_len: u16 = try core_reader.readInt(u16, endian);
29 self.core_s1 = try allocator.alloc(u16, core_stage_1_len); 38 props.core_s1 = try allocator.alloc(u16, core_stage_1_len);
30 errdefer allocator.free(self.core_s1); 39 errdefer allocator.free(props.core_s1);
31 for (0..core_stage_1_len) |i| self.core_s1[i] = try core_reader.readInt(u16, endian); 40 for (0..core_stage_1_len) |i| props.core_s1[i] = try core_reader.readInt(u16, endian);
32 41
33 const core_stage_2_len: u16 = try core_reader.readInt(u16, endian); 42 const core_stage_2_len: u16 = try core_reader.readInt(u16, endian);
34 self.core_s2 = try allocator.alloc(u8, core_stage_2_len); 43 props.core_s2 = try allocator.alloc(u8, core_stage_2_len);
35 errdefer allocator.free(self.core_s2); 44 errdefer allocator.free(props.core_s2);
36 _ = try core_reader.readAll(self.core_s2); 45 _ = try core_reader.readAll(props.core_s2);
37 46
38 // Process PropList.txt 47 // Process PropList.txt
39 const props_bytes = @embedFile("props"); 48 const props_bytes = @embedFile("props");
@@ -42,14 +51,14 @@ pub fn init(allocator: mem.Allocator) !Self {
42 var props_reader = props_decomp.reader(); 51 var props_reader = props_decomp.reader();
43 52
44 const stage_1_len: u16 = try props_reader.readInt(u16, endian); 53 const stage_1_len: u16 = try props_reader.readInt(u16, endian);
45 self.props_s1 = try allocator.alloc(u16, stage_1_len); 54 props.props_s1 = try allocator.alloc(u16, stage_1_len);
46 errdefer allocator.free(self.props_s1); 55 errdefer allocator.free(props.props_s1);
47 for (0..stage_1_len) |i| self.props_s1[i] = try props_reader.readInt(u16, endian); 56 for (0..stage_1_len) |i| props.props_s1[i] = try props_reader.readInt(u16, endian);
48 57
49 const stage_2_len: u16 = try props_reader.readInt(u16, endian); 58 const stage_2_len: u16 = try props_reader.readInt(u16, endian);
50 self.props_s2 = try allocator.alloc(u8, stage_2_len); 59 props.props_s2 = try allocator.alloc(u8, stage_2_len);
51 errdefer allocator.free(self.props_s2); 60 errdefer allocator.free(props.props_s2);
52 _ = try props_reader.readAll(self.props_s2); 61 _ = try props_reader.readAll(props.props_s2);
53 62
54 // Process DerivedNumericType.txt 63 // Process DerivedNumericType.txt
55 const num_bytes = @embedFile("numeric"); 64 const num_bytes = @embedFile("numeric");
@@ -58,19 +67,17 @@ pub fn init(allocator: mem.Allocator) !Self {
58 var num_reader = num_decomp.reader(); 67 var num_reader = num_decomp.reader();
59 68
60 const num_stage_1_len: u16 = try num_reader.readInt(u16, endian); 69 const num_stage_1_len: u16 = try num_reader.readInt(u16, endian);
61 self.num_s1 = try allocator.alloc(u16, num_stage_1_len); 70 props.num_s1 = try allocator.alloc(u16, num_stage_1_len);
62 errdefer allocator.free(self.num_s1); 71 errdefer allocator.free(props.num_s1);
63 for (0..num_stage_1_len) |i| self.num_s1[i] = try num_reader.readInt(u16, endian); 72 for (0..num_stage_1_len) |i| props.num_s1[i] = try num_reader.readInt(u16, endian);
64 73
65 const num_stage_2_len: u16 = try num_reader.readInt(u16, endian); 74 const num_stage_2_len: u16 = try num_reader.readInt(u16, endian);
66 self.num_s2 = try allocator.alloc(u8, num_stage_2_len); 75 props.num_s2 = try allocator.alloc(u8, num_stage_2_len);
67 errdefer allocator.free(self.num_s2); 76 errdefer allocator.free(props.num_s2);
68 _ = try num_reader.readAll(self.num_s2); 77 _ = try num_reader.readAll(props.num_s2);
69
70 return self;
71} 78}
72 79
73pub fn deinit(self: *const Self, allocator: mem.Allocator) void { 80pub fn deinit(self: *const Properties, allocator: Allocator) void {
74 allocator.free(self.core_s1); 81 allocator.free(self.core_s1);
75 allocator.free(self.core_s2); 82 allocator.free(self.core_s2);
76 allocator.free(self.props_s1); 83 allocator.free(self.props_s1);
@@ -80,62 +87,62 @@ pub fn deinit(self: *const Self, allocator: mem.Allocator) void {
80} 87}
81 88
82/// True if `cp` is a mathematical symbol. 89/// True if `cp` is a mathematical symbol.
83pub fn isMath(self: Self, cp: u21) bool { 90pub fn isMath(self: Properties, cp: u21) bool {
84 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 1 == 1; 91 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 1 == 1;
85} 92}
86 93
87/// True if `cp` is an alphabetic character. 94/// True if `cp` is an alphabetic character.
88pub fn isAlphabetic(self: Self, cp: u21) bool { 95pub fn isAlphabetic(self: Properties, cp: u21) bool {
89 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 2 == 2; 96 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 2 == 2;
90} 97}
91 98
92/// True if `cp` is a valid identifier start character. 99/// True if `cp` is a valid identifier start character.
93pub fn isIdStart(self: Self, cp: u21) bool { 100pub fn isIdStart(self: Properties, cp: u21) bool {
94 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 4 == 4; 101 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 4 == 4;
95} 102}
96 103
97/// True if `cp` is a valid identifier continuation character. 104/// True if `cp` is a valid identifier continuation character.
98pub fn isIdContinue(self: Self, cp: u21) bool { 105pub fn isIdContinue(self: Properties, cp: u21) bool {
99 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 8 == 8; 106 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 8 == 8;
100} 107}
101 108
102/// True if `cp` is a valid extended identifier start character. 109/// True if `cp` is a valid extended identifier start character.
103pub fn isXidStart(self: Self, cp: u21) bool { 110pub fn isXidStart(self: Properties, cp: u21) bool {
104 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 16 == 16; 111 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 16 == 16;
105} 112}
106 113
107/// True if `cp` is a valid extended identifier continuation character. 114/// True if `cp` is a valid extended identifier continuation character.
108pub fn isXidContinue(self: Self, cp: u21) bool { 115pub fn isXidContinue(self: Properties, cp: u21) bool {
109 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 32 == 32; 116 return self.core_s2[self.core_s1[cp >> 8] + (cp & 0xff)] & 32 == 32;
110} 117}
111 118
112/// True if `cp` is a whitespace character. 119/// True if `cp` is a whitespace character.
113pub fn isWhitespace(self: Self, cp: u21) bool { 120pub fn isWhitespace(self: Properties, cp: u21) bool {
114 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 1 == 1; 121 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 1 == 1;
115} 122}
116 123
117/// True if `cp` is a hexadecimal digit. 124/// True if `cp` is a hexadecimal digit.
118pub fn isHexDigit(self: Self, cp: u21) bool { 125pub fn isHexDigit(self: Properties, cp: u21) bool {
119 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 2 == 2; 126 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 2 == 2;
120} 127}
121 128
122/// True if `cp` is a diacritic mark. 129/// True if `cp` is a diacritic mark.
123pub fn isDiacritic(self: Self, cp: u21) bool { 130pub fn isDiacritic(self: Properties, cp: u21) bool {
124 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 4 == 4; 131 return self.props_s2[self.props_s1[cp >> 8] + (cp & 0xff)] & 4 == 4;
125} 132}
126 133
127/// True if `cp` is numeric. 134/// True if `cp` is numeric.
128pub fn isNumeric(self: Self, cp: u21) bool { 135pub fn isNumeric(self: Properties, cp: u21) bool {
129 return self.num_s2[self.num_s1[cp >> 8] + (cp & 0xff)] & 1 == 1; 136 return self.num_s2[self.num_s1[cp >> 8] + (cp & 0xff)] & 1 == 1;
130} 137}
131 138
132/// True if `cp` is a digit. 139/// True if `cp` is a digit.
133pub fn isDigit(self: Self, cp: u21) bool { 140pub fn isDigit(self: Properties, cp: u21) bool {
134 return self.num_s2[self.num_s1[cp >> 8] + (cp & 0xff)] & 2 == 2; 141 return self.num_s2[self.num_s1[cp >> 8] + (cp & 0xff)] & 2 == 2;
135} 142}
136 143
137/// True if `cp` is decimal. 144/// True if `cp` is decimal.
138pub fn isDecimal(self: Self, cp: u21) bool { 145pub fn isDecimal(self: Properties, cp: u21) bool {
139 return self.num_s2[self.num_s1[cp >> 8] + (cp & 0xff)] & 4 == 4; 146 return self.num_s2[self.num_s1[cp >> 8] + (cp & 0xff)] & 4 == 4;
140} 147}
141 148
@@ -161,3 +168,10 @@ test "Props" {
161 try testing.expect(!self.isDigit('2')); 168 try testing.expect(!self.isDigit('2'));
162 try testing.expect(!self.isDecimal('g')); 169 try testing.expect(!self.isDecimal('g'));
163} 170}
171
172const std = @import("std");
173const builtin = @import("builtin");
174const compress = std.compress;
175const mem = std.mem;
176const Allocator = mem.Allocator;
177const testing = std.testing;