1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
const std = @import("std");
const expect = std.testing.expect;
const JavascriptString = @import("ast/base.zig").JavascriptString;
usingnamespace @import("string_types.zig");
pub fn containsChar(self: string, char: u8) bool {
return std.mem(char) != null;
}
pub fn indexOfChar(self: string, char: u8) ?usize {
return std.mem.indexOfScalar(@TypeOf(char), self, char);
}
pub fn lastIndexOfChar(self: string, char: u8) ?usize {
return std.mem.lastIndexOfScalar(u8, self, char);
}
pub fn lastIndexOf(self: string, str: u8) ?usize {
return std.mem.lastIndexOf(u8, self, str);
}
pub fn indexOf(self: string, str: u8) ?usize {
return std.mem.indexOf(u8, self, str);
}
pub fn startsWith(self: string, str: string) bool {
if (str.len > self.len) {
return false;
}
var i: usize = 0;
while (i < str.len) {
if (str[i] != self[i]) {
return false;
}
i += 1;
}
return true;
}
pub fn endsWithAny(self: string, str: string) bool {
const end = self[self.len - 1];
for (str) |char| {
if (char == end) {
return true;
}
}
return false;
}
pub fn lastNonwhitespace(self: string, str: string) bool {}
pub fn endsWithAnyComptime(self: string, comptime str: string) bool {
if (str.len < 10) {
const last = self[self.len - 1];
inline while (str) |char| {
if (char == last) {
return true;
}
}
return false;
} else {
return endsWithAny(self, str);
}
}
pub fn eql(self: string, other: anytype) bool {
return std.mem.eql(u8, self, other);
}
pub fn append(allocator: *std.mem.Allocator, self: string, other: string) !string {
return std.fmt.allocPrint(allocator, "{s}{s}", .{ self, other });
}
pub fn index(self: string, str: string) i32 {
if (std.mem.indexOf(u8, self, str)) |i| {
return @intCast(i32, i);
} else {
return -1;
}
}
pub fn eqlUtf16(comptime self: string, other: JavascriptString) bool {
return std.mem.eql(u16, std.unicode.utf8ToUtf16LeStringLiteral(self), other);
}
pub fn toUTF16Buf(in: string, out: []u16) usize {
var utf8Iterator = std.unicode.Utf8Iterator{ .bytes = in, .i = 0 };
var c: u21 = 0;
var i: usize = 0;
while (utf8Iterator.nextCodepoint()) |code_point| {
switch (code_point) {
0...0xFFFF => {
out[i] = @intCast(u16, code_point);
i += 1;
},
else => {
c = code_point - 0x10000;
out[i] = @intCast(u16, 0xD800 + ((c >> 10) & 0x3FF));
i += 1;
out[i] = @intCast(u16, 0xDC00 + (c & 0x3FF));
i += 1;
},
}
}
return utf8Iterator.i;
}
pub fn toUTF16Alloc(in: string, allocator: *std.mem.Allocator) !JavascriptString {
var utf8Iterator = std.unicode.Utf8Iterator{ .bytes = in, .i = 0 };
var out = try std.ArrayList(u16).initCapacity(allocator, in.len);
var c: u21 = 0;
var i: usize = 0;
while (utf8Iterator.nextCodepoint()) |code_point| {
switch (code_point) {
0...0xFFFF => {
try out.append(@intCast(u16, code_point));
},
else => {
c = code_point - 0x10000;
try out.append(@intCast(u16, 0xD800 + ((c >> 10) & 0x3FF)));
try out.append(@intCast(u16, 0xDC00 + (c & 0x3FF)));
},
}
}
return out.toOwnedSlice();
}
pub fn containsNonBmpCodePoint(text: string) bool {
var iter = std.unicode.Utf8Iterator{ .bytes = text, .i = 0 };
while (iter.nextCodepoint()) |codepoint| {
if (codepoint > 0xFFFF) {
return true;
}
}
return false;
}
pub fn containsNonBmpCodePointUTF16(_text: JavascriptString) bool {
const n = _text.len;
if (n > 0) {
var i: usize = 0;
var c: u16 = 0;
var c2: u16 = 0;
var text = _text[0 .. n - 1];
while (i < n - 1) : (i += 1) {
c = text[i];
if (c >= 0xD800 and c <= 0xDBFF) {
c2 = text[i + 1];
if (c2 >= 0xDC00 and c2 <= 0xDFFF) {
return true;
}
}
}
}
return false;
}
|