#![deny(missing_docs)]
extern crate byteorder;
extern crate bytes;
use byteorder::{ByteOrder, NativeEndian, BE, LE};
use bytes::{Bytes, BytesMut};
use std::mem;
use std::fmt::Debug;
use std::hash::Hash;
pub const U8: usize = 1;
pub const U16: usize = 2;
pub const U24: usize = 3;
pub const U32: usize = 4;
pub const U64: usize = 8;
pub const U128: usize = 16;
pub const I8: usize = 1;
pub const I16: usize = 2;
pub const I24: usize = 3;
pub const I32: usize = 4;
pub const I64: usize = 8;
pub const I128: usize = 16;
pub const F32: usize = 4;
pub const F64: usize = 8;
pub fn padding(offset: usize, align: usize) -> usize {
let padding = -(offset as isize) as usize & align - 1;
debug_assert_eq!(padding, (align - offset % align) % align);
padding
}
pub fn aligned(offset: usize, align: usize) -> usize {
let aligned = offset + align - 1 & -(align as isize) as usize;
debug_assert_eq!(aligned, offset + padding(offset, align));
aligned
}
pub trait InSitu: AsRef<[u8]> {
fn swap_size(&self) -> usize;
fn is_be(&self) -> bool;
fn is_le(&self) -> bool {
!self.is_be()
}
fn is_native(&self) -> bool {
self.is_be() == (NativeEndian::read_u16(&[0, 1]) == 1)
}
fn order(&self) -> Order {
match self.is_be()
{ true => Order::BE, false => Order::LE }
}
fn at(&self, offset: usize, word_size: usize) -> usize {
if self.is_be()
{ offset } else { offset ^ self.swap_size() - word_size }
}
fn u8(&self, offset: usize) -> u8 {
let offset = self.at(offset, U8);
self.as_ref()[offset]
}
fn u16(&self, offset: usize) -> u16 {
let offset = self.at(offset, U16);
if self.is_be() {
BE::read_u16(&self.as_ref()[offset..])
} else {
LE::read_u16(&self.as_ref()[offset..])
}
}
fn u24(&self, offset: usize) -> u32 {
let offset = self.at(offset, U24);
if self.is_be() {
BE::read_u24(&self.as_ref()[offset..])
} else {
LE::read_u24(&self.as_ref()[offset..])
}
}
fn u32(&self, offset: usize) -> u32 {
let offset = self.at(offset, U32);
if self.is_be() {
BE::read_u32(&self.as_ref()[offset..])
} else {
LE::read_u32(&self.as_ref()[offset..])
}
}
fn u64(&self, offset: usize) -> u64 {
let offset = self.at(offset, U64);
if self.is_be() {
BE::read_u64(&self.as_ref()[offset..])
} else {
LE::read_u64(&self.as_ref()[offset..])
}
}
fn u128(&self, offset: usize) -> u128 {
let offset = self.at(offset, U128);
if self.is_be() {
BE::read_u128(&self.as_ref()[offset..])
} else {
LE::read_u128(&self.as_ref()[offset..])
}
}
fn uint(&self, offset: usize, word_size: usize) -> u64 {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::read_uint(&self.as_ref()[offset..], word_size)
} else {
LE::read_uint(&self.as_ref()[offset..], word_size)
}
}
fn uint128(&self, offset: usize, word_size: usize) -> u128 {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::read_uint128(&self.as_ref()[offset..], word_size)
} else {
LE::read_uint128(&self.as_ref()[offset..], word_size)
}
}
fn i8(&self, offset: usize) -> i8 {
let offset = self.at(offset, I8);
self.as_ref()[offset] as i8
}
fn i16(&self, offset: usize) -> i16 {
let offset = self.at(offset, I16);
if self.is_be() {
BE::read_i16(&self.as_ref()[offset..])
} else {
LE::read_i16(&self.as_ref()[offset..])
}
}
fn i24(&self, offset: usize) -> i32 {
let offset = self.at(offset, I24);
if self.is_be() {
BE::read_i24(&self.as_ref()[offset..])
} else {
LE::read_i24(&self.as_ref()[offset..])
}
}
fn i32(&self, offset: usize) -> i32 {
let offset = self.at(offset, I32);
if self.is_be() {
BE::read_i32(&self.as_ref()[offset..])
} else {
LE::read_i32(&self.as_ref()[offset..])
}
}
fn i64(&self, offset: usize) -> i64 {
let offset = self.at(offset, I64);
if self.is_be() {
BE::read_i64(&self.as_ref()[offset..])
} else {
LE::read_i64(&self.as_ref()[offset..])
}
}
fn i128(&self, offset: usize) -> i128 {
let offset = self.at(offset, I128);
if self.is_be() {
BE::read_i128(&self.as_ref()[offset..])
} else {
LE::read_i128(&self.as_ref()[offset..])
}
}
fn int(&self, offset: usize, word_size: usize) -> i64 {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::read_int(&self.as_ref()[offset..], word_size)
} else {
LE::read_int(&self.as_ref()[offset..], word_size)
}
}
fn int128(&self, offset: usize, word_size: usize) -> i128 {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::read_int128(&self.as_ref()[offset..], word_size)
} else {
LE::read_int128(&self.as_ref()[offset..], word_size)
}
}
fn f32(&self, offset: usize) -> f32 {
let offset = self.at(offset, F32);
if self.is_be() {
BE::read_f32(&self.as_ref()[offset..])
} else {
LE::read_f32(&self.as_ref()[offset..])
}
}
fn f64(&self, offset: usize) -> f64 {
let offset = self.at(offset, F64);
if self.is_be() {
BE::read_f64(&self.as_ref()[offset..])
} else {
LE::read_f64(&self.as_ref()[offset..])
}
}
}
pub trait InSituMut: InSitu + AsMut<[u8]> {
fn set_u8(&mut self, offset: usize, value: u8) {
let at = self.at(offset, U8);
self.as_mut()[at] = value;
}
fn set_u16(&mut self, offset: usize, value: u16) {
let offset = self.at(offset, U16);
if self.is_be() {
BE::write_u16(&mut self.as_mut()[offset..], value)
} else {
LE::write_u16(&mut self.as_mut()[offset..], value)
}
}
fn set_u24(&mut self, offset: usize, value: u32) {
let offset = self.at(offset, U24);
if self.is_be() {
BE::write_u24(&mut self.as_mut()[offset..], value)
} else {
LE::write_u24(&mut self.as_mut()[offset..], value)
}
}
fn set_u32(&mut self, offset: usize, value: u32) {
let offset = self.at(offset, U32);
if self.is_be() {
BE::write_u32(&mut self.as_mut()[offset..], value)
} else {
LE::write_u32(&mut self.as_mut()[offset..], value)
}
}
fn set_u64(&mut self, offset: usize, value: u64) {
let offset = self.at(offset, U64);
if self.is_be() {
BE::write_u64(&mut self.as_mut()[offset..], value)
} else {
LE::write_u64(&mut self.as_mut()[offset..], value)
}
}
fn set_u128(&mut self, offset: usize, value: u128) {
let offset = self.at(offset, U128);
if self.is_be() {
BE::write_u128(&mut self.as_mut()[offset..], value)
} else {
LE::write_u128(&mut self.as_mut()[offset..], value)
}
}
fn set_uint(&mut self, offset: usize, value: u64, word_size: usize) {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::write_uint(&mut self.as_mut()[offset..], value, word_size)
} else {
LE::write_uint(&mut self.as_mut()[offset..], value, word_size)
}
}
fn set_uint128(&mut self, offset: usize, value: u128, word_size: usize) {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::write_uint128(&mut self.as_mut()[offset..], value, word_size)
} else {
LE::write_uint128(&mut self.as_mut()[offset..], value, word_size)
}
}
fn set_i8(&mut self, offset: usize, value: i8) {
let at = self.at(offset, I8);
self.as_mut()[at] = value as u8;
}
fn set_i16(&mut self, offset: usize, value: i16) {
let offset = self.at(offset, I16);
if self.is_be() {
BE::write_i16(&mut self.as_mut()[offset..], value)
} else {
LE::write_i16(&mut self.as_mut()[offset..], value)
}
}
fn set_i24(&mut self, offset: usize, value: i32) {
let offset = self.at(offset, I24);
if self.is_be() {
BE::write_i24(&mut self.as_mut()[offset..], value)
} else {
LE::write_i24(&mut self.as_mut()[offset..], value)
}
}
fn set_i32(&mut self, offset: usize, value: i32) {
let offset = self.at(offset, I32);
if self.is_be() {
BE::write_i32(&mut self.as_mut()[offset..], value)
} else {
LE::write_i32(&mut self.as_mut()[offset..], value)
}
}
fn set_i64(&mut self, offset: usize, value: i64) {
let offset = self.at(offset, I64);
if self.is_be() {
BE::write_i64(&mut self.as_mut()[offset..], value)
} else {
LE::write_i64(&mut self.as_mut()[offset..], value)
}
}
fn set_i128(&mut self, offset: usize, value: i128) {
let offset = self.at(offset, I128);
if self.is_be() {
BE::write_i128(&mut self.as_mut()[offset..], value)
} else {
LE::write_i128(&mut self.as_mut()[offset..], value)
}
}
fn set_int(&mut self, offset: usize, value: i64, word_size: usize) {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::write_int(&mut self.as_mut()[offset..], value, word_size)
} else {
LE::write_int(&mut self.as_mut()[offset..], value, word_size)
}
}
fn set_int128(&mut self, offset: usize, value: i128, word_size: usize) {
let offset = self.at(offset, word_size);
if self.is_be() {
BE::write_int128(&mut self.as_mut()[offset..], value, word_size)
} else {
LE::write_int128(&mut self.as_mut()[offset..], value, word_size)
}
}
fn set_f32(&mut self, offset: usize, value: f32) {
let offset = self.at(offset, F32);
if self.is_be() {
BE::write_f32(&mut self.as_mut()[offset..], value)
} else {
LE::write_f32(&mut self.as_mut()[offset..], value)
}
}
fn set_f64(&mut self, offset: usize, value: f64) {
let offset = self.at(offset, F64);
if self.is_be() {
BE::write_f64(&mut self.as_mut()[offset..], value)
} else {
LE::write_f64(&mut self.as_mut()[offset..], value)
}
}
}
impl<T: InSitu + AsMut<[u8]>> InSituMut for T {}
pub trait Raw: AsRef<[u8]>
+ Default + PartialEq + Eq + PartialOrd + Ord + Debug + Hash {
fn split_off(&mut self, at: usize) -> Self;
fn split_to(&mut self, at: usize) -> Self;
}
pub trait RawMut: Raw + AsMut<[u8]> {}
impl<T: Raw + AsMut<[u8]>> RawMut for T {}
impl<'a> Raw for &'a [u8] {
fn split_off(&mut self, at: usize) -> Self {
let (l, r) = self.split_at(at);
*self = l;
r
}
fn split_to(&mut self, at: usize) -> Self {
let (l, r) = self.split_at(at);
*self = r;
l
}
}
impl<'a> Raw for &'a mut [u8] {
fn split_off(&mut self, at: usize) -> Self {
let slice = mem::replace(self, &mut []);
let (l, r) = slice.split_at_mut(at);
*self = l;
r
}
fn split_to(&mut self, at: usize) -> Self {
let slice = mem::replace(self, &mut []);
let (l, r) = slice.split_at_mut(at);
*self = r;
l
}
}
impl Raw for Bytes {
fn split_off(&mut self, at: usize) -> Self {
self.split_off(at)
}
fn split_to(&mut self, at: usize) -> Self {
self.split_to(at)
}
}
impl Raw for BytesMut {
fn split_off(&mut self, at: usize) -> Self {
self.split_off(at)
}
fn split_to(&mut self, at: usize) -> Self {
self.split_to(at)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Order {
BE,
LE,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Take {
Header,
Packet,
}