Commit c09d7af4 authored by Seth Hinze's avatar Seth Hinze Committed by Facebook GitHub Bot

Add ability to specify an offset to IOBuf::takeOwnership

Summary: Allow callers to `IOBuf::takeOwnership()` to specify valid data in the middle of the underlying buffer.

Reviewed By: yfeldblum

Differential Revision: D27583632

fbshipit-source-id: 4651dec5e53c5eea341b2b4ad3782adfbe7ff779
parent 67c99b13
......@@ -360,13 +360,14 @@ IOBuf::IOBuf(
TakeOwnershipOp,
void* buf,
std::size_t capacity,
std::size_t offset,
std::size_t length,
FreeFunction freeFn,
void* userData,
bool freeOnError)
: next_(this),
prev_(this),
data_(static_cast<uint8_t*>(buf)),
data_(static_cast<uint8_t*>(buf) + offset),
buf_(static_cast<uint8_t*>(buf)),
length_(length),
capacity_(capacity),
......@@ -386,6 +387,7 @@ IOBuf::IOBuf(
unique_ptr<IOBuf> IOBuf::takeOwnership(
void* buf,
std::size_t capacity,
std::size_t offset,
std::size_t length,
FreeFunction freeFn,
void* userData,
......@@ -416,7 +418,7 @@ unique_ptr<IOBuf> IOBuf::takeOwnership(
packFlagsAndSharedInfo(0, &storage->shared),
static_cast<uint8_t*>(buf),
capacity,
static_cast<uint8_t*>(buf),
static_cast<uint8_t*>(buf) + offset,
length));
rollback.dismiss();
......
......@@ -314,6 +314,9 @@ class IOBuf {
* In the second version, the user specifies the valid length of data
* in the buffer
*
* In the third version, the user specifies the offset to the valid data
* and the length of valid data in the buffer.
*
* On error, std::bad_alloc will be thrown. If freeOnError is true (the
* default) the buffer will be freed before throwing the error.
*/
......@@ -324,7 +327,7 @@ class IOBuf {
void* userData = nullptr,
bool freeOnError = true) {
return takeOwnership(
buf, capacity, capacity, freeFn, userData, freeOnError);
buf, capacity, 0, capacity, freeFn, userData, freeOnError);
}
IOBuf(
TakeOwnershipOp op,
......@@ -333,11 +336,32 @@ class IOBuf {
FreeFunction freeFn = nullptr,
void* userData = nullptr,
bool freeOnError = true)
: IOBuf(op, buf, capacity, capacity, freeFn, userData, freeOnError) {}
: IOBuf(op, buf, capacity, 0, capacity, freeFn, userData, freeOnError) {}
static std::unique_ptr<IOBuf> takeOwnership(
void* buf,
std::size_t capacity,
std::size_t length,
FreeFunction freeFn = nullptr,
void* userData = nullptr,
bool freeOnError = true) {
return takeOwnership(
buf, capacity, 0, length, freeFn, userData, freeOnError);
}
IOBuf(
TakeOwnershipOp op,
void* buf,
std::size_t capacity,
std::size_t length,
FreeFunction freeFn = nullptr,
void* userData = nullptr,
bool freeOnError = true)
: IOBuf(op, buf, capacity, 0, length, freeFn, userData, freeOnError) {}
static std::unique_ptr<IOBuf> takeOwnership(
void* buf,
std::size_t capacity,
std::size_t offset,
std::size_t length,
FreeFunction freeFn = nullptr,
void* userData = nullptr,
......@@ -346,6 +370,7 @@ class IOBuf {
TakeOwnershipOp,
void* buf,
std::size_t capacity,
std::size_t offset,
std::size_t length,
FreeFunction freeFn = nullptr,
void* userData = nullptr,
......
......@@ -167,6 +167,21 @@ TEST(IOBuf, TakeOwnership) {
fbstring str = iobuf->moveToFbString();
EXPECT_EQ(str, "A");
}
deleteCount = 0;
uint32_t size6 = 100;
uint8_t* buf6 = new uint8_t[size6];
uint32_t offset6 = 48;
uint32_t length6 = 48;
unique_ptr<IOBuf> iobuf6(IOBuf::takeOwnership(
buf6, size6, offset6, length6, deleteArrayBuffer, &deleteCount));
EXPECT_EQ(buf6 + offset6, iobuf6->data());
EXPECT_EQ(length6, iobuf6->length());
EXPECT_EQ(buf6, iobuf6->buffer());
EXPECT_EQ(size6, iobuf6->capacity());
EXPECT_EQ(0, deleteCount);
iobuf6.reset();
EXPECT_EQ(1, deleteCount);
}
TEST(IOBuf, GetUserData) {
......
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