From 00616345649f48bcd2739af8aaa8d18cf174d20b Mon Sep 17 00:00:00 2001 From: Abhijeet Joglekar Date: Wed, 1 Aug 2012 10:36:14 -0700 Subject: [PATCH] Allow capacity and length to be different for user buffers Summary: Currently, takeOwnership lets a user pass in a data buffer and wraps it in an IOBuffer. However, the capacity and length of the user buffer are required to be same. Added a new API to allow buffers where the capacity and length can be different. Users of existing API should not be affected. Test Plan: 1) Added new test case to IOBufTest that checks buffers with length different from capacity 2) Run existing IOBuf test cases to verify no regressions Reviewed By: brianp@fb.com FB internal diff: D536575 --- folly/experimental/io/IOBuf.cpp | 3 ++- folly/experimental/io/IOBuf.h | 16 +++++++++++++++- folly/experimental/io/test/IOBufTest.cpp | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/folly/experimental/io/IOBuf.cpp b/folly/experimental/io/IOBuf.cpp index 838d7069..42abf330 100644 --- a/folly/experimental/io/IOBuf.cpp +++ b/folly/experimental/io/IOBuf.cpp @@ -117,6 +117,7 @@ unique_ptr IOBuf::create(uint32_t capacity) { } unique_ptr IOBuf::takeOwnership(void* buf, uint32_t capacity, + uint32_t length, FreeFunction freeFn, void* userData, bool freeOnError) { @@ -127,7 +128,7 @@ unique_ptr IOBuf::takeOwnership(void* buf, uint32_t capacity, uint8_t* bufPtr = static_cast(buf); return unique_ptr(new IOBuf(kExtUserSupplied, kFlagFreeSharedInfo, bufPtr, capacity, - bufPtr, capacity, + bufPtr, length, sharedInfo)); } catch (...) { delete sharedInfo; diff --git a/folly/experimental/io/IOBuf.h b/folly/experimental/io/IOBuf.h index a06f7a44..a9c5fcf3 100644 --- a/folly/experimental/io/IOBuf.h +++ b/folly/experimental/io/IOBuf.h @@ -217,12 +217,26 @@ class IOBuf { * If no FreeFunction is specified, the buffer will be freed using free(). * * The IOBuf data pointer will initially point to the start of the buffer, - * and the length will be the full capacity of the buffer. + * + * In the first version of this function, the length of data is unspecified + * and is initialized to the capacity of the buffer + * + * In the second version, the user specifies the valid length of 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. */ static std::unique_ptr takeOwnership(void* buf, uint32_t capacity, + FreeFunction freeFn = NULL, + void* userData = NULL, + bool freeOnError = true) { + return takeOwnership(buf, capacity, capacity, freeFn, + userData, freeOnError); + } + + static std::unique_ptr takeOwnership(void* buf, uint32_t capacity, + uint32_t length, FreeFunction freeFn = NULL, void* userData = NULL, bool freeOnError = true); diff --git a/folly/experimental/io/test/IOBufTest.cpp b/folly/experimental/io/test/IOBufTest.cpp index 46dfdcb5..2e123297 100644 --- a/folly/experimental/io/test/IOBufTest.cpp +++ b/folly/experimental/io/test/IOBufTest.cpp @@ -120,6 +120,23 @@ TEST(IOBuf, TakeOwnership) { EXPECT_EQ(0, deleteCount); iobuf2.reset(); EXPECT_EQ(1, deleteCount); + + deleteCount = 0; + uint32_t size3 = 3456; + uint8_t *buf3 = new uint8_t[size3]; + uint32_t length3 = 48; + unique_ptr iobuf3(IOBuf::takeOwnership(buf3, size3, length3, + deleteArrayBuffer, + &deleteCount)); + EXPECT_EQ(buf3, iobuf3->data()); + EXPECT_EQ(length3, iobuf3->length()); + EXPECT_EQ(buf3, iobuf3->buffer()); + EXPECT_EQ(size3, iobuf3->capacity()); + EXPECT_EQ(0, deleteCount); + iobuf3.reset(); + EXPECT_EQ(1, deleteCount); + + } TEST(IOBuf, WrapBuffer) { -- 2.34.1