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