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
// 原始实现来自 rust-memchr。
// 版权所有 2015 Andrew Gallant,bluss 和 Nicolas Koch

pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    let p = unsafe {
        libc::memchr(
            haystack.as_ptr() as *const libc::c_void,
            needle as libc::c_int,
            haystack.len(),
        )
    };
    if p.is_null() { None } else { Some(p.addr() - haystack.as_ptr().addr()) }
}

pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        // 如果 haystack 为空,则 GNU 的 memrchr() (与 memchr() 不同) 将出错。
        if haystack.is_empty() {
            return None;
        }
        let p = unsafe {
            libc::memrchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len(),
            )
        };
        // FIXME: 这应该可能使用 `offset_from`,但需要进行更多调查 (包括在 miri 中运行测试)。
        //
        if p.is_null() { None } else { Some(p.addr() - haystack.as_ptr().addr()) }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        core::slice::memchr::memrchr(needle, haystack)
    }

    memrchr_specific(needle, haystack)
}