Function eqlIgnoreCaseWtf8 [src]
Compares two WTF-8 strings using the equivalent functionality of
RtlEqualUnicodeString (with case insensitive comparison enabled).
This function can be called on any target.
Assumes a and b are valid WTF-8.
Prototype
pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool
Parameters
a: []const u8
b: []const u8
Source
pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool {
// A length equality check is not possible here because there are
// some codepoints that have a different length uppercase UTF-8 representations
// than their lowercase counterparts, e.g. U+0250 (2 bytes) <-> U+2C6F (3 bytes).
// There are 7 such codepoints in the uppercase data used by Windows.
var a_wtf8_it = std.unicode.Wtf8View.initUnchecked(a).iterator();
var b_wtf8_it = std.unicode.Wtf8View.initUnchecked(b).iterator();
// Use RtlUpcaseUnicodeChar on Windows when not in comptime to avoid including a
// redundant copy of the uppercase data.
const upcaseImpl = switch (builtin.os.tag) {
.windows => if (@inComptime()) nls.upcaseW else ntdll.RtlUpcaseUnicodeChar,
else => nls.upcaseW,
};
while (true) {
const a_cp = a_wtf8_it.nextCodepoint() orelse break;
const b_cp = b_wtf8_it.nextCodepoint() orelse return false;
if (a_cp <= std.math.maxInt(u16) and b_cp <= std.math.maxInt(u16)) {
if (a_cp != b_cp and upcaseImpl(@intCast(a_cp)) != upcaseImpl(@intCast(b_cp))) {
return false;
}
} else if (a_cp != b_cp) {
return false;
}
}
// Make sure there are no leftover codepoints in b
if (b_wtf8_it.nextCodepoint() != null) return false;
return true;
}