send_signal(signal: libc::c_int)1 use std::io::{self, Read, Write};
2
3 use futures::{Future, Poll};
4
5 /// A future which will copy all data from a reader into a writer.
6 ///
7 /// Created by the [`copy`] function, this future will resolve to the number of
8 /// bytes copied or an error if one happens.
9 ///
10 /// [`copy`]: fn.copy.html
11 #[must_use = "futures do nothing unless polled"]
12 pub struct Copy<R, W> {
13 reader: R,
14 read_done: bool,
15 writer: W,
16 pos: usize,
17 cap: usize,
18 amt: u64,
19 buf: Box<[u8]>,
20 }
21
22 /// Creates a future which represents copying all the bytes from one object to
23 /// another.
24 ///
25 /// The returned future will copy all the bytes read from `reader` into the
26 /// `writer` specified. This future will only complete once the `reader` has hit
27 /// EOF and all bytes have been written to and flushed from the `writer`
28 /// provided.
29 ///
30 /// On success the number of bytes is returned and the `reader` and `writer` are
31 /// consumed. On error the error is returned and the I/O objects are consumed as
32 /// well.
33 pub fn copy<R, W>(reader: R, writer: W) -> Copy<R, W>
34 where R: Read,
35 W: Write,
36 {
37 Copy {
38 reader: reader,
39 read_done: false,
40 writer: writer,
41 amt: 0,
42 pos: 0,
43 cap: 0,
44 buf: Box::new([0; 2048]),
45 }
46 }
47
48 impl<R, W> Future for Copy<R, W>
49 where R: Read,
50 W: Write,
51 {
52 type Item = u64;
53 type Error = io::Error;
54
55 fn poll(&mut self) -> Poll<u64, io::Error> {
56 loop {
57 // If our buffer is empty, then we need to read some data to
58 // continue.
59 if self.pos == self.cap && !self.read_done {
60 let n = try_nb!(self.reader.read(&mut self.buf));
61 if n == 0 {
62 self.read_done = true;
63 } else {
64 self.pos = 0;
65 self.cap = n;
66 }
67 }
68
69 // If our buffer has some data, let's write it out!
70 while self.pos < self.cap {
71 let i = try_nb!(self.writer.write(&self.buf[self.pos..self.cap]));
72 self.pos += i;
73 self.amt += i as u64;
74 }
75
76 // If we've written all the data and we've seen EOF, flush out the
77 // data and finish the transfer.
78 // done with the entire transfer.
79 if self.pos == self.cap && self.read_done {
80 try_nb!(self.writer.flush());
81 return Ok(self.amt.into())
82 }
83 }
84 }
85 }
86