1fb6c1f39Sopenharmony_ci// This module defines safe wrappers around memchr (POSIX) and memrchr (GNU
2fb6c1f39Sopenharmony_ci// extension).
3fb6c1f39Sopenharmony_ci
4fb6c1f39Sopenharmony_ci#![allow(dead_code)]
5fb6c1f39Sopenharmony_ci
6fb6c1f39Sopenharmony_ciuse libc::{c_int, c_void, size_t};
7fb6c1f39Sopenharmony_ci
8fb6c1f39Sopenharmony_cipub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
9fb6c1f39Sopenharmony_ci    // SAFETY: This is safe to call since all pointers are valid.
10fb6c1f39Sopenharmony_ci    let p = unsafe {
11fb6c1f39Sopenharmony_ci        libc::memchr(
12fb6c1f39Sopenharmony_ci            haystack.as_ptr() as *const c_void,
13fb6c1f39Sopenharmony_ci            needle as c_int,
14fb6c1f39Sopenharmony_ci            haystack.len() as size_t,
15fb6c1f39Sopenharmony_ci        )
16fb6c1f39Sopenharmony_ci    };
17fb6c1f39Sopenharmony_ci    if p.is_null() {
18fb6c1f39Sopenharmony_ci        None
19fb6c1f39Sopenharmony_ci    } else {
20fb6c1f39Sopenharmony_ci        Some(p as usize - (haystack.as_ptr() as usize))
21fb6c1f39Sopenharmony_ci    }
22fb6c1f39Sopenharmony_ci}
23fb6c1f39Sopenharmony_ci
24fb6c1f39Sopenharmony_ci// memrchr is a GNU extension. We know it's available on Linux at least.
25fb6c1f39Sopenharmony_ci#[cfg(target_os = "linux")]
26fb6c1f39Sopenharmony_cipub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
27fb6c1f39Sopenharmony_ci    // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
28fb6c1f39Sopenharmony_ci    if haystack.is_empty() {
29fb6c1f39Sopenharmony_ci        return None;
30fb6c1f39Sopenharmony_ci    }
31fb6c1f39Sopenharmony_ci    // SAFETY: This is safe to call since all pointers are valid.
32fb6c1f39Sopenharmony_ci    let p = unsafe {
33fb6c1f39Sopenharmony_ci        libc::memrchr(
34fb6c1f39Sopenharmony_ci            haystack.as_ptr() as *const c_void,
35fb6c1f39Sopenharmony_ci            needle as c_int,
36fb6c1f39Sopenharmony_ci            haystack.len() as size_t,
37fb6c1f39Sopenharmony_ci        )
38fb6c1f39Sopenharmony_ci    };
39fb6c1f39Sopenharmony_ci    if p.is_null() {
40fb6c1f39Sopenharmony_ci        None
41fb6c1f39Sopenharmony_ci    } else {
42fb6c1f39Sopenharmony_ci        Some(p as usize - (haystack.as_ptr() as usize))
43fb6c1f39Sopenharmony_ci    }
44fb6c1f39Sopenharmony_ci}
45