| 58 | } |
| 59 | |
| 60 | [[nodiscard]] size_t data_pipe::fetch_data(boost::asio::mutable_buffer _out) { |
| 61 | std::scoped_lock lock{mtx_}; |
| 62 | if (data_to_forward_.size() == 0) { |
| 63 | return 0; |
| 64 | } |
| 65 | |
| 66 | size_t len{0}; |
| 67 | auto data_it = data_to_forward_.begin(); |
| 68 | while (data_it != data_to_forward_.end()) { |
| 69 | // Number of bytes we can write from the current segment without exceeding the output buffer size. |
| 70 | auto const segment_writable = std::min(_out.size() - len, data_it->buffer_.size()); |
| 71 | std::copy(data_it->buffer_.begin(), data_it->buffer_.begin() + static_cast<std::ptrdiff_t>(segment_writable), |
| 72 | static_cast<unsigned char*>(_out.data()) + len); |
| 73 | len += segment_writable; |
| 74 | if (segment_writable == data_it->buffer_.size()) { |
| 75 | // Fully consumed the current segment, move to the next one. |
| 76 | ++data_it; |
| 77 | } else { |
| 78 | // Partially consumed the current segment, erase the consumed part and stop. |
| 79 | data_it->buffer_.erase(data_it->buffer_.begin(), data_it->buffer_.begin() + static_cast<std::ptrdiff_t>(segment_writable)); |
| 80 | break; |
| 81 | } |
| 82 | } |
| 83 | // Remove all fully consumed segments from the forward queue. |
| 84 | data_to_forward_.erase(data_to_forward_.begin(), data_it); |
| 85 | |
| 86 | return len; |
| 87 | } |
| 88 | |
| 89 | [[nodiscard]] bool data_pipe::fetch_data(control_data_t& _out) { |
| 90 | std::scoped_lock lock{mtx_}; |
no test coverage detected