aboutsummaryrefslogtreecommitdiff
path: root/src/windows/wtf8/string.rs
blob: b3523a2eff712dccfe7e77f75d0425a042f0d8d1 (plain)
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
use crate::util;

const SURROGATE_LENGTH: usize = 3;

pub(crate) fn ends_with(string: &[u8], mut suffix: &[u8]) -> bool {
    let index = if let Some(index) = string.len().checked_sub(suffix.len()) {
        index
    } else {
        return false;
    };
    if let Some(&byte) = string.get(index) {
        if util::is_continuation(byte) {
            let index = expect_encoded!(index.checked_sub(1));
            let mut wide_surrogate =
                if let Some(surrogate) = suffix.get(..SURROGATE_LENGTH) {
                    super::encode_wide(surrogate)
                } else {
                    return false;
                };
            let surrogate_wchar = wide_surrogate
                .next()
                .expect("failed decoding non-empty suffix");

            if wide_surrogate.next().is_some()
                || super::encode_wide(&string[index..])
                    .take_while(Result::is_ok)
                    .nth(1)
                    != Some(surrogate_wchar)
            {
                return false;
            }
            suffix = &suffix[SURROGATE_LENGTH..];
        }
    }
    string.ends_with(suffix)
}

pub(crate) fn starts_with(string: &[u8], mut prefix: &[u8]) -> bool {
    if let Some(&byte) = string.get(prefix.len()) {
        if util::is_continuation(byte) {
            let index = if let Some(index) =
                prefix.len().checked_sub(SURROGATE_LENGTH)
            {
                index
            } else {
                return false;
            };
            let (substring, surrogate) = prefix.split_at(index);
            let mut wide_surrogate = super::encode_wide(surrogate);
            let surrogate_wchar = wide_surrogate
                .next()
                .expect("failed decoding non-empty prefix");

            if surrogate_wchar.is_err()
                || wide_surrogate.next().is_some()
                || super::encode_wide(&string[index..])
                    .next()
                    .expect("failed decoding non-empty substring")
                    != surrogate_wchar
            {
                return false;
            }
            prefix = substring;
        }
    }
    string.starts_with(prefix)
}