use std::marker;
use std::mem::{size_of, transmute};
pub fn write_be<T: Writeable>(v: &T, buffer: &mut [u8]) {
T::to_u8_be(v, buffer);
}
pub fn read_be<T: Readable>(buffer: &[u8]) -> T {
T::from_u8_be(buffer)
}
pub fn write_le<T: Writeable>(v: &T, buffer: &mut [u8]) {
T::to_u8_le(v, buffer);
}
pub fn read_le<T: Readable>(buffer: &[u8]) -> T {
T::from_u8_le(buffer)
}
pub trait Readable : marker::Sized {
fn from_u8_be(&[u8]) -> Self;
fn from_u8_le(&[u8]) -> Self;
}
pub trait Writeable : marker::Sized {
fn to_u8_be(&Self, &mut [u8]);
fn to_u8_le(&Self, &mut [u8]);
}
impl<T: Readable> Readable for Vec<T> {
fn from_u8_be(input: &[u8]) -> Self {
let t_size = size_of::<T>();
let mut output = Vec::new();
for i in 0..input.len() / t_size {
output.push(T::from_u8_be(&input[i * t_size..(i + 1) * t_size]));
}
output
}
fn from_u8_le(input: &[u8]) -> Self {
let t_size = size_of::<T>();
let mut output = Vec::new();
for i in 0..input.len() / t_size {
output.push(T::from_u8_le(&input[i * t_size..(i + 1) * t_size]));
}
output
}
}
impl<T: Writeable> Writeable for Vec<T> {
fn to_u8_be(v: &Self, buf: &mut [u8]) {
let t_size = size_of::<T>();
for (i, v) in v.iter().enumerate() {
T::to_u8_be(v, &mut buf[i * t_size..(i + 1) * t_size]);
}
}
fn to_u8_le(v: &Self, buf: &mut [u8]) {
let t_size = size_of::<T>();
for (i, v) in v.iter().enumerate() {
T::to_u8_le(v, &mut buf[i * t_size..(i + 1) * t_size]);
}
}
}
impl Writeable for i8 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[0] = *v as u8;
}
}
impl Readable for i8 {
fn from_u8_be(i: &[u8]) -> Self {
i[0] as i8
}
fn from_u8_le(i: &[u8]) -> Self {
i[0] as i8
}
}
impl Readable for u8 {
fn from_u8_be(a: &[u8]) -> Self {
a[0]
}
fn from_u8_le(a: &[u8]) -> Self {
a[0]
}
}
impl Writeable for u8 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = *v;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[0] = *v;
}
}
impl Readable for i16 {
fn from_u8_be(i: &[u8]) -> Self {
(i[0] as i16) << 8 | i[1] as i16
}
fn from_u8_le(i: &[u8]) -> Self {
(i[1] as i16) << 8 | i[0] as i16
}
}
impl Writeable for i16 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = (*v >> 8) as u8;
a[1] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[1] = (*v >> 8) as u8;
a[0] = *v as u8;
}
}
impl Readable for u16 {
fn from_u8_be(i: &[u8]) -> Self {
(i[0] as u16) << 8 | i[1] as u16
}
fn from_u8_le(i: &[u8]) -> Self {
(i[1] as u16) << 8 | i[0] as u16
}
}
impl Writeable for u16 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = (*v >> 8) as u8;
a[1] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[1] = (*v >> 8) as u8;
a[0] = *v as u8;
}
}
impl Readable for i32 {
fn from_u8_be(i: &[u8]) -> Self {
(i[0] as i32) << 24 | (i[1] as i32) << 16 | (i[2] as i32) << 8 | i[3] as i32
}
fn from_u8_le(i: &[u8]) -> Self {
(i[3] as i32) << 24 | (i[2] as i32) << 16 | (i[1] as i32) << 8 | i[0] as i32
}
}
impl Writeable for i32 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = (*v >> 24) as u8;
a[1] = (*v >> 16) as u8;
a[2] = (*v >> 8) as u8;
a[3] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[3] = (*v >> 24) as u8;
a[2] = (*v >> 16) as u8;
a[1] = (*v >> 8) as u8;
a[0] = *v as u8;
}
}
impl Readable for u32 {
fn from_u8_be(i: &[u8]) -> Self {
(i[0] as u32) << 24 | (i[1] as u32) << 16 | (i[2] as u32) << 8 | i[3] as u32
}
fn from_u8_le(i: &[u8]) -> Self {
(i[3] as u32) << 24 | (i[2] as u32) << 16 | (i[1] as u32) << 8 | i[0] as u32
}
}
impl Writeable for u32 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = (*v >> 24) as u8;
a[1] = (*v >> 16) as u8;
a[2] = (*v >> 8) as u8;
a[3] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[3] = (*v >> 24) as u8;
a[2] = (*v >> 16) as u8;
a[1] = (*v >> 8) as u8;
a[0] = *v as u8;
}
}
impl Readable for i64 {
fn from_u8_be(i: &[u8]) -> Self {
(i[0] as i64) << 56 | (i[1] as i64) << 48 | (i[2] as i64) << 40 | (i[3] as i64) << 32 |
(i[4] as i64) << 24 | (i[5] as i64) << 16 |
(i[6] as i64) << 8 | i[7] as i64
}
fn from_u8_le(i: &[u8]) -> Self {
(i[7] as i64) << 56 | (i[6] as i64) << 48 | (i[5] as i64) << 40 | (i[4] as i64) << 32 |
(i[3] as i64) << 24 | (i[2] as i64) << 16 |
(i[1] as i64) << 8 | i[0] as i64
}
}
impl Writeable for i64 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = (*v >> 56) as u8;
a[1] = (*v >> 48) as u8;
a[2] = (*v >> 40) as u8;
a[3] = (*v >> 32) as u8;
a[4] = (*v >> 24) as u8;
a[5] = (*v >> 16) as u8;
a[6] = (*v >> 8) as u8;
a[7] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[7] = (*v >> 56) as u8;
a[6] = (*v >> 48) as u8;
a[5] = (*v >> 40) as u8;
a[4] = (*v >> 32) as u8;
a[3] = (*v >> 24) as u8;
a[2] = (*v >> 16) as u8;
a[1] = (*v >> 8) as u8;
a[0] = *v as u8;
}
}
impl Readable for u64 {
fn from_u8_be(i: &[u8]) -> Self {
(i[0] as u64) << 56 | (i[1] as u64) << 48 | (i[2] as u64) << 40 | (i[3] as u64) << 32 |
(i[4] as u64) << 24 | (i[5] as u64) << 16 |
(i[6] as u64) << 8 | i[7] as u64
}
fn from_u8_le(i: &[u8]) -> Self {
(i[7] as u64) << 56 | (i[6] as u64) << 48 | (i[5] as u64) << 40 | (i[4] as u64) << 32 |
(i[3] as u64) << 24 | (i[2] as u64) << 16 |
(i[1] as u64) << 8 | i[0] as u64
}
}
impl Writeable for u64 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = (*v >> 56) as u8;
a[1] = (*v >> 48) as u8;
a[2] = (*v >> 40) as u8;
a[3] = (*v >> 32) as u8;
a[4] = (*v >> 24) as u8;
a[5] = (*v >> 16) as u8;
a[6] = (*v >> 8) as u8;
a[7] = *v as u8;
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[7] = (*v >> 56) as u8;
a[6] = (*v >> 48) as u8;
a[5] = (*v >> 40) as u8;
a[4] = (*v >> 32) as u8;
a[3] = (*v >> 24) as u8;
a[2] = (*v >> 16) as u8;
a[1] = (*v >> 8) as u8;
a[0] = *v as u8;
}
}
impl Readable for bool {
fn from_u8_be(i: &[u8]) -> Self {
i[0] > 0
}
fn from_u8_le(i: &[u8]) -> Self {
i[0] > 0
}
}
impl Writeable for bool {
fn to_u8_be(v: &Self, a: &mut [u8]) {
a[0] = if *v {
1u8
} else {
0u8
};
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
a[0] = if *v {
1u8
} else {
0u8
};
}
}
impl Readable for f32 {
fn from_u8_be(i: &[u8]) -> Self {
unsafe { transmute(u32::from_u8_be(i)) }
}
fn from_u8_le(i: &[u8]) -> Self {
unsafe { transmute(u32::from_u8_le(i)) }
}
}
impl Writeable for f32 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
unsafe { u32::to_u8_be(transmute(v), a) }
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
unsafe { u32::to_u8_le(transmute(v), a) }
}
}
impl Readable for f64 {
fn from_u8_be(i: &[u8]) -> Self {
unsafe { transmute(u64::from_u8_be(i)) }
}
fn from_u8_le(i: &[u8]) -> Self {
unsafe { transmute(u64::from_u8_le(i)) }
}
}
impl Writeable for f64 {
fn to_u8_be(v: &Self, a: &mut [u8]) {
unsafe { u64::to_u8_be(transmute(v), a) }
}
fn to_u8_le(v: &Self, a: &mut [u8]) {
unsafe { u64::to_u8_le(transmute(v), a) }
}
}