#[macro_use] extern crate quickcheck; extern crate byte; extern crate byteorder; use byte::ctx::*; use byte::*; use byteorder::*; #[test] fn test_str() { let bytes: &[u8] = b"abcd\0efg"; let mut offset = 0; assert_eq!( bytes .read_with::<&str>(&mut offset, Str::Delimiter(NULL)) .unwrap(), "abcd" ); assert_eq!(offset, 5); let bytes: &[u8] = b"abcdefghijklmnopqrstuvwxyz"; assert_eq!( TryRead::try_read(bytes, Str::Len(15)).unwrap(), ("abcdefghijklmno", 15) ); assert_eq!( TryRead::try_read(bytes, Str::Len(26)).unwrap(), ("abcdefghijklmnopqrstuvwxyz", 26) ); assert!(bytes.read_with::<&str>(&mut 0, Str::Len(27)).is_err()); assert!(bytes.read_with::<&str>(&mut 27, Str::Len(0)).is_err()); assert!(bytes.read_with::<&str>(&mut 26, Str::Len(1)).is_err()); } #[test] fn test_str_delimitor() { let bytes: &[u8] = b""; assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 0)).unwrap(), ("", 0) ); let bytes: &[u8] = b"abcdefg"; assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 6)).unwrap(), ("abcdef", 6) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 7)).unwrap(), ("abcdefg", 7) ); let bytes: &[u8] = b"\0abcdefg"; assert_eq!( TryRead::try_read(bytes, Str::Delimiter(NULL)).unwrap(), ("", 1) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 0)).unwrap(), ("", 0) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 1)).unwrap(), ("", 1) ); let bytes: &[u8] = b"abcd\0efg"; assert_eq!( TryRead::try_read(bytes, Str::Delimiter(NULL)).unwrap(), ("abcd", 5) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 4)).unwrap(), ("abcd", 4) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 5)).unwrap(), ("abcd", 5) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 6)).unwrap(), ("abcd", 5) ); let bytes: &[u8] = b"abcdefg\0"; assert_eq!( TryRead::try_read(bytes, Str::Delimiter(NULL)).unwrap(), ("abcdefg", 8) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 8)).unwrap(), ("abcdefg", 8) ); assert_eq!( TryRead::try_read(bytes, Str::DelimiterUntil(NULL, 20)).unwrap(), ("abcdefg", 8) ); let bytes: &[u8] = b""; assert!(bytes .read_with::<&str>(&mut 0, Str::Delimiter(NULL)) .is_err()); assert!(bytes .read_with::<&str>(&mut 0, Str::DelimiterUntil(NULL, 1)) .is_err()); let bytes: &[u8] = b"abcdefg"; assert!(bytes .read_with::<&str>(&mut 0, Str::DelimiterUntil(NULL, 8)) .is_err()); assert!(bytes .read_with::<&str>(&mut 0, Str::Delimiter(NULL)) .is_err()); } #[test] fn test_str_write() { let mut bytes = [0; 20]; let mut offset = 0; bytes.write(&mut offset, "hello world!").unwrap(); assert_eq!(offset, 12); assert_eq!(&bytes[..offset], b"hello world!" as &[u8]); let bytes = &mut [0; 10]; assert!(bytes.write(&mut 0, "hello world!").is_err()); } #[test] fn test_bytes() { let bytes: &[u8] = &[0xde, 0xad, 0xbe, 0xef]; assert_eq!( TryRead::try_read(&bytes, Bytes::Len(4)).unwrap(), (&bytes[..], 4) ); assert!(bytes.read_with::<&[u8]>(&mut 5, Bytes::Len(0)).is_err()); let mut write = [0; 5]; assert_eq!(TryWrite::try_write(bytes, &mut write, ()).unwrap(), 4); assert_eq!(&write[..4], bytes); assert!([0u8; 3].write(&mut 0, bytes).is_err()); } #[test] fn test_bytes_pattern() { let bytes: &[u8] = b"abcdefghijk"; assert_eq!( TryRead::try_read(bytes, Bytes::Pattern(b"abc")).unwrap(), (&b"abc"[..], 3) ); assert_eq!( TryRead::try_read(bytes, Bytes::Pattern(b"cde")).unwrap(), (&b"abcde"[..], 5) ); assert_eq!( TryRead::try_read(bytes, Bytes::Pattern(b"jk")).unwrap(), (&b"abcdefghijk"[..], 11) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"abc", 3)).unwrap(), (&b"abc"[..], 3) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"abc", 4)).unwrap(), (&b"abc"[..], 3) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"cde", 3)).unwrap(), (&b"abc"[..], 3) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"cde", 4)).unwrap(), (&b"abcd"[..], 4) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"cde", 5)).unwrap(), (&b"abcde"[..], 5) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"cde", 6)).unwrap(), (&b"abcde"[..], 5) ); assert_eq!( TryRead::try_read(bytes, Bytes::PatternUntil(b"xyz", 5)).unwrap(), (&b"abcde"[..], 5) ); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::Pattern(b"xyz")) .is_err()); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::Pattern(b"")) .is_err()); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::PatternUntil(b"", 3)) .is_err()); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::PatternUntil(b"abcd", 3)) .is_err()); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::PatternUntil(b"xyz", 20)) .is_err()); let bytes: &[u8] = b""; assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::Pattern(b"xyz")) .is_err()); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::PatternUntil(b"abc", 3)) .is_err()); assert!(bytes .read_with::<&[u8]>(&mut 0, Bytes::PatternUntil(b"abc", 4)) .is_err()); } #[test] fn test_bool() { let bytes = [0x00, 0x01, 0x80, 0xff]; assert_eq!(bytes.read::(&mut 0).unwrap(), false); assert_eq!(bytes.read::(&mut 1).unwrap(), true); assert_eq!(bytes.read::(&mut 2).unwrap(), true); assert_eq!(bytes.read::(&mut 3).unwrap(), true); let mut bytes = [0u8; 2]; bytes.write(&mut 0, false).unwrap(); bytes.write(&mut 1, true).unwrap(); assert!(bytes[0] == 0); assert!(bytes[1] != 0); } #[test] fn test_iter() { let bytes: &[u8] = b"hello\0world\0dead\0beef\0more"; let mut offset = 0; { let mut iter = bytes.read_iter(&mut offset, Str::Delimiter(NULL)); assert_eq!(iter.next(), Some("hello")); assert_eq!(iter.next(), Some("world")); assert_eq!(iter.next(), Some("dead")); assert_eq!(iter.next(), Some("beef")); assert_eq!(iter.next(), None); } assert_eq!(offset, 22); } macro_rules! test_num { ($test_name: tt, $ty: ty, $byteorder_read_fn: tt, $byteorder_write_fn: tt) => { quickcheck! { fn $test_name (num: $ty) -> () { let mut bytes = [0u8; 8]; bytes.write_with(&mut 0, num, LE).unwrap(); let result = LittleEndian::$byteorder_read_fn(&bytes); assert_eq!(result, num); let mut bytes = [0u8; 8]; LittleEndian::$byteorder_write_fn(&mut bytes, num); let result: $ty = bytes.read_with(&mut 0, LE).unwrap(); assert_eq!(result, num); let mut bytes = [0u8; 8]; bytes.write_with(&mut 0, num, BE).unwrap(); let result = BigEndian::$byteorder_read_fn(&bytes); assert_eq!(result, num); let mut bytes = [0u8; 8]; BigEndian::$byteorder_write_fn(&mut bytes, num); let result: $ty = bytes.read_with(&mut 0, BE).unwrap(); assert_eq!(result, num); } } }; } test_num!(test_u16, u16, read_u16, write_u16); test_num!(test_u32, u32, read_u32, write_u32); test_num!(test_u64, u64, read_u64, write_u64); test_num!(test_i16, i16, read_i16, write_i16); test_num!(test_i32, i32, read_i32, write_i32); test_num!(test_i64, i64, read_i64, write_i64); test_num!(test_f32, f32, read_f32, write_f32); test_num!(test_f64, f64, read_f64, write_f64); struct Header<'a> { name: &'a str, enabled: bool, } impl<'a> TryRead<'a, Endian> for Header<'a> { fn try_read(bytes: &'a [u8], endian: Endian) -> Result<(Self, usize)> { let offset = &mut 0; let name_len = bytes.read_with::(offset, endian)? as usize; let header = Header { name: bytes.read_with::<&str>(offset, Str::Len(name_len))?, enabled: bytes.read(offset)?, }; Ok((header, *offset)) } } impl<'a> TryWrite for Header<'a> { fn try_write(self, bytes: &mut [u8], endian: Endian) -> Result { let offset = &mut 0; bytes.write_with(offset, self.name.len() as u16, endian)?; bytes.write(offset, self.name)?; bytes.write(offset, self.enabled)?; Ok(*offset) } } #[test] fn test_api() { let bytes = [0, 5, b"H"[0], b"E"[0], b"L"[0], b"L"[0], b"O"[0], 0]; let header: Header = bytes.read_with(&mut 0, BE).unwrap(); assert_eq!(header.name, "HELLO"); assert_eq!(header.enabled, false); let mut write = [0u8; 8]; write.write_with(&mut 0, header, BE).unwrap(); assert_eq!(write, bytes); } #[derive(Debug, Clone, PartialEq, Eq)] struct Empty; impl<'a> TryRead<'a, ()> for Empty { fn try_read(bytes: &'a [u8], _ctx: ()) -> Result<(Self, usize)> { Ok((Self, 0)) } } impl TryWrite<()> for Empty { fn try_write(self, bytes: &mut [u8], _ctx: ()) -> Result { Ok(0) } } #[test] fn test_empty() { let empty_bytes: [u8; 0] = []; let mut offset = 0; let empty: Empty = empty_bytes.read(&mut offset).unwrap(); assert_eq!(empty, Empty); assert_eq!(offset, 0); let zero_bytes = [0; 8]; let mut offset = 0; let empty: Empty = zero_bytes.read(&mut offset).unwrap(); assert_eq!(empty, Empty); assert_eq!(offset, 0); let mut write_empty_bytes: [u8; 0] = []; let mut offset = 0; write_empty_bytes.write(&mut offset, Empty).unwrap(); assert_eq!(write_empty_bytes, empty_bytes); assert_eq!(offset, 0); let mut write_zero_bytes = [0u8; 4]; let mut offset = 0; write_zero_bytes.write(&mut offset, Empty).unwrap(); assert_eq!(write_zero_bytes, [0u8; 4]); assert_eq!(offset, 0); }