use core::iter::Iterator;
#[no_mangle]
pub unsafe extern "C" fn memset(dest: *mut u8, val: u8, count: usize) -> *mut u8 {
for i in 0..count {
*dest.offset(i as isize) = val;
}
dest
}
#[no_mangle]
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
let mut i = 0;
while i < n {
*dest.add(i) = *src.add(i);
i += 1;
}
dest
}
#[no_mangle]
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
let mut i = 0;
while i < n {
let a = *s1.add(i);
let b = *s2.add(i);
if a != b {
return a as i32 - b as i32;
}
i += 1;
}
return 0;
}
#[no_mangle]
fn memmove(dest: *mut u8, src: *const u8, n: usize) {
unsafe {
if src < dest {
for i in (0..n).rev() {
*dest.add(i) = *src.add(i);
}
} else {
for i in 0..n {
*dest.add(i) = *src.add(i);
}
}
}
}
#[no_mangle]
fn strlen(s: *const u8) -> usize {
let mut len = 0;
unsafe {
while *s.add(len) != 0 {
len += 1;
}
}
len
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_memset() {
let mut buf = [0u8; 10];
unsafe {
memset(buf.as_mut_ptr(), 0xff, buf.len());
}
assert_eq!(buf, [0xff; 10]);
}
#[test]
fn test_memcpy() {
let mut src = [1u8, 2, 3, 4, 5];
let mut dst = [0u8; 5];
unsafe {
memcpy(dst.as_mut_ptr(), src.as_ptr(), src.len());
}
assert_eq!(src, dst);
}
#[test]
fn test_memcmp() {
let a = [1u8, 2, 3, 4, 5];
let b = [1u8, 2, 3, 4, 5];
let c = [1u8, 2, 3, 4, 6];
unsafe {
assert_eq!(memcmp(a.as_ptr(), b.as_ptr(), a.len()), 0);
assert_eq!(memcmp(a.as_ptr(), c.as_ptr(), a.len()), -1);
}
}
#[test]
fn test_memmove() {
let mut buf = [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10];
unsafe {
memmove(buf.as_mut_ptr().offset(3), buf.as_ptr(), 5);
}
assert_eq!(buf, [1, 2, 3, 1, 2, 3, 4, 5, 9, 10]);
}
#[test]
fn test_strlen() {
let s = b"hello world\0";
unsafe {
assert_eq!(strlen(s.as_ptr()), 11);
}
}
}