use errors::*;
use failure::ResultExt;
use memchr::memchr;
use std::io;
use std::mem::{size_of, transmute};
use std::slice::from_raw_parts;
const DIGITS: [u8; 36] = *b"0123456789abcdefghijklmnopqrstuvwxyz";
#[inline(always)]
pub fn read_le_u16(b: &[u8], i: usize) -> u16 {
if b.len() < 2 {
return invalid();
}
u16::from_le(unsafe { (&*(b as *const [u8] as *const [u16]))[i] })
}
#[inline(always)]
pub fn read_le_u32(b: &[u8], i: usize) -> u32 {
if b.len() < 4 {
return invalid();
}
u32::from_le(unsafe { (&*(b as *const [u8] as *const [u32]))[i] })
}
#[inline(always)]
pub fn invalid<T>() -> T
where
T: From<u16>,
{
T::from(65535)
}
#[inline]
pub fn strlen(s: &[u8]) -> usize {
memchr(0, s).unwrap_or_else(|| s.len())
}
#[inline]
pub fn write_u8_ansi<W: io::Write>(w: &mut W, num: u8) -> Result<usize> {
let mut num_buf = [0u8; 3];
let mut num_buf_len = 0;
let mut num = num;
if num == 0 {
return Ok(0);
}
while num > 0 {
let c = num % 10;
num /= 10;
num_buf[num_buf_len] = DIGITS[c as usize];
num_buf_len += 1;
}
if num_buf_len > 1 {
num_buf[0] ^= num_buf[num_buf_len - 1];
num_buf[num_buf_len - 1] ^= num_buf[0];
num_buf[0] ^= num_buf[num_buf_len - 1];
}
w.write(&num_buf[..num_buf_len])
.context(ErrorKind::FailedWriteToStdout)?;
Ok(num_buf_len)
}