| 91 | namespace internal { |
| 92 | |
| 93 | Future<Nothing> splice( |
| 94 | int_fd from, |
| 95 | int_fd to, |
| 96 | size_t chunk, |
| 97 | const vector<lambda::function<void(const string&)>>& hooks) |
| 98 | { |
| 99 | boost::shared_array<char> data(new char[chunk]); |
| 100 | return loop( |
| 101 | None(), |
| 102 | [=]() { |
| 103 | return io::read(from, data.get(), chunk); |
| 104 | }, |
| 105 | [=](size_t length) -> Future<ControlFlow<Nothing>> { |
| 106 | if (length == 0) { // EOF. |
| 107 | return Break(); |
| 108 | } |
| 109 | |
| 110 | // Send the data to the redirect hooks. |
| 111 | const string s = string(data.get(), length); |
| 112 | foreach (const lambda::function<void(const string&)>& hook, hooks) { |
| 113 | hook(s); |
| 114 | } |
| 115 | |
| 116 | return io::write(to, s) |
| 117 | .then([]() -> Future<ControlFlow<Nothing>> { |
| 118 | return Continue(); |
| 119 | }); |
| 120 | }); |
| 121 | } |
| 122 | |
| 123 | |
| 124 | } // namespace internal { |