mirror of https://github.com/tailix/libkernaux.git
267 lines
9.8 KiB
Rust
267 lines
9.8 KiB
Rust
use libc::{c_char, c_int};
|
|
|
|
pub const MAX_PREFIX_LEN: usize = 100;
|
|
|
|
pub const UTOA_MIN_BUFFER_SIZE: usize = 64 + 1;
|
|
pub const ITOA_MIN_BUFFER_SIZE: usize = 65 + 1;
|
|
|
|
pub const UTOA2_BUFFER_SIZE: usize = 64 + 2 + 1;
|
|
pub const ITOA2_BUFFER_SIZE: usize = 65 + 2 + 1;
|
|
pub const UTOA8_BUFFER_SIZE: usize = 21 + 2 + 1;
|
|
pub const ITOA8_BUFFER_SIZE: usize = 22 + 2 + 1;
|
|
pub const UTOA10_BUFFER_SIZE: usize = 20 + 1;
|
|
pub const ITOA10_BUFFER_SIZE: usize = 20 + 1;
|
|
pub const UTOA16_BUFFER_SIZE: usize = 16 + 2 + 1;
|
|
pub const ITOA16_BUFFER_SIZE: usize = 17 + 2 + 1;
|
|
|
|
#[link(name = "kernaux")]
|
|
extern "C" {
|
|
#[link_name = "kernaux_utoa"]
|
|
pub fn utoa(
|
|
value: u64,
|
|
buffer: *mut c_char,
|
|
base: c_int,
|
|
prefix: *const c_char,
|
|
) -> *mut c_char;
|
|
#[link_name = "kernaux_itoa"]
|
|
pub fn itoa(
|
|
value: i64,
|
|
buffer: *mut c_char,
|
|
base: c_int,
|
|
prefix: *const c_char,
|
|
) -> *mut c_char;
|
|
|
|
#[link_name = "kernaux_utoa2"]
|
|
pub fn utoa2(value: u64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_itoa2"]
|
|
pub fn itoa2(value: i64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_utoa8"]
|
|
pub fn utoa8(value: u64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_itoa8"]
|
|
pub fn itoa8(value: i64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_utoa10"]
|
|
pub fn utoa10(value: u64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_itoa10"]
|
|
pub fn itoa10(value: i64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_utoa16"]
|
|
pub fn utoa16(value: u64, buffer: *mut c_char) -> *mut c_char;
|
|
#[link_name = "kernaux_itoa16"]
|
|
pub fn itoa16(value: i64, buffer: *mut c_char) -> *mut c_char;
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
use std::ffi::{CStr, CString};
|
|
use std::ptr::null;
|
|
|
|
fn empty_prefix() -> CString {
|
|
CString::new("").unwrap()
|
|
}
|
|
|
|
fn foo_prefix() -> CString {
|
|
CString::new("foo").unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn test_utoa() {
|
|
let mut buffer: [i8; UTOA_MIN_BUFFER_SIZE + 3] =
|
|
[0; UTOA_MIN_BUFFER_SIZE + 3];
|
|
|
|
let empty_pfx = empty_prefix();
|
|
let foo_pfx = foo_prefix();
|
|
|
|
let end: *mut c_char =
|
|
unsafe { utoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, null()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
|
|
|
let end: *mut c_char = unsafe {
|
|
utoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, empty_pfx.as_ptr())
|
|
};
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
|
|
|
let end: *mut c_char = unsafe {
|
|
utoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, foo_pfx.as_ptr())
|
|
};
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "foo123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_itoa() {
|
|
let mut buffer: [i8; ITOA_MIN_BUFFER_SIZE + 3] =
|
|
[0; ITOA_MIN_BUFFER_SIZE + 3];
|
|
|
|
let empty_pfx = empty_prefix();
|
|
let foo_pfx = foo_prefix();
|
|
|
|
let end: *mut c_char =
|
|
unsafe { itoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, null()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
|
|
|
let end: *mut c_char = unsafe {
|
|
itoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, empty_pfx.as_ptr())
|
|
};
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
|
|
|
let end: *mut c_char = unsafe {
|
|
itoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, foo_pfx.as_ptr())
|
|
};
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "foo123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
|
|
|
let end: *mut c_char =
|
|
unsafe { itoa(-0x123, buffer.as_mut_ptr(), 'x' as c_int, null()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(4) });
|
|
|
|
let end: *mut c_char = unsafe {
|
|
itoa(
|
|
-0x123,
|
|
buffer.as_mut_ptr(),
|
|
'x' as c_int,
|
|
empty_pfx.as_ptr(),
|
|
)
|
|
};
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(4) });
|
|
|
|
let end: *mut c_char = unsafe {
|
|
itoa(-0x123, buffer.as_mut_ptr(), 'x' as c_int, foo_pfx.as_ptr())
|
|
};
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-foo123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(7) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_utoa2() {
|
|
let mut buffer: [i8; UTOA2_BUFFER_SIZE] = [0; UTOA2_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { utoa2(123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "0b1111011");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(9) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_itoa2() {
|
|
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa2(123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "0b1111011");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(9) });
|
|
|
|
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa2(-123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-0b1111011");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(10) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_utoa8() {
|
|
let mut buffer: [i8; UTOA8_BUFFER_SIZE] = [0; UTOA8_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { utoa8(0o123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "0o123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_itoa8() {
|
|
let mut buffer: [i8; ITOA8_BUFFER_SIZE] = [0; ITOA8_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa8(0o123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "0o123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
|
|
|
let mut buffer: [i8; ITOA8_BUFFER_SIZE] = [0; ITOA8_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa8(-0o123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-0o123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_utoa10() {
|
|
let mut buffer: [i8; UTOA10_BUFFER_SIZE] = [0; UTOA10_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { utoa10(123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_itoa10() {
|
|
let mut buffer: [i8; ITOA10_BUFFER_SIZE] = [0; ITOA10_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa10(123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
|
|
|
let mut buffer: [i8; ITOA10_BUFFER_SIZE] = [0; ITOA10_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa10(-123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(4) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_utoa16() {
|
|
let mut buffer: [i8; UTOA16_BUFFER_SIZE] = [0; UTOA16_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { utoa16(0x123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "0x123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
|
}
|
|
|
|
#[test]
|
|
fn test_itoa16() {
|
|
let mut buffer: [i8; ITOA16_BUFFER_SIZE] = [0; ITOA16_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa16(0x123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "0x123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
|
|
|
let mut buffer: [i8; ITOA16_BUFFER_SIZE] = [0; ITOA16_BUFFER_SIZE];
|
|
let end: *mut c_char = unsafe { itoa16(-0x123, buffer.as_mut_ptr()) };
|
|
let result =
|
|
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
|
assert_eq!(result, "-0x123");
|
|
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
|
}
|
|
}
|