]>
Commit | Line | Data |
---|---|---|
a2a8927a | 1 | use super::{repeat, Cursor, ReadBuf, SeekFrom}; |
1b1a35ee | 2 | use crate::cmp::{self, min}; |
1b1a35ee | 3 | use crate::io::{self, IoSlice, IoSliceMut}; |
6a06907d | 4 | use crate::io::{BufRead, BufReader, Read, Seek, Write}; |
a2a8927a | 5 | use crate::mem::MaybeUninit; |
1b1a35ee XL |
6 | use crate::ops::Deref; |
7 | ||
8 | #[test] | |
9 | #[cfg_attr(target_os = "emscripten", ignore)] | |
10 | fn read_until() { | |
11 | let mut buf = Cursor::new(&b"12"[..]); | |
12 | let mut v = Vec::new(); | |
13 | assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2); | |
14 | assert_eq!(v, b"12"); | |
15 | ||
16 | let mut buf = Cursor::new(&b"1233"[..]); | |
17 | let mut v = Vec::new(); | |
18 | assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3); | |
19 | assert_eq!(v, b"123"); | |
20 | v.truncate(0); | |
21 | assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1); | |
22 | assert_eq!(v, b"3"); | |
23 | v.truncate(0); | |
24 | assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0); | |
25 | assert_eq!(v, []); | |
26 | } | |
27 | ||
28 | #[test] | |
29 | fn split() { | |
30 | let buf = Cursor::new(&b"12"[..]); | |
31 | let mut s = buf.split(b'3'); | |
32 | assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); | |
33 | assert!(s.next().is_none()); | |
34 | ||
35 | let buf = Cursor::new(&b"1233"[..]); | |
36 | let mut s = buf.split(b'3'); | |
37 | assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); | |
38 | assert_eq!(s.next().unwrap().unwrap(), vec![]); | |
39 | assert!(s.next().is_none()); | |
40 | } | |
41 | ||
42 | #[test] | |
43 | fn read_line() { | |
44 | let mut buf = Cursor::new(&b"12"[..]); | |
45 | let mut v = String::new(); | |
46 | assert_eq!(buf.read_line(&mut v).unwrap(), 2); | |
47 | assert_eq!(v, "12"); | |
48 | ||
49 | let mut buf = Cursor::new(&b"12\n\n"[..]); | |
50 | let mut v = String::new(); | |
51 | assert_eq!(buf.read_line(&mut v).unwrap(), 3); | |
52 | assert_eq!(v, "12\n"); | |
53 | v.truncate(0); | |
54 | assert_eq!(buf.read_line(&mut v).unwrap(), 1); | |
55 | assert_eq!(v, "\n"); | |
56 | v.truncate(0); | |
57 | assert_eq!(buf.read_line(&mut v).unwrap(), 0); | |
58 | assert_eq!(v, ""); | |
59 | } | |
60 | ||
61 | #[test] | |
62 | fn lines() { | |
63 | let buf = Cursor::new(&b"12\r"[..]); | |
64 | let mut s = buf.lines(); | |
65 | assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string()); | |
66 | assert!(s.next().is_none()); | |
67 | ||
68 | let buf = Cursor::new(&b"12\r\n\n"[..]); | |
69 | let mut s = buf.lines(); | |
70 | assert_eq!(s.next().unwrap().unwrap(), "12".to_string()); | |
71 | assert_eq!(s.next().unwrap().unwrap(), "".to_string()); | |
72 | assert!(s.next().is_none()); | |
73 | } | |
74 | ||
136023e0 XL |
75 | #[test] |
76 | fn buf_read_has_data_left() { | |
77 | let mut buf = Cursor::new(&b"abcd"[..]); | |
78 | assert!(buf.has_data_left().unwrap()); | |
79 | buf.read_exact(&mut [0; 2]).unwrap(); | |
80 | assert!(buf.has_data_left().unwrap()); | |
81 | buf.read_exact(&mut [0; 2]).unwrap(); | |
82 | assert!(!buf.has_data_left().unwrap()); | |
83 | } | |
84 | ||
1b1a35ee XL |
85 | #[test] |
86 | fn read_to_end() { | |
87 | let mut c = Cursor::new(&b""[..]); | |
88 | let mut v = Vec::new(); | |
89 | assert_eq!(c.read_to_end(&mut v).unwrap(), 0); | |
90 | assert_eq!(v, []); | |
91 | ||
92 | let mut c = Cursor::new(&b"1"[..]); | |
93 | let mut v = Vec::new(); | |
94 | assert_eq!(c.read_to_end(&mut v).unwrap(), 1); | |
95 | assert_eq!(v, b"1"); | |
96 | ||
97 | let cap = 1024 * 1024; | |
98 | let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>(); | |
99 | let mut v = Vec::new(); | |
100 | let (a, b) = data.split_at(data.len() / 2); | |
101 | assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len()); | |
102 | assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len()); | |
103 | assert_eq!(v, data); | |
104 | } | |
105 | ||
106 | #[test] | |
107 | fn read_to_string() { | |
108 | let mut c = Cursor::new(&b""[..]); | |
109 | let mut v = String::new(); | |
110 | assert_eq!(c.read_to_string(&mut v).unwrap(), 0); | |
111 | assert_eq!(v, ""); | |
112 | ||
113 | let mut c = Cursor::new(&b"1"[..]); | |
114 | let mut v = String::new(); | |
115 | assert_eq!(c.read_to_string(&mut v).unwrap(), 1); | |
116 | assert_eq!(v, "1"); | |
117 | ||
118 | let mut c = Cursor::new(&b"\xff"[..]); | |
119 | let mut v = String::new(); | |
120 | assert!(c.read_to_string(&mut v).is_err()); | |
121 | } | |
122 | ||
123 | #[test] | |
124 | fn read_exact() { | |
125 | let mut buf = [0; 4]; | |
126 | ||
127 | let mut c = Cursor::new(&b""[..]); | |
128 | assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); | |
129 | ||
130 | let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..])); | |
131 | c.read_exact(&mut buf).unwrap(); | |
132 | assert_eq!(&buf, b"1234"); | |
133 | c.read_exact(&mut buf).unwrap(); | |
134 | assert_eq!(&buf, b"5678"); | |
135 | assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); | |
136 | } | |
137 | ||
138 | #[test] | |
139 | fn read_exact_slice() { | |
140 | let mut buf = [0; 4]; | |
141 | ||
142 | let mut c = &b""[..]; | |
143 | assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); | |
144 | ||
145 | let mut c = &b"123"[..]; | |
146 | assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); | |
147 | // make sure the optimized (early returning) method is being used | |
148 | assert_eq!(&buf, &[0; 4]); | |
149 | ||
150 | let mut c = &b"1234"[..]; | |
151 | c.read_exact(&mut buf).unwrap(); | |
152 | assert_eq!(&buf, b"1234"); | |
153 | ||
154 | let mut c = &b"56789"[..]; | |
155 | c.read_exact(&mut buf).unwrap(); | |
156 | assert_eq!(&buf, b"5678"); | |
157 | assert_eq!(c, b"9"); | |
158 | } | |
159 | ||
a2a8927a XL |
160 | #[test] |
161 | fn read_buf_exact() { | |
162 | let mut buf = [0; 4]; | |
163 | let mut buf = ReadBuf::new(&mut buf); | |
164 | ||
165 | let mut c = Cursor::new(&b""[..]); | |
166 | assert_eq!(c.read_buf_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); | |
167 | ||
168 | let mut c = Cursor::new(&b"123456789"[..]); | |
169 | c.read_buf_exact(&mut buf).unwrap(); | |
170 | assert_eq!(buf.filled(), b"1234"); | |
171 | ||
172 | buf.clear(); | |
173 | ||
174 | c.read_buf_exact(&mut buf).unwrap(); | |
175 | assert_eq!(buf.filled(), b"5678"); | |
176 | ||
177 | buf.clear(); | |
178 | ||
179 | assert_eq!(c.read_buf_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); | |
180 | } | |
181 | ||
1b1a35ee XL |
182 | #[test] |
183 | fn take_eof() { | |
184 | struct R; | |
185 | ||
186 | impl Read for R { | |
187 | fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { | |
5099ac24 | 188 | Err(io::const_io_error!(io::ErrorKind::Other, "")) |
1b1a35ee XL |
189 | } |
190 | } | |
191 | impl BufRead for R { | |
192 | fn fill_buf(&mut self) -> io::Result<&[u8]> { | |
5099ac24 | 193 | Err(io::const_io_error!(io::ErrorKind::Other, "")) |
1b1a35ee XL |
194 | } |
195 | fn consume(&mut self, _amt: usize) {} | |
196 | } | |
197 | ||
198 | let mut buf = [0; 1]; | |
199 | assert_eq!(0, R.take(0).read(&mut buf).unwrap()); | |
200 | assert_eq!(b"", R.take(0).fill_buf().unwrap()); | |
201 | } | |
202 | ||
203 | fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) { | |
204 | let mut cat = Vec::new(); | |
205 | loop { | |
206 | let consume = { | |
207 | let buf1 = br1.fill_buf().unwrap(); | |
208 | let buf2 = br2.fill_buf().unwrap(); | |
209 | let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() }; | |
210 | assert_eq!(buf1[..minlen], buf2[..minlen]); | |
211 | cat.extend_from_slice(&buf1[..minlen]); | |
212 | minlen | |
213 | }; | |
214 | if consume == 0 { | |
215 | break; | |
216 | } | |
217 | br1.consume(consume); | |
218 | br2.consume(consume); | |
219 | } | |
220 | assert_eq!(br1.fill_buf().unwrap().len(), 0); | |
221 | assert_eq!(br2.fill_buf().unwrap().len(), 0); | |
222 | assert_eq!(&cat[..], &exp[..]) | |
223 | } | |
224 | ||
225 | #[test] | |
226 | fn chain_bufread() { | |
227 | let testdata = b"ABCDEFGHIJKL"; | |
228 | let chain1 = | |
229 | (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]); | |
230 | let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]); | |
231 | cmp_bufread(chain1, chain2, &testdata[..]); | |
232 | } | |
233 | ||
6a06907d XL |
234 | #[test] |
235 | fn bufreader_size_hint() { | |
236 | let testdata = b"ABCDEFGHIJKL"; | |
237 | let mut buf_reader = BufReader::new(&testdata[..]); | |
238 | assert_eq!(buf_reader.buffer().len(), 0); | |
239 | ||
240 | let buffer_length = testdata.len(); | |
241 | buf_reader.fill_buf().unwrap(); | |
242 | ||
243 | // Check that size hint matches buffer contents | |
244 | let mut buffered_bytes = buf_reader.bytes(); | |
245 | let (lower_bound, _upper_bound) = buffered_bytes.size_hint(); | |
246 | assert_eq!(lower_bound, buffer_length); | |
247 | ||
248 | // Check that size hint matches buffer contents after advancing | |
249 | buffered_bytes.next().unwrap().unwrap(); | |
250 | let (lower_bound, _upper_bound) = buffered_bytes.size_hint(); | |
251 | assert_eq!(lower_bound, buffer_length - 1); | |
252 | } | |
253 | ||
254 | #[test] | |
255 | fn empty_size_hint() { | |
256 | let size_hint = io::empty().bytes().size_hint(); | |
257 | assert_eq!(size_hint, (0, Some(0))); | |
258 | } | |
259 | ||
136023e0 XL |
260 | #[test] |
261 | fn slice_size_hint() { | |
262 | let size_hint = (&[1, 2, 3]).bytes().size_hint(); | |
263 | assert_eq!(size_hint, (3, Some(3))); | |
264 | } | |
265 | ||
266 | #[test] | |
267 | fn take_size_hint() { | |
268 | let size_hint = (&[1, 2, 3]).take(2).bytes().size_hint(); | |
269 | assert_eq!(size_hint, (2, Some(2))); | |
270 | ||
271 | let size_hint = (&[1, 2, 3]).take(4).bytes().size_hint(); | |
272 | assert_eq!(size_hint, (3, Some(3))); | |
273 | ||
274 | let size_hint = io::repeat(0).take(3).bytes().size_hint(); | |
275 | assert_eq!(size_hint, (3, Some(3))); | |
276 | } | |
277 | ||
6a06907d XL |
278 | #[test] |
279 | fn chain_empty_size_hint() { | |
280 | let chain = io::empty().chain(io::empty()); | |
281 | let size_hint = chain.bytes().size_hint(); | |
282 | assert_eq!(size_hint, (0, Some(0))); | |
283 | } | |
284 | ||
285 | #[test] | |
286 | fn chain_size_hint() { | |
287 | let testdata = b"ABCDEFGHIJKL"; | |
288 | let mut buf_reader_1 = BufReader::new(&testdata[..6]); | |
289 | let mut buf_reader_2 = BufReader::new(&testdata[6..]); | |
290 | ||
291 | buf_reader_1.fill_buf().unwrap(); | |
292 | buf_reader_2.fill_buf().unwrap(); | |
293 | ||
294 | let chain = buf_reader_1.chain(buf_reader_2); | |
295 | let size_hint = chain.bytes().size_hint(); | |
136023e0 | 296 | assert_eq!(size_hint, (testdata.len(), Some(testdata.len()))); |
6a06907d XL |
297 | } |
298 | ||
1b1a35ee XL |
299 | #[test] |
300 | fn chain_zero_length_read_is_not_eof() { | |
301 | let a = b"A"; | |
302 | let b = b"B"; | |
303 | let mut s = String::new(); | |
304 | let mut chain = (&a[..]).chain(&b[..]); | |
305 | chain.read(&mut []).unwrap(); | |
306 | chain.read_to_string(&mut s).unwrap(); | |
307 | assert_eq!("AB", s); | |
308 | } | |
309 | ||
310 | #[bench] | |
311 | #[cfg_attr(target_os = "emscripten", ignore)] | |
312 | fn bench_read_to_end(b: &mut test::Bencher) { | |
313 | b.iter(|| { | |
314 | let mut lr = repeat(1).take(10000000); | |
315 | let mut vec = Vec::with_capacity(1024); | |
c295e0f8 | 316 | super::default_read_to_end(&mut lr, &mut vec) |
1b1a35ee XL |
317 | }); |
318 | } | |
319 | ||
320 | #[test] | |
321 | fn seek_len() -> io::Result<()> { | |
322 | let mut c = Cursor::new(vec![0; 15]); | |
323 | assert_eq!(c.stream_len()?, 15); | |
324 | ||
325 | c.seek(SeekFrom::End(0))?; | |
326 | let old_pos = c.stream_position()?; | |
327 | assert_eq!(c.stream_len()?, 15); | |
328 | assert_eq!(c.stream_position()?, old_pos); | |
329 | ||
330 | c.seek(SeekFrom::Start(7))?; | |
331 | c.seek(SeekFrom::Current(2))?; | |
332 | let old_pos = c.stream_position()?; | |
333 | assert_eq!(c.stream_len()?, 15); | |
334 | assert_eq!(c.stream_position()?, old_pos); | |
335 | ||
336 | Ok(()) | |
337 | } | |
338 | ||
339 | #[test] | |
340 | fn seek_position() -> io::Result<()> { | |
341 | // All `asserts` are duplicated here to make sure the method does not | |
342 | // change anything about the seek state. | |
343 | let mut c = Cursor::new(vec![0; 15]); | |
344 | assert_eq!(c.stream_position()?, 0); | |
345 | assert_eq!(c.stream_position()?, 0); | |
346 | ||
347 | c.seek(SeekFrom::End(0))?; | |
348 | assert_eq!(c.stream_position()?, 15); | |
349 | assert_eq!(c.stream_position()?, 15); | |
350 | ||
351 | c.seek(SeekFrom::Start(7))?; | |
352 | c.seek(SeekFrom::Current(2))?; | |
353 | assert_eq!(c.stream_position()?, 9); | |
354 | assert_eq!(c.stream_position()?, 9); | |
355 | ||
356 | c.seek(SeekFrom::End(-3))?; | |
357 | c.seek(SeekFrom::Current(1))?; | |
358 | c.seek(SeekFrom::Current(-5))?; | |
359 | assert_eq!(c.stream_position()?, 8); | |
360 | assert_eq!(c.stream_position()?, 8); | |
361 | ||
136023e0 XL |
362 | c.rewind()?; |
363 | assert_eq!(c.stream_position()?, 0); | |
364 | assert_eq!(c.stream_position()?, 0); | |
365 | ||
1b1a35ee XL |
366 | Ok(()) |
367 | } | |
368 | ||
369 | // A simple example reader which uses the default implementation of | |
370 | // read_to_end. | |
371 | struct ExampleSliceReader<'a> { | |
372 | slice: &'a [u8], | |
373 | } | |
374 | ||
375 | impl<'a> Read for ExampleSliceReader<'a> { | |
376 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
377 | let len = cmp::min(self.slice.len(), buf.len()); | |
378 | buf[..len].copy_from_slice(&self.slice[..len]); | |
379 | self.slice = &self.slice[len..]; | |
380 | Ok(len) | |
381 | } | |
382 | } | |
383 | ||
384 | #[test] | |
385 | fn test_read_to_end_capacity() -> io::Result<()> { | |
386 | let input = &b"foo"[..]; | |
387 | ||
c295e0f8 XL |
388 | // read_to_end() takes care not to over-allocate when a buffer is the |
389 | // exact size needed. | |
1b1a35ee XL |
390 | let mut vec1 = Vec::with_capacity(input.len()); |
391 | ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?; | |
392 | assert_eq!(vec1.len(), input.len()); | |
c295e0f8 | 393 | assert_eq!(vec1.capacity(), input.len(), "did not allocate more"); |
1b1a35ee XL |
394 | |
395 | Ok(()) | |
396 | } | |
397 | ||
398 | #[test] | |
136023e0 | 399 | fn io_slice_mut_advance_slices() { |
1b1a35ee XL |
400 | let mut buf1 = [1; 8]; |
401 | let mut buf2 = [2; 16]; | |
402 | let mut buf3 = [3; 8]; | |
403 | let mut bufs = &mut [ | |
404 | IoSliceMut::new(&mut buf1), | |
405 | IoSliceMut::new(&mut buf2), | |
406 | IoSliceMut::new(&mut buf3), | |
407 | ][..]; | |
408 | ||
409 | // Only in a single buffer.. | |
136023e0 | 410 | IoSliceMut::advance_slices(&mut bufs, 1); |
1b1a35ee XL |
411 | assert_eq!(bufs[0].deref(), [1; 7].as_ref()); |
412 | assert_eq!(bufs[1].deref(), [2; 16].as_ref()); | |
413 | assert_eq!(bufs[2].deref(), [3; 8].as_ref()); | |
414 | ||
415 | // Removing a buffer, leaving others as is. | |
136023e0 | 416 | IoSliceMut::advance_slices(&mut bufs, 7); |
1b1a35ee XL |
417 | assert_eq!(bufs[0].deref(), [2; 16].as_ref()); |
418 | assert_eq!(bufs[1].deref(), [3; 8].as_ref()); | |
419 | ||
420 | // Removing a buffer and removing from the next buffer. | |
136023e0 | 421 | IoSliceMut::advance_slices(&mut bufs, 18); |
1b1a35ee XL |
422 | assert_eq!(bufs[0].deref(), [3; 6].as_ref()); |
423 | } | |
424 | ||
425 | #[test] | |
923072b8 | 426 | #[should_panic] |
136023e0 XL |
427 | fn io_slice_mut_advance_slices_empty_slice() { |
428 | let mut empty_bufs = &mut [][..]; | |
136023e0 | 429 | IoSliceMut::advance_slices(&mut empty_bufs, 1); |
1b1a35ee XL |
430 | } |
431 | ||
432 | #[test] | |
923072b8 | 433 | #[should_panic] |
136023e0 | 434 | fn io_slice_mut_advance_slices_beyond_total_length() { |
1b1a35ee XL |
435 | let mut buf1 = [1; 8]; |
436 | let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; | |
437 | ||
136023e0 | 438 | IoSliceMut::advance_slices(&mut bufs, 9); |
1b1a35ee XL |
439 | assert!(bufs.is_empty()); |
440 | } | |
441 | ||
442 | #[test] | |
136023e0 | 443 | fn io_slice_advance_slices() { |
1b1a35ee XL |
444 | let buf1 = [1; 8]; |
445 | let buf2 = [2; 16]; | |
446 | let buf3 = [3; 8]; | |
447 | let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; | |
448 | ||
449 | // Only in a single buffer.. | |
136023e0 | 450 | IoSlice::advance_slices(&mut bufs, 1); |
1b1a35ee XL |
451 | assert_eq!(bufs[0].deref(), [1; 7].as_ref()); |
452 | assert_eq!(bufs[1].deref(), [2; 16].as_ref()); | |
453 | assert_eq!(bufs[2].deref(), [3; 8].as_ref()); | |
454 | ||
455 | // Removing a buffer, leaving others as is. | |
136023e0 | 456 | IoSlice::advance_slices(&mut bufs, 7); |
1b1a35ee XL |
457 | assert_eq!(bufs[0].deref(), [2; 16].as_ref()); |
458 | assert_eq!(bufs[1].deref(), [3; 8].as_ref()); | |
459 | ||
460 | // Removing a buffer and removing from the next buffer. | |
136023e0 | 461 | IoSlice::advance_slices(&mut bufs, 18); |
1b1a35ee XL |
462 | assert_eq!(bufs[0].deref(), [3; 6].as_ref()); |
463 | } | |
464 | ||
465 | #[test] | |
923072b8 | 466 | #[should_panic] |
136023e0 XL |
467 | fn io_slice_advance_slices_empty_slice() { |
468 | let mut empty_bufs = &mut [][..]; | |
136023e0 | 469 | IoSlice::advance_slices(&mut empty_bufs, 1); |
1b1a35ee XL |
470 | } |
471 | ||
472 | #[test] | |
923072b8 | 473 | #[should_panic] |
136023e0 | 474 | fn io_slice_advance_slices_beyond_total_length() { |
1b1a35ee XL |
475 | let buf1 = [1; 8]; |
476 | let mut bufs = &mut [IoSlice::new(&buf1)][..]; | |
477 | ||
136023e0 | 478 | IoSlice::advance_slices(&mut bufs, 9); |
1b1a35ee XL |
479 | assert!(bufs.is_empty()); |
480 | } | |
481 | ||
482 | /// Create a new writer that reads from at most `n_bufs` and reads | |
483 | /// `per_call` bytes (in total) per call to write. | |
484 | fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter { | |
485 | TestWriter { n_bufs, per_call, written: Vec::new() } | |
486 | } | |
487 | ||
488 | struct TestWriter { | |
489 | n_bufs: usize, | |
490 | per_call: usize, | |
491 | written: Vec<u8>, | |
492 | } | |
493 | ||
494 | impl Write for TestWriter { | |
495 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
496 | self.write_vectored(&[IoSlice::new(buf)]) | |
497 | } | |
498 | ||
499 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { | |
500 | let mut left = self.per_call; | |
501 | let mut written = 0; | |
502 | for buf in bufs.iter().take(self.n_bufs) { | |
503 | let n = min(left, buf.len()); | |
504 | self.written.extend_from_slice(&buf[0..n]); | |
505 | left -= n; | |
506 | written += n; | |
507 | } | |
508 | Ok(written) | |
509 | } | |
510 | ||
511 | fn flush(&mut self) -> io::Result<()> { | |
512 | Ok(()) | |
513 | } | |
514 | } | |
515 | ||
516 | #[test] | |
517 | fn test_writer_read_from_one_buf() { | |
518 | let mut writer = test_writer(1, 2); | |
519 | ||
520 | assert_eq!(writer.write(&[]).unwrap(), 0); | |
521 | assert_eq!(writer.write_vectored(&[]).unwrap(), 0); | |
522 | ||
523 | // Read at most 2 bytes. | |
524 | assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2); | |
525 | let bufs = &[IoSlice::new(&[2, 2, 2])]; | |
526 | assert_eq!(writer.write_vectored(bufs).unwrap(), 2); | |
527 | ||
528 | // Only read from first buf. | |
529 | let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])]; | |
530 | assert_eq!(writer.write_vectored(bufs).unwrap(), 1); | |
531 | ||
532 | assert_eq!(writer.written, &[1, 1, 2, 2, 3]); | |
533 | } | |
534 | ||
535 | #[test] | |
536 | fn test_writer_read_from_multiple_bufs() { | |
537 | let mut writer = test_writer(3, 3); | |
538 | ||
539 | // Read at most 3 bytes from two buffers. | |
540 | let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; | |
541 | assert_eq!(writer.write_vectored(bufs).unwrap(), 3); | |
542 | ||
543 | // Read at most 3 bytes from three buffers. | |
544 | let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; | |
545 | assert_eq!(writer.write_vectored(bufs).unwrap(), 3); | |
546 | ||
547 | assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]); | |
548 | } | |
549 | ||
550 | #[test] | |
551 | fn test_write_all_vectored() { | |
552 | #[rustfmt::skip] // Becomes unreadable otherwise. | |
553 | let tests: Vec<(_, &'static [u8])> = vec![ | |
554 | (vec![], &[]), | |
555 | (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), | |
556 | (vec![IoSlice::new(&[1])], &[1]), | |
557 | (vec![IoSlice::new(&[1, 2])], &[1, 2]), | |
558 | (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), | |
559 | (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), | |
560 | (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), | |
561 | (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), | |
562 | (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]), | |
563 | (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), | |
564 | (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), | |
565 | (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), | |
566 | (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), | |
567 | (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]), | |
568 | (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), | |
569 | (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), | |
570 | (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), | |
571 | (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]), | |
572 | (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), | |
573 | ]; | |
574 | ||
575 | let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]; | |
576 | ||
577 | for (n_bufs, per_call) in writer_configs.iter().copied() { | |
578 | for (mut input, wanted) in tests.clone().into_iter() { | |
579 | let mut writer = test_writer(n_bufs, per_call); | |
580 | assert!(writer.write_all_vectored(&mut *input).is_ok()); | |
581 | assert_eq!(&*writer.written, &*wanted); | |
582 | } | |
583 | } | |
584 | } | |
a2a8927a XL |
585 | |
586 | #[bench] | |
587 | fn bench_take_read(b: &mut test::Bencher) { | |
588 | b.iter(|| { | |
589 | let mut buf = [0; 64]; | |
590 | ||
591 | [255; 128].take(64).read(&mut buf).unwrap(); | |
592 | }); | |
593 | } | |
594 | ||
595 | #[bench] | |
596 | fn bench_take_read_buf(b: &mut test::Bencher) { | |
597 | b.iter(|| { | |
598 | let mut buf = [MaybeUninit::uninit(); 64]; | |
599 | ||
600 | let mut rbuf = ReadBuf::uninit(&mut buf); | |
601 | ||
602 | [255; 128].take(64).read_buf(&mut rbuf).unwrap(); | |
603 | }); | |
604 | } |