Commit cb771e84 authored by Adam Simpkins's avatar Adam Simpkins Committed by Jordan DeLong

add IOBuf::maybeCopyBuffer()

Summary:
Add a version of IOBuf::copyBuffer() which accepts a std::string, as
well as a maybeCopyBuffer() function which returns a null pointer if the
input string is empty.

In proxygen we have a few places where we construct an IOBuf from a
string configuration parameter, and we almost always want a null pointer
rather than an empty IOBuf chain if the string is empty.

Test Plan: Included unit tests for these new functions.

Reviewed By: tudorb@fb.com

FB internal diff: D630547
parent 389fb8a5
......@@ -299,6 +299,29 @@ class IOBuf {
uint32_t headroom=0,
uint32_t minTailroom=0);
/**
* Convenience function to create a new IOBuf object that copies data from a
* user-supplied string, optionally allocating a given amount of
* headroom and tailroom.
*
* Beware when attempting to invoke this function with a constant string
* literal and a headroom argument: you will likely end up invoking the
* version of copyBuffer() above. IOBuf::copyBuffer("hello", 3) will treat
* the first argument as a const void*, and will invoke the version of
* copyBuffer() above, with the size argument of 3.
*/
static std::unique_ptr<IOBuf> copyBuffer(const std::string& buf,
uint32_t headroom=0,
uint32_t minTailroom=0);
/**
* A version of copyBuffer() that returns a null pointer if the input string
* is empty.
*/
static std::unique_ptr<IOBuf> maybeCopyBuffer(const std::string& buf,
uint32_t headroom=0,
uint32_t minTailroom=0);
/**
* Convenience function to free a chain of IOBufs held by a unique_ptr.
*/
......@@ -1076,6 +1099,21 @@ inline std::unique_ptr<IOBuf> IOBuf::copyBuffer(
return buf;
}
inline std::unique_ptr<IOBuf> IOBuf::copyBuffer(const std::string& buf,
uint32_t headroom,
uint32_t minTailroom) {
return copyBuffer(buf.data(), buf.size(), headroom, minTailroom);
}
inline std::unique_ptr<IOBuf> IOBuf::maybeCopyBuffer(const std::string& buf,
uint32_t headroom,
uint32_t minTailroom) {
if (buf.empty()) {
return nullptr;
}
return copyBuffer(buf.data(), buf.size(), headroom, minTailroom);
}
} // folly
#endif // FOLLY_IO_IOBUF_H_
......@@ -550,6 +550,34 @@ TEST(IOBuf, copyBuffer) {
EXPECT_EQ(s, std::string(reinterpret_cast<const char*>(buf->data()),
buf->length()));
EXPECT_LE(2, buf->tailroom());
buf = IOBuf::copyBuffer(s, 5, 7);
EXPECT_EQ(5, buf->headroom());
EXPECT_EQ(s, std::string(reinterpret_cast<const char*>(buf->data()),
buf->length()));
EXPECT_LE(7, buf->tailroom());
std::string empty;
buf = IOBuf::copyBuffer(empty, 3, 6);
EXPECT_EQ(3, buf->headroom());
EXPECT_EQ(0, buf->length());
EXPECT_LE(6, buf->tailroom());
}
TEST(IOBuf, maybeCopyBuffer) {
std::string s("this is a test");
auto buf = IOBuf::maybeCopyBuffer(s, 1, 2);
EXPECT_EQ(1, buf->headroom());
EXPECT_EQ(s, std::string(reinterpret_cast<const char*>(buf->data()),
buf->length()));
EXPECT_LE(2, buf->tailroom());
std::string empty;
buf = IOBuf::maybeCopyBuffer("", 5, 7);
EXPECT_EQ(nullptr, buf.get());
buf = IOBuf::maybeCopyBuffer("");
EXPECT_EQ(nullptr, buf.get());
}
namespace {
......
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