use std::io::{
Cursor,
ErrorKind,
};
use qubit_io::{
BigEndian,
BinaryReader,
ByteOrder,
LittleEndian,
};
fn push_be_values(output: &mut Vec<u8>) {
output.extend_from_slice(&[0xaa, 0xbb]);
output.push(0x12);
output.push((-2_i8) as u8);
output.extend_from_slice(&0x1234_u16.to_be_bytes());
output.extend_from_slice(&0x1234_5678_u32.to_be_bytes());
output.extend_from_slice(&0x0123_4567_89ab_cdef_u64.to_be_bytes());
output.extend_from_slice(&0x0123_4567_89ab_cdef_fedc_ba98_7654_3210_u128.to_be_bytes());
output.extend_from_slice(&(-0x1234_i16).to_be_bytes());
output.extend_from_slice(&(-0x0123_4567_i32).to_be_bytes());
output.extend_from_slice(&(-0x0123_4567_89ab_cdef_i64).to_be_bytes());
output.extend_from_slice(&(-0x0123_4567_89ab_cdef_fedc_ba98_7654_3210_i128).to_be_bytes());
output.extend_from_slice(&12.5_f32.to_bits().to_be_bytes());
output.extend_from_slice(&(-25.25_f64).to_bits().to_be_bytes());
output.extend_from_slice(&2_u16.to_be_bytes());
output.extend_from_slice(b"hi");
output.extend_from_slice(&2_u32.to_be_bytes());
output.extend_from_slice(b"ok");
}
fn push_le_values(output: &mut Vec<u8>) {
output.extend_from_slice(&[0xaa, 0xbb]);
output.push(0x12);
output.push((-2_i8) as u8);
output.extend_from_slice(&0x1234_u16.to_le_bytes());
output.extend_from_slice(&0x1234_5678_u32.to_le_bytes());
output.extend_from_slice(&0x0123_4567_89ab_cdef_u64.to_le_bytes());
output.extend_from_slice(&0x0123_4567_89ab_cdef_fedc_ba98_7654_3210_u128.to_le_bytes());
output.extend_from_slice(&(-0x1234_i16).to_le_bytes());
output.extend_from_slice(&(-0x0123_4567_i32).to_le_bytes());
output.extend_from_slice(&(-0x0123_4567_89ab_cdef_i64).to_le_bytes());
output.extend_from_slice(&(-0x0123_4567_89ab_cdef_fedc_ba98_7654_3210_i128).to_le_bytes());
output.extend_from_slice(&12.5_f32.to_bits().to_le_bytes());
output.extend_from_slice(&(-25.25_f64).to_bits().to_le_bytes());
output.extend_from_slice(&2_u16.to_le_bytes());
output.extend_from_slice(b"hi");
output.extend_from_slice(&2_u32.to_le_bytes());
output.extend_from_slice(b"ok");
}
#[test]
fn test_binary_reader_reads_all_big_endian_methods() {
let mut bytes = Vec::new();
push_be_values(&mut bytes);
let mut reader = BinaryReader::<_, BigEndian>::new(Cursor::new(bytes));
assert_eq!(ByteOrder::BigEndian, reader.byte_order());
let mut prefix = [0u8; 2];
std::io::Read::read_exact(&mut reader, &mut prefix).expect("bytes should be read");
assert_eq!([0xaa, 0xbb], prefix);
assert_eq!(0x12, reader.read_u8().expect("u8 should be read"));
assert_eq!(-2, reader.read_i8().expect("i8 should be read"));
assert_eq!(0x1234, reader.read_u16().expect("u16 should be read"));
assert_eq!(0x1234_5678, reader.read_u32().expect("u32 should be read"));
assert_eq!(0x0123_4567_89ab_cdef, reader.read_u64().expect("u64 should be read"));
assert_eq!(
0x0123_4567_89ab_cdef_fedc_ba98_7654_3210,
reader.read_u128().expect("u128 should be read")
);
assert_eq!(-0x1234, reader.read_i16().expect("i16 should be read"));
assert_eq!(-0x0123_4567, reader.read_i32().expect("i32 should be read"));
assert_eq!(-0x0123_4567_89ab_cdef, reader.read_i64().expect("i64 should be read"));
assert_eq!(
-0x0123_4567_89ab_cdef_fedc_ba98_7654_3210,
reader.read_i128().expect("i128 should be read")
);
assert_eq!(12.5, reader.read_f32().expect("f32 should be read"));
assert_eq!(-25.25, reader.read_f64().expect("f64 should be read"));
assert_eq!(
"hi",
reader
.read_utf8_string_u16(usize::MAX)
.expect("u16 string should be read")
);
assert_eq!(
"ok",
reader
.read_utf8_string_u32(usize::MAX)
.expect("u32 string should be read")
);
}
#[test]
fn test_binary_reader_reads_little_endian_and_exposes_accessors() {
let mut bytes = Vec::new();
push_le_values(&mut bytes);
let len = bytes.len() as u64;
let mut reader = BinaryReader::<_, LittleEndian>::new(Cursor::new(bytes));
assert_eq!(ByteOrder::LittleEndian, reader.byte_order());
assert_eq!(0, reader.get_ref().position());
reader.get_mut().set_position(0);
let mut prefix = [0u8; 2];
std::io::Read::read_exact(&mut reader, &mut prefix).expect("bytes should be read");
assert_eq!([0xaa, 0xbb], prefix);
assert_eq!(0x12, reader.read_u8().expect("u8 should be read"));
assert_eq!(-2, reader.read_i8().expect("i8 should be read"));
assert_eq!(0x1234, reader.read_u16().expect("u16 should be read"));
assert_eq!(0x1234_5678, reader.read_u32().expect("u32 should be read"));
assert_eq!(0x0123_4567_89ab_cdef, reader.read_u64().expect("u64 should be read"));
assert_eq!(
0x0123_4567_89ab_cdef_fedc_ba98_7654_3210,
reader.read_u128().expect("u128 should be read")
);
assert_eq!(-0x1234, reader.read_i16().expect("i16 should be read"));
assert_eq!(-0x0123_4567, reader.read_i32().expect("i32 should be read"));
assert_eq!(-0x0123_4567_89ab_cdef, reader.read_i64().expect("i64 should be read"));
assert_eq!(
-0x0123_4567_89ab_cdef_fedc_ba98_7654_3210,
reader.read_i128().expect("i128 should be read")
);
assert_eq!(12.5, reader.read_f32().expect("f32 should be read"));
assert_eq!(-25.25, reader.read_f64().expect("f64 should be read"));
assert_eq!(
"hi",
reader
.read_utf8_string_u16(usize::MAX)
.expect("u16 string should be read")
);
assert_eq!(
"ok",
reader
.read_utf8_string_u32(usize::MAX)
.expect("u32 string should be read")
);
assert_eq!(len, reader.into_inner().position());
}
#[test]
fn test_binary_reader_reports_read_and_utf8_errors() {
let mut reader = BinaryReader::<_, BigEndian>::new(Cursor::new(vec![0x12]));
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_u16().expect_err("truncated u16 should fail").kind()
);
let mut reader = BinaryReader::<_, BigEndian>::new(Cursor::new(vec![0x00, 0x02, 0xff, 0xff]));
assert_eq!(
ErrorKind::InvalidData,
reader
.read_utf8_string_u16(usize::MAX)
.expect_err("invalid UTF-8 should fail")
.kind()
);
let mut reader = BinaryReader::<_, BigEndian>::new(Cursor::new(vec![0x00, 0x03, b'a', b'b', b'c']));
assert_eq!(
ErrorKind::InvalidData,
reader
.read_utf8_string_u16(2)
.expect_err("oversized u16 string should fail")
.kind()
);
let mut reader = BinaryReader::<_, BigEndian>::new(Cursor::new(vec![0x00, 0x00, 0x00, 0x03, b'a', b'b', b'c']));
assert_eq!(
ErrorKind::InvalidData,
reader
.read_utf8_string_u32(2)
.expect_err("oversized u32 string should fail")
.kind()
);
}
#[test]
fn test_binary_reader_reports_truncated_scalar_errors_for_all_methods() {
let mut reader = BinaryReader::<_, LittleEndian>::new(Cursor::new(Vec::new()));
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_u8().expect_err("u8 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_i8().expect_err("i8 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_u16().expect_err("u16 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_u32().expect_err("u32 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_u64().expect_err("u64 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_u128().expect_err("u128 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_i16().expect_err("i16 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_i32().expect_err("i32 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_i64().expect_err("i64 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_i128().expect_err("i128 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_f32().expect_err("f32 should fail").kind()
);
assert_eq!(
ErrorKind::UnexpectedEof,
reader.read_f64().expect_err("f64 should fail").kind()
);
}
#[test]
fn test_binary_reader_read_and_seek_delegate_to_inner_reader() {
let mut reader = qubit_io::BinaryReader::<_, qubit_io::LittleEndian>::new(std::io::Cursor::new(vec![1, 2, 3, 4]));
std::io::Seek::seek(&mut reader, std::io::SeekFrom::Start(1)).expect("seeking through BinaryReader should succeed");
let mut bytes = [0_u8; 2];
std::io::Read::read_exact(&mut reader, &mut bytes).expect("reading through BinaryReader should succeed");
assert_eq!(bytes, [2, 3]);
}