IOBuf::IOBuf(
    TakeOwnershipOp,
    SizedFree,
    void* buf,
    std::size_t capacity,
    std::size_t offset,
    std::size_t length,
    bool freeOnError)
    : next_(this),
      prev_(this),
      data_(static_cast<uint8_t*>(buf) + offset),
      buf_(static_cast<uint8_t*>(buf)),
      length_(length),
      capacity_(capacity),
      flagsAndSharedInfo_(
          packFlagsAndSharedInfo(kFlagFreeSharedInfo, nullptr)) {
  auto rollback = makeGuard([&] { //
    takeOwnershipError(freeOnError, buf, nullptr, nullptr);
  });
  setSharedInfo(new SharedInfo(nullptr, reinterpret_cast<void*>(capacity)));
  rollback.dismiss();

  if (io_buf_alloc_cb && capacity) {
    io_buf_alloc_cb(buf, capacity);
  }
}
IOBuf::IOBuf(
    TakeOwnershipOp,
    SizedFree,
    void* buf,
    std::size_t capacity,
    std::size_t offset,
    std::size_t length,
    bool freeOnError)
    : next_(this),
      prev_(this),
      data_(static_cast<uint8_t*>(buf) + offset),
      buf_(static_cast<uint8_t*>(buf)),
      length_(length),
      capacity_(capacity),
      flagsAndSharedInfo_(
          packFlagsAndSharedInfo(kFlagFreeSharedInfo, nullptr)) {
  auto rollback = makeGuard([&] {  
    takeOwnershipError(freeOnError, buf, nullptr, nullptr);
  });
  setSharedInfo(new SharedInfo(nullptr, reinterpret_cast<void*>(capacity)));
  rollback.dismiss();

  if (io_buf_alloc_cb && capacity) {
    io_buf_alloc_cb(buf, capacity);
  }
}