#![cfg(all(feature = "std", feature = "base64"))]
use crate::Error;
use crate::{Limited, Limits, ReadXdr, WriteXdr};
use std::io::{self, Cursor};
#[test]
fn test_read_interrupts_and_residuals() -> Result<(), Error> {
let v_bytes = [1u32.to_xdr(Limits::none())?, 2u32.to_xdr(Limits::none())?].concat();
{
let mut cursor = Limited::new(Interrupted::new(Cursor::new(&v_bytes)), Limits::none());
assert_eq!(u32::read_xdr(&mut cursor), Ok(1u32));
assert_eq!(u32::read_xdr(&mut cursor), Ok(2u32));
}
{
assert_eq!(
u32::read_xdr_to_end(&mut Limited::new(
Interrupted::new(Cursor::new(&v_bytes)),
Limits::none(),
)),
Err(Error::Invalid)
);
assert_eq!(
u64::read_xdr_to_end(&mut Limited::new(
Interrupted::new(Cursor::new(&v_bytes)),
Limits::none(),
)),
Ok((1u64 << 32) | 2u64)
);
}
{
assert_eq!(u32::from_xdr(&v_bytes, Limits::none()), Err(Error::Invalid));
assert_eq!(
u64::from_xdr(&v_bytes, Limits::none()),
Ok((1u64 << 32) | 2u64)
);
}
{
use base64::Engine;
let v_base64 = base64::engine::general_purpose::STANDARD.encode(v_bytes);
assert_eq!(
u32::from_xdr_base64(&v_base64, Limits::none()),
Err(Error::Invalid)
);
assert_eq!(
u64::from_xdr_base64(&v_base64, Limits::none()),
Ok((1u64 << 32) | 2u64)
);
}
Ok(())
}
struct Interrupted<R: io::Read> {
next_read_interrupts: bool,
r: R,
}
impl<R: io::Read> Interrupted<R> {
pub fn new(r: R) -> Self {
Self {
next_read_interrupts: true,
r,
}
}
}
impl<R: io::Read> io::Read for Interrupted<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if self.next_read_interrupts {
self.next_read_interrupts = false;
Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted"))
} else {
self.r.read(buf)
}
}
}