+macro_rules! read_int_func {
+ ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
+ pub fn $s(src: &[u8]) -> ByteIOResult<$inttype> {
+ if src.len() < $size { return Err(ByteIOError::ReadError); }
+ unsafe {
+ let mut buf: $inttype = 0;
+ ptr::copy_nonoverlapping(src.as_ptr(), &mut buf as *mut $inttype as *mut u8, 1);
+ Ok(buf.$which())
+ }
+ }
+ }
+}
+
+read_int_func!(read_u16be, u16, 2, to_be);
+read_int_func!(read_u16le, u16, 2, to_le);
+read_int_func!(read_u32be, u32, 4, to_be);
+read_int_func!(read_u32le, u32, 4, to_le);
+read_int_func!(read_u64be, u64, 8, to_be);
+read_int_func!(read_u64le, u64, 8, to_le);
+
+pub fn read_u24be(src: &[u8]) -> ByteIOResult<u32> {
+ if src.len() < 3 { return Err(ByteIOError::ReadError); }
+ Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
+}
+pub fn read_u24le(src: &[u8]) -> ByteIOResult<u32> {
+ if src.len() < 3 { return Err(ByteIOError::ReadError); }
+ Ok((u32::from(src[2]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[0]))
+}
+