1#[inline]
2pub fn read(source: &mut dyn std::io::Read, len: usize) -> std::io::Result<Vec<u8>> {
3 let mut out = vec![];
4 if len == 0 {
5 source.read_to_end(&mut out)?;
6 } else {
7 out.resize(len, 0u8);
8 source.read_exact(&mut out)?;
9 }
10 return Ok(out);
11}
12
13#[inline]
14pub fn read_delimited(source: &mut dyn std::io::BufRead, delimiter: &[u8]) -> std::io::Result<Vec<u8>> {
15 let mut out = vec![];
16 let mut delim_buffer = vec![];
17 delim_buffer.resize(delimiter.len() - 1, 0u8);
18 loop {
19 source.read_until(delimiter[0], &mut out)?;
21
22 let mut delim_size = 0usize;
24 while delim_size < delimiter.len() - 1 {
25 let count = source.read(&mut delim_buffer[delim_size..])?;
26 if count == 0 {
27 out.extend(delim_buffer);
29 return Ok(out);
30 }
31 delim_size += count;
32 }
33
34 if delim_buffer == delimiter[1..] {
36 out.pop();
37 return Ok(out);
38 }
39
40 out.extend(&delim_buffer);
42 }
43}
44
45#[cfg(feature = "async")]
46pub mod async_ {
47 pub use futures::io::{
48 AsyncReadExt,
49 AsyncBufReadExt,
50 AsyncWriteExt,
51 };
52
53 #[inline]
54 pub async fn read<T: futures::io::AsyncReadExt + Unpin>(source: &mut T, len: usize) -> std::io::Result<Vec<u8>> {
55 let mut out = vec![];
56 if len == 0 {
57 source.read_to_end(&mut out).await?;
58 } else {
59 out.resize(len, 0u8);
60 source.read_exact(&mut out).await?;
61 }
62 return Ok(out);
63 }
64
65 #[inline]
66 pub async fn read_delimited<
67 T: futures::io::AsyncBufReadExt + Unpin,
68 >(source: &mut T, delimiter: &[u8]) -> std::io::Result<Vec<u8>> {
69 let mut out = vec![];
70 let mut delim_buffer = vec![];
71 delim_buffer.resize(delimiter.len() - 1, 0u8);
72 loop {
73 source.read_until(delimiter[0], &mut out).await?;
75
76 let mut delim_size = 0usize;
78 while delim_size < delimiter.len() - 1 {
79 let count = source.read(&mut delim_buffer[delim_size..]).await?;
80 if count == 0 {
81 out.extend(delim_buffer);
83 return Ok(out);
84 }
85 delim_size += count;
86 }
87
88 if delim_buffer == delimiter[1..] {
90 out.pop();
91 return Ok(out);
92 }
93
94 out.extend(&delim_buffer);
96 }
97 }
98}
99
100pub mod lowheap_error {
101 use std::fmt::Display;
102
103 #[derive(Debug)]
104 pub enum ReadErrorInner {
105 Io(std::io::Error),
106 Other(&'static str),
107 }
108
109 #[derive(Debug)]
110 pub struct ReadError {
111 pub node: &'static str,
112 pub inner: ReadErrorInner,
113 }
114
115 impl Display for ReadError {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 return format_args!("Error reading in node {}: {:?}", self.node, self.inner).fmt(f);
118 }
119 }
120
121 impl std::error::Error for ReadError { }
122
123 impl ReadError {
124 pub fn new(node: &'static str, text: &'static str) -> ReadError {
125 return ReadError {
126 node: node,
127 inner: ReadErrorInner::Other(text),
128 };
129 }
130 }
131
132 pub trait ReadErrCtx<T> {
133 fn errorize(self, node: &'static str, text: &'static str) -> Result<T, ReadError>;
134 }
135
136 impl<T, E> ReadErrCtx<T> for Result<T, E> {
137 fn errorize(self, node: &'static str, text: &'static str) -> Result<T, ReadError> {
138 match self {
139 Err(_) => return Err(ReadError {
140 node: node,
141 inner: ReadErrorInner::Other(text),
142 }),
143 Ok(v) => return Ok(v),
144 }
145 }
146 }
147
148 pub trait ReadErrCtxIo<T> {
149 fn errorize_io(self, node: &'static str) -> Result<T, ReadError>;
150 }
151
152 impl<T> ReadErrCtxIo<T> for Result<T, std::io::Error> {
153 fn errorize_io(self, node: &'static str) -> Result<T, ReadError> {
154 match self {
155 Err(e) => return Err(ReadError {
156 node: node,
157 inner: ReadErrorInner::Io(e),
158 }),
159 Ok(v) => return Ok(v),
160 }
161 }
162 }
163}
164
165#[cfg(not(noheap))]
166pub mod error {
167 use std::fmt::Display;
168
169 #[derive(Debug)]
170 pub enum ReadErrorInner {
171 Io(std::io::Error),
172 Other(String),
173 }
174
175 #[derive(Debug)]
176 pub struct ReadError {
177 pub node: &'static str,
178 pub inner: ReadErrorInner,
179 }
180
181 impl Display for ReadError {
182 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
183 return format_args!("Error reading in node {}: {:?}", self.node, self.inner).fmt(f);
184 }
185 }
186
187 impl std::error::Error for ReadError { }
188
189 impl ReadError {
190 pub fn new(node: &'static str, text: impl Into<String>) -> ReadError {
191 return ReadError {
192 node: node,
193 inner: ReadErrorInner::Other(text.into()),
194 };
195 }
196 }
197
198 pub trait ReadErrCtx<T> {
199 fn errorize(self, node: &'static str) -> Result<T, ReadError>;
200 }
201
202 impl<T, E: Display> ReadErrCtx<T> for Result<T, E> {
203 fn errorize(self, node: &'static str) -> Result<T, ReadError> {
204 match self {
205 Err(e) => return Err(ReadError {
206 node: node,
207 inner: ReadErrorInner::Other(e.to_string()),
208 }),
209 Ok(v) => return Ok(v),
210 }
211 }
212 }
213
214 pub trait ReadErrCtxIo<T> {
215 fn errorize_io(self, node: &'static str) -> Result<T, ReadError>;
216 }
217
218 impl<T> ReadErrCtxIo<T> for Result<T, std::io::Error> {
219 fn errorize_io(self, node: &'static str) -> Result<T, ReadError> {
220 match self {
221 Err(e) => return Err(ReadError {
222 node: node,
223 inner: ReadErrorInner::Io(e),
224 }),
225 Ok(v) => return Ok(v),
226 }
227 }
228 }
229}