Commit b7e06ff9 authored by Dan Melnic's avatar Dan Melnic Committed by Facebook Github Bot

Add IOBuf::takeOwnershipIov method

Summary: Add IOBuf::takeOwnershipIov method

Reviewed By: yfeldblum, djwatson

Differential Revision: D10135962

fbshipit-source-id: 86a22d73aa1b72645640cf026d2dc2f38b02989c
parent 1efbcb1b
...@@ -1031,6 +1031,31 @@ unique_ptr<IOBuf> IOBuf::wrapIov(const iovec* vec, size_t count) { ...@@ -1031,6 +1031,31 @@ unique_ptr<IOBuf> IOBuf::wrapIov(const iovec* vec, size_t count) {
return result; return result;
} }
std::unique_ptr<IOBuf> IOBuf::takeOwnershipIov(
const iovec* vec,
size_t count,
FreeFunction freeFn,
void* userData,
bool freeOnError) {
unique_ptr<IOBuf> result = nullptr;
for (size_t i = 0; i < count; ++i) {
size_t len = vec[i].iov_len;
void* data = vec[i].iov_base;
if (len > 0) {
auto buf = takeOwnership(data, len, freeFn, userData, freeOnError);
if (!result) {
result = std::move(buf);
} else {
result->prependChain(std::move(buf));
}
}
}
if (UNLIKELY(result == nullptr)) {
return create(0);
}
return result;
}
size_t IOBuf::fillIov(struct iovec* iov, size_t len) const { size_t IOBuf::fillIov(struct iovec* iov, size_t len) const {
IOBuf const* p = this; IOBuf const* p = this;
size_t i = 0; size_t i = 0;
......
...@@ -1231,6 +1231,18 @@ class IOBuf { ...@@ -1231,6 +1231,18 @@ class IOBuf {
*/ */
static std::unique_ptr<IOBuf> wrapIov(const iovec* vec, size_t count); static std::unique_ptr<IOBuf> wrapIov(const iovec* vec, size_t count);
/**
* A helper that takes ownerships a number of iovecs into an IOBuf chain. If
* count == 0, then a zero length buf is returned. This function never
* returns nullptr.
*/
static std::unique_ptr<IOBuf> takeOwnershipIov(
const iovec* vec,
size_t count,
FreeFunction freeFn = nullptr,
void* userData = nullptr,
bool freeOnError = true);
/* /*
* Overridden operator new and delete. * Overridden operator new and delete.
* These perform specialized memory management to help support * These perform specialized memory management to help support
......
...@@ -1020,6 +1020,25 @@ TEST(IOBuf, wrapIov) { ...@@ -1020,6 +1020,25 @@ TEST(IOBuf, wrapIov) {
} }
} }
TEST(IOBuf, takeOwnershipIov) {
// Test taking IOVs ownership
folly::fbvector<folly::StringPiece> words{"hello", "world!"};
folly::fbvector<struct iovec> iov;
iov.push_back({nullptr, 0});
for (size_t i = 0; i < words.size(); i++) {
iov.push_back({(void*)strdup(words[i].data()), words[i].size() + 1});
}
auto buf = IOBuf::takeOwnershipIov(iov.data(), iov.size());
EXPECT_EQ(iov.size() - 1, buf->countChainElements());
IOBuf const* b = buf.get();
// skip the first iovec, which is empty/null, as it is ignored by
// IOBuf::takeIovOwnership
for (size_t i = 0; i < buf->countChainElements(); ++i, b = b->next()) {
EXPECT_EQ(words[i], static_cast<const char*>(iov[i + 1].iov_base));
}
}
TEST(IOBuf, wrapZeroLenIov) { TEST(IOBuf, wrapZeroLenIov) {
folly::fbvector<struct iovec> iov; folly::fbvector<struct iovec> iov;
iov.push_back({nullptr, 0}); iov.push_back({nullptr, 0});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment