+// Return a new set of iovecs that contains only the first <bytes_wanted> bytes of <data>.
+vector<iovec> collect_iovecs(const vector<iovec> &data, size_t bytes_wanted)
+{
+ vector<iovec> ret;
+ size_t max_iovecs = std::min<size_t>(data.size(), IOV_MAX);
+ for (size_t i = 0; i < max_iovecs && bytes_wanted > 0; ++i) {
+ if (data[i].iov_len <= bytes_wanted) {
+ // Consume the entire iovec.
+ ret.push_back(data[i]);
+ bytes_wanted -= data[i].iov_len;
+ } else {
+ // Take only parts of this iovec.
+ iovec iov;
+ iov.iov_base = data[i].iov_base;
+ iov.iov_len = bytes_wanted;
+ ret.push_back(iov);
+ bytes_wanted = 0;
+ }
+ }
+ return ret;
+}
+
+// Return a new set of iovecs that contains all of <data> except the first <bytes_wanted> bytes.
+vector<iovec> remove_iovecs(const vector<iovec> &data, size_t bytes_wanted)
+{
+ vector<iovec> ret;
+ size_t i;
+ for (i = 0; i < data.size() && bytes_wanted > 0; ++i) {
+ if (data[i].iov_len <= bytes_wanted) {
+ // Consume the entire iovec.
+ bytes_wanted -= data[i].iov_len;
+ } else {
+ // Take only parts of this iovec.
+ iovec iov;
+ iov.iov_base = reinterpret_cast<char *>(data[i].iov_base) + bytes_wanted;
+ iov.iov_len = data[i].iov_len - bytes_wanted;
+ ret.push_back(iov);
+ bytes_wanted = 0;
+ }
+ }
+
+ // Add the rest of the iovecs unchanged.
+ ret.insert(ret.end(), data.begin() + i, data.end());
+ return ret;
+}
+
+void Stream::add_data_raw(const vector<iovec> &orig_data)