endian_type/
lib.rs

1use std::{mem,slice};
2use std::convert::{From,Into};
3use std::ops::{BitAnd,BitOr,BitXor};
4
5///Type with a specified byte order
6pub trait Endian<T>{}
7
8macro_rules! impl_Endian{
9	( for $e:ident) => {
10		impl<T> BitAnd for $e<T>
11			where T: BitAnd
12		{
13			type Output = $e<<T as BitAnd>::Output>;
14
15			#[inline]
16			fn bitand(self,other: Self) -> Self::Output{
17				$e(self.0 & other.0)
18			}
19		}
20		impl<T> BitOr for $e<T>
21			where T: BitOr
22		{
23			type Output = $e<<T as BitOr>::Output>;
24
25			#[inline]
26			fn bitor(self,other: Self) -> Self::Output{
27				$e(self.0 | other.0)
28			}
29		}
30		impl<T> BitXor for $e<T>
31			where T: BitXor
32		{
33			type Output = $e<<T as BitXor>::Output>;
34
35			#[inline]
36			fn bitxor(self,other: Self) -> Self::Output{
37				$e(self.0 ^ other.0)
38			}
39		}
40
41		impl<T> $e<T>
42			where T: Sized + Copy
43		{
44			#[inline]
45			pub fn from_bytes(bytes: &[u8]) -> Self{
46				debug_assert!(bytes.len() >= mem::size_of::<T>());
47				$e(unsafe{*(bytes.as_ptr() as *const T)})
48			}
49
50			#[inline]
51			pub fn as_bytes(&self) -> &[u8]{
52				unsafe{slice::from_raw_parts(
53					&self.0 as *const T as *const u8,
54					mem::size_of::<T>()
55				)}
56			}
57
58			/*pub fn write_bytes(self,buffer: &mut [u8]){
59				debug_assert!(buffer.len() >= mem::size_of::<T>());
60				let bytes = mem::transmute::<_,[u8; mem::size_of::<T>()]>();
61				unsafe{ptr::copy_nonoverlapping(bytes.as_ptr(),buffer.as_mut_ptr(),mem::size_of::<T>())};
62			}*/
63		}
64	}
65}
66
67
68
69///Big endian byte order
70///
71///Most significant byte first
72#[derive(Copy,Clone,Debug,Eq,PartialEq,Hash,Ord,PartialOrd)]
73pub struct BigEndian<T>(T);
74impl<T> Endian<T> for BigEndian<T>{}
75macro_rules! impl_for_BigEndian{
76	( $t:ident ) => {
77		impl Into<$t> for BigEndian<$t>{
78			#[inline]
79			fn into(self) -> $t{
80				$t::from_be(self.0)
81			}
82		}
83
84		impl From<$t> for BigEndian<$t>{
85			#[inline]
86			fn from(data: $t) -> Self{
87				BigEndian(data.to_be())
88			}
89		}
90
91		impl From<LittleEndian<$t>> for BigEndian<$t>{
92			#[inline]
93			fn from(data: LittleEndian<$t>) -> Self{
94				BigEndian(data.0.swap_bytes())
95			}
96		}
97	}
98}
99impl_Endian!(for BigEndian);
100impl_for_BigEndian!(u16);
101impl_for_BigEndian!(u32);
102impl_for_BigEndian!(u64);
103impl_for_BigEndian!(usize);
104impl_for_BigEndian!(i16);
105impl_for_BigEndian!(i32);
106impl_for_BigEndian!(i64);
107impl_for_BigEndian!(isize);
108
109
110
111///Little endian byte order
112///
113///Least significant byte first
114#[derive(Copy,Clone,Debug,Eq,PartialEq,Hash,Ord,PartialOrd)]
115pub struct LittleEndian<T>(T);
116impl<T> Endian<T> for LittleEndian<T>{}
117macro_rules! impl_for_LittleEndian{
118	( $t:ident ) => {
119		impl Into<$t> for LittleEndian<$t>{
120			#[inline]
121			fn into(self) -> $t{
122				$t::from_le(self.0)
123			}
124		}
125
126		impl From<$t> for LittleEndian<$t>{
127			#[inline]
128			fn from(data: $t) -> Self{
129				LittleEndian(data.to_le())
130			}
131		}
132
133		impl From<BigEndian<$t>> for LittleEndian<$t>{
134			#[inline]
135			fn from(data: BigEndian<$t>) -> Self{
136				LittleEndian(data.0.swap_bytes())
137			}
138		}
139	}
140}
141impl_Endian!(for LittleEndian);
142impl_for_LittleEndian!(u16);
143impl_for_LittleEndian!(u32);
144impl_for_LittleEndian!(u64);
145impl_for_LittleEndian!(usize);
146impl_for_LittleEndian!(i16);
147impl_for_LittleEndian!(i32);
148impl_for_LittleEndian!(i64);
149impl_for_LittleEndian!(isize);
150
151
152///Network byte order as defined by IETF RFC1700 [http://tools.ietf.org/html/rfc1700]
153pub type NetworkOrder<T> = BigEndian<T>;
154
155
156///Type aliases for primitive types
157pub mod types{
158	#![allow(non_camel_case_types)]
159
160	use super::*;
161
162	pub type i16_be   = BigEndian<i16>;
163	pub type i32_be   = BigEndian<i32>;
164	pub type i64_be   = BigEndian<i64>;
165	pub type isize_be = BigEndian<isize>;
166
167	pub type u16_be   = BigEndian<u16>;
168	pub type u32_be   = BigEndian<u32>;
169	pub type u64_be   = BigEndian<u64>;
170	pub type usize_be = BigEndian<usize>;
171
172	pub type i16_le   = LittleEndian<i16>;
173	pub type i32_le   = LittleEndian<i32>;
174	pub type i64_le   = LittleEndian<i64>;
175	pub type isize_le = LittleEndian<isize>;
176
177	pub type u16_le   = LittleEndian<u16>;
178	pub type u32_le   = LittleEndian<u32>;
179	pub type u64_le   = LittleEndian<u64>;
180	pub type usize_le = LittleEndian<usize>;
181
182	pub type i16_net   = NetworkOrder<i16>;
183	pub type i32_net   = NetworkOrder<i32>;
184	pub type i64_net   = NetworkOrder<i64>;
185	pub type isize_net = NetworkOrder<isize>;
186
187	pub type u16_net   = NetworkOrder<u16>;
188	pub type u32_net   = NetworkOrder<u32>;
189	pub type u64_net   = NetworkOrder<u64>;
190	pub type usize_net = NetworkOrder<usize>;
191}
192
193/*#[cfg(test)]
194mod tests{
195	use super::*;
196	use super::types::*;
197
198	#[test]
199	fn construct_big(){
200		//#[cfg(target_endian = "big")]{}
201
202	}
203}*/