use std::prelude::v1::*;
mod c_str;
#[allow(dead_code)]
mod wide_str;
mod guid;
mod align;
#[cfg(feature = "serde")]
pub(crate) mod serde_helper;
pub use self::c_str::CStr;
pub(crate) use self::wide_str::FmtUtf16;
pub use self::align::*;
pub trait FromBytes {
const MIN_SIZE_OF: usize;
const ALIGN_OF: usize;
unsafe fn from_bytes(bytes: &[u8]) -> Option<&Self>;
}
#[inline]
pub(crate) fn split_f<T, F: FnMut(&T) -> bool>(slice: &[T], f: F) -> (&[T], &[T]) {
let i = slice.iter().position(f).unwrap_or(slice.len());
(&slice[..i], &slice[i..])
}
#[inline]
pub fn strn(buf: &[u8]) -> &[u8] {
split_f(buf, |&byte| byte == 0).0
}
pub(crate) fn trimn(buf: &[u8]) -> &[u8] {
let mut len = buf.len();
while len > 0 {
if buf[len - 1] != 0 {
break;
}
len -= 1;
}
&buf[..len]
}
pub(crate) fn parsen(buf: &[u8]) -> Result<&str, &[u8]> {
std::str::from_utf8(trimn(buf)).map_err(|_| buf)
}
#[inline]
pub fn wstrn(buf: &[u16]) -> &[u16] {
split_f(buf, |&word| word == 0).0
}
#[cfg(feature = "std")]
pub fn shannon_entropy(data: &[u8]) -> f64 {
let mut map = [0usize; 256];
for &byte in data {
map[byte as usize] += 1;
}
let mut result = 0.0;
let len = data.len() as f64;
for &item in &map[..] {
if item != 0 {
let freq = item as f64 / len;
result -= freq * freq.log2();
}
}
result
}
pub(crate) unsafe fn extend_in_place<'a, T, F: FnMut(&'a mut [T])>(vec: &'a mut Vec<T>, additional: usize, mut f: F) {
let vec_len = vec.len();
if vec_len + additional > vec.capacity() {
vec.reserve(additional);
}
f(std::slice::from_raw_parts_mut(vec.as_mut_ptr().offset(vec_len as isize), additional));
vec.set_len(vec_len + additional);
}