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