1 use crate::io::{AsyncRead, ReadBuf}; 2 3 use bytes::Buf; 4 use pin_project_lite::pin_project; 5 use std::future::Future; 6 use std::io; 7 use std::io::ErrorKind::UnexpectedEof; 8 use std::marker::PhantomPinned; 9 use std::pin::Pin; 10 use std::task::{Context, Poll}; 11 12 macro_rules! reader { 13 ($name:ident, $ty:ty, $reader:ident) => { 14 reader!($name, $ty, $reader, std::mem::size_of::<$ty>()); 15 }; 16 ($name:ident, $ty:ty, $reader:ident, $bytes:expr) => { 17 pin_project! { 18 #[doc(hidden)] 19 #[must_use = "futures do nothing unless you `.await` or poll them"] 20 pub struct $name<R> { 21 #[pin] 22 src: R, 23 buf: [u8; $bytes], 24 read: u8, 25 // Make this future `!Unpin` for compatibility with async trait methods. 26 #[pin] 27 _pin: PhantomPinned, 28 } 29 } 30 31 impl<R> $name<R> { 32 pub(crate) fn new(src: R) -> Self { 33 $name { 34 src, 35 buf: [0; $bytes], 36 read: 0, 37 _pin: PhantomPinned, 38 } 39 } 40 } 41 42 impl<R> Future for $name<R> 43 where 44 R: AsyncRead, 45 { 46 type Output = io::Result<$ty>; 47 48 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 49 let mut me = self.project(); 50 51 if *me.read == $bytes as u8 { 52 return Poll::Ready(Ok(Buf::$reader(&mut &me.buf[..]))); 53 } 54 55 while *me.read < $bytes as u8 { 56 let mut buf = ReadBuf::new(&mut me.buf[*me.read as usize..]); 57 58 *me.read += match me.src.as_mut().poll_read(cx, &mut buf) { 59 Poll::Pending => return Poll::Pending, 60 Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())), 61 Poll::Ready(Ok(())) => { 62 let n = buf.filled().len(); 63 if n == 0 { 64 return Poll::Ready(Err(UnexpectedEof.into())); 65 } 66 67 n as u8 68 } 69 }; 70 } 71 72 let num = Buf::$reader(&mut &me.buf[..]); 73 74 Poll::Ready(Ok(num)) 75 } 76 } 77 }; 78 } 79 80 macro_rules! reader8 { 81 ($name:ident, $ty:ty) => { 82 pin_project! { 83 /// Future returned from `read_u8` 84 #[doc(hidden)] 85 #[must_use = "futures do nothing unless you `.await` or poll them"] 86 pub struct $name<R> { 87 #[pin] 88 reader: R, 89 // Make this future `!Unpin` for compatibility with async trait methods. 90 #[pin] 91 _pin: PhantomPinned, 92 } 93 } 94 95 impl<R> $name<R> { 96 pub(crate) fn new(reader: R) -> $name<R> { 97 $name { 98 reader, 99 _pin: PhantomPinned, 100 } 101 } 102 } 103 104 impl<R> Future for $name<R> 105 where 106 R: AsyncRead, 107 { 108 type Output = io::Result<$ty>; 109 110 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 111 let me = self.project(); 112 113 let mut buf = [0; 1]; 114 let mut buf = ReadBuf::new(&mut buf); 115 match me.reader.poll_read(cx, &mut buf) { 116 Poll::Pending => Poll::Pending, 117 Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), 118 Poll::Ready(Ok(())) => { 119 if buf.filled().len() == 0 { 120 return Poll::Ready(Err(UnexpectedEof.into())); 121 } 122 123 Poll::Ready(Ok(buf.filled()[0] as $ty)) 124 } 125 } 126 } 127 } 128 }; 129 } 130 131 reader8!(ReadU8, u8); 132 reader8!(ReadI8, i8); 133 134 reader!(ReadU16, u16, get_u16); 135 reader!(ReadU32, u32, get_u32); 136 reader!(ReadU64, u64, get_u64); 137 reader!(ReadU128, u128, get_u128); 138 139 reader!(ReadI16, i16, get_i16); 140 reader!(ReadI32, i32, get_i32); 141 reader!(ReadI64, i64, get_i64); 142 reader!(ReadI128, i128, get_i128); 143 144 reader!(ReadF32, f32, get_f32); 145 reader!(ReadF64, f64, get_f64); 146 147 reader!(ReadU16Le, u16, get_u16_le); 148 reader!(ReadU32Le, u32, get_u32_le); 149 reader!(ReadU64Le, u64, get_u64_le); 150 reader!(ReadU128Le, u128, get_u128_le); 151 152 reader!(ReadI16Le, i16, get_i16_le); 153 reader!(ReadI32Le, i32, get_i32_le); 154 reader!(ReadI64Le, i64, get_i64_le); 155 reader!(ReadI128Le, i128, get_i128_le); 156 157 reader!(ReadF32Le, f32, get_f32_le); 158 reader!(ReadF64Le, f64, get_f64_le); 159