Allow capacity and length to be different for user buffers
authorAbhijeet Joglekar <abhijeet@fb.com>
Wed, 1 Aug 2012 17:36:14 +0000 (10:36 -0700)
committerJordan DeLong <jdelong@fb.com>
Thu, 2 Aug 2012 08:55:51 +0000 (01:55 -0700)
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
folly/experimental/io/IOBuf.h
folly/experimental/io/test/IOBufTest.cpp

index 838d7069d2ffbdff52eb40d12e3fe01c88fa49a1..42abf330b9fdfdd7441dc10aedb6855dede6e08a 100644 (file)
@@ -117,6 +117,7 @@ unique_ptr<IOBuf> IOBuf::create(uint32_t capacity) {
 }
 
 unique_ptr<IOBuf> IOBuf::takeOwnership(void* buf, uint32_t capacity,
+                                       uint32_t length,
                                        FreeFunction freeFn,
                                        void* userData,
                                        bool freeOnError) {
@@ -127,7 +128,7 @@ unique_ptr<IOBuf> IOBuf::takeOwnership(void* buf, uint32_t capacity,
     uint8_t* bufPtr = static_cast<uint8_t*>(buf);
     return unique_ptr<IOBuf>(new IOBuf(kExtUserSupplied, kFlagFreeSharedInfo,
                                        bufPtr, capacity,
-                                       bufPtr, capacity,
+                                       bufPtr, length,
                                        sharedInfo));
   } catch (...) {
     delete sharedInfo;
index a06f7a44f215c521d50168224df323534295b191..a9c5fcf30eb30e588c69727ce8c973e9f6272137 100644 (file)
@@ -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<IOBuf> 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<IOBuf> takeOwnership(void* buf, uint32_t capacity,
+                                              uint32_t length,
                                               FreeFunction freeFn = NULL,
                                               void* userData = NULL,
                                               bool freeOnError = true);
index 46dfdcb51e8284f44141551a6ae11ebcb6d82bae..2e12329711a9a7980bf62f4085fb1cc3a4811049 100644 (file)
@@ -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<IOBuf> 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) {