proxygen
folly::IOBuf Class Reference

#include <IOBuf.h>

Classes

struct  DeleterBase
 
struct  HeapFullStorage
 
struct  HeapPrefix
 
struct  HeapStorage
 
struct  InternalConstructor
 
class  Iterator
 
struct  SharedInfo
 
struct  UniquePtrDeleter
 

Public Types

enum  CreateOp { CREATE }
 
enum  WrapBufferOp { WRAP_BUFFER }
 
enum  TakeOwnershipOp { TAKE_OWNERSHIP }
 
enum  CopyBufferOp { COPY_BUFFER }
 
typedef ByteRange value_type
 
typedef Iterator iterator
 
typedef Iterator const_iterator
 
typedef void(* FreeFunction) (void *buf, void *userData)
 

Public Member Functions

 IOBuf (CreateOp, std::size_t capacity)
 
 IOBuf (TakeOwnershipOp op, void *buf, std::size_t capacity, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
 
 IOBuf (TakeOwnershipOp, void *buf, std::size_t capacity, std::size_t length, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
 
 IOBuf (WrapBufferOp op, const void *buf, std::size_t capacity) noexcept
 
 IOBuf (WrapBufferOp op, ByteRange br) noexcept
 
 IOBuf (CopyBufferOp op, const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
 
 IOBuf (CopyBufferOp op, ByteRange br, std::size_t headroom=0, std::size_t minTailroom=0)
 
 IOBuf (CopyBufferOp op, const std::string &buf, std::size_t headroom=0, std::size_t minTailroom=0)
 
 ~IOBuf ()
 
bool empty () const
 
const uint8_tdata () const
 
uint8_twritableData ()
 
const uint8_ttail () const
 
uint8_twritableTail ()
 
std::size_t length () const
 
std::size_t headroom () const
 
std::size_t tailroom () const
 
const uint8_tbuffer () const
 
uint8_twritableBuffer ()
 
const uint8_tbufferEnd () const
 
std::size_t capacity () const
 
IOBufnext ()
 
const IOBufnext () const
 
IOBufprev ()
 
const IOBufprev () const
 
void advance (std::size_t amount)
 
void retreat (std::size_t amount)
 
void prepend (std::size_t amount)
 
void append (std::size_t amount)
 
void trimStart (std::size_t amount)
 
void trimEnd (std::size_t amount)
 
void clear ()
 
void reserve (std::size_t minHeadroom, std::size_t minTailroom)
 
bool isChained () const
 
size_t countChainElements () const
 
std::size_t computeChainDataLength () const
 
void prependChain (std::unique_ptr< IOBuf > &&iobuf)
 
void appendChain (std::unique_ptr< IOBuf > &&iobuf)
 
std::unique_ptr< IOBufunlink ()
 
std::unique_ptr< IOBufpop ()
 
std::unique_ptr< IOBufseparateChain (IOBuf *head, IOBuf *tail)
 
bool isShared () const
 
bool isManaged () const
 
bool isManagedOne () const
 
bool isSharedOne () const
 
void unshare ()
 
void unshareOne ()
 
void markExternallyShared ()
 
void markExternallySharedOne ()
 
void makeManaged ()
 
void makeManagedOne ()
 
ByteRange coalesce ()
 
ByteRange coalesceWithHeadroomTailroom (std::size_t newHeadroom, std::size_t newTailroom)
 
void gather (std::size_t maxLength)
 
std::unique_ptr< IOBufclone () const
 
IOBuf cloneAsValue () const
 
std::unique_ptr< IOBufcloneOne () const
 
IOBuf cloneOneAsValue () const
 
std::unique_ptr< IOBufcloneCoalesced () const
 
std::unique_ptr< IOBufcloneCoalescedWithHeadroomTailroom (std::size_t newHeadroom, std::size_t newTailroom) const
 
IOBuf cloneCoalescedAsValue () const
 
IOBuf cloneCoalescedAsValueWithHeadroomTailroom (std::size_t newHeadroom, std::size_t newTailroom) const
 
void cloneInto (IOBuf &other) const
 
void cloneOneInto (IOBuf &other) const
 
folly::fbvector< struct iovec > getIov () const
 
void appendToIov (folly::fbvector< struct iovec > *iov) const
 
size_t fillIov (struct iovec *iov, size_t len) const
 
void * operator new (size_t size)
 
void * operator new (size_t size, void *ptr)
 
void operator delete (void *ptr)
 
void operator delete (void *ptr, void *placement)
 
fbstring moveToFbString ()
 
Iterator cbegin () const
 
Iterator cend () const
 
Iterator begin () const
 
Iterator end () const
 
 IOBuf () noexcept
 
 IOBuf (IOBuf &&other) noexcept
 
IOBufoperator= (IOBuf &&other) noexcept
 
 IOBuf (const IOBuf &other)
 
IOBufoperator= (const IOBuf &other)
 

Static Public Member Functions

static std::unique_ptr< IOBufcreate (std::size_t capacity)
 
static std::unique_ptr< IOBufcreateCombined (std::size_t capacity)
 
static std::unique_ptr< IOBufcreateSeparate (std::size_t capacity)
 
static std::unique_ptr< IOBufcreateChain (size_t totalCapacity, std::size_t maxBufCapacity)
 
static std::unique_ptr< IOBuftakeOwnership (void *buf, std::size_t capacity, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
 
static std::unique_ptr< IOBuftakeOwnership (void *buf, std::size_t capacity, std::size_t length, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
 
template<class UniquePtr >
static std::enable_if< detail::IsUniquePtrToSL< UniquePtr >::value, std::unique_ptr< IOBuf > >::type takeOwnership (UniquePtr &&buf, size_t count=1)
 
static std::unique_ptr< IOBufwrapBuffer (const void *buf, std::size_t capacity)
 
static std::unique_ptr< IOBufwrapBuffer (ByteRange br)
 
static IOBuf wrapBufferAsValue (const void *buf, std::size_t capacity) noexcept
 
static IOBuf wrapBufferAsValue (ByteRange br) noexcept
 
static std::unique_ptr< IOBufcopyBuffer (const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
 
static std::unique_ptr< IOBufcopyBuffer (ByteRange br, std::size_t headroom=0, std::size_t minTailroom=0)
 
static std::unique_ptr< IOBufcopyBuffer (const std::string &buf, std::size_t headroom=0, std::size_t minTailroom=0)
 
static std::unique_ptr< IOBufmaybeCopyBuffer (const std::string &buf, std::size_t headroom=0, std::size_t minTailroom=0)
 
static void destroy (std::unique_ptr< IOBuf > &&data)
 
static std::unique_ptr< IOBufwrapIov (const iovec *vec, size_t count)
 
static std::unique_ptr< IOBuftakeOwnershipIov (const iovec *vec, size_t count, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
 

Private Types

enum  FlagsEnum : uintptr_t { kFlagFreeSharedInfo = 0x1, kFlagMaybeShared = 0x2, kFlagMask = kFlagFreeSharedInfo | kFlagMaybeShared }
 

Private Member Functions

 IOBuf (InternalConstructor, uintptr_t flagsAndSharedInfo, uint8_t *buf, std::size_t capacity, uint8_t *data, std::size_t length) noexcept
 
void unshareOneSlow ()
 
void unshareChained ()
 
void makeManagedChained ()
 
void coalesceSlow ()
 
void coalesceSlow (size_t maxLength)
 
void coalesceAndReallocate (size_t newHeadroom, size_t newLength, IOBuf *end, size_t newTailroom)
 
void coalesceAndReallocate (size_t newLength, IOBuf *end)
 
void decrementRefcount ()
 
void reserveSlow (std::size_t minHeadroom, std::size_t minTailroom)
 
void freeExtBuffer ()
 
SharedInfosharedInfo () const
 
void setSharedInfo (SharedInfo *info)
 
uintptr_t flags () const
 
void setFlags (uintptr_t flags) const
 
void clearFlags (uintptr_t flags) const
 
void setFlagsAndSharedInfo (uintptr_t flags, SharedInfo *info)
 

Static Private Member Functions

static size_t goodExtBufferSize (std::size_t minCapacity)
 
static void initExtBuffer (uint8_t *buf, size_t mallocSize, SharedInfo **infoReturn, std::size_t *capacityReturn)
 
static void allocExtBuffer (std::size_t minCapacity, uint8_t **bufReturn, SharedInfo **infoReturn, std::size_t *capacityReturn)
 
static void releaseStorage (HeapStorage *storage, uint16_t freeFlags)
 
static void freeInternalBuf (void *buf, void *userData)
 
static uintptr_t packFlagsAndSharedInfo (uintptr_t flags, SharedInfo *info)
 
static void freeUniquePtrBuffer (void *ptr, void *userData)
 

Private Attributes

IOBufnext_ {this}
 
IOBufprev_ {this}
 
uint8_tdata_ {nullptr}
 
uint8_tbuf_ {nullptr}
 
std::size_t length_ {0}
 
std::size_t capacity_ {0}
 
uintptr_t flagsAndSharedInfo_ {0}
 

Detailed Description

Definition at line 221 of file IOBuf.h.

Member Typedef Documentation

Definition at line 232 of file IOBuf.h.

typedef void(* folly::IOBuf::FreeFunction) (void *buf, void *userData)

Definition at line 234 of file IOBuf.h.

Definition at line 231 of file IOBuf.h.

Definition at line 230 of file IOBuf.h.

Member Enumeration Documentation

Enumerator
COPY_BUFFER 

Definition at line 228 of file IOBuf.h.

Enumerator
CREATE 

Definition at line 225 of file IOBuf.h.

enum folly::IOBuf::FlagsEnum : uintptr_t
private
Enumerator
kFlagFreeSharedInfo 
kFlagMaybeShared 
kFlagMask 

Definition at line 1338 of file IOBuf.h.

1338  : uintptr_t {
1339  // Adding any more flags would not work on 32-bit architectures,
1340  // as these flags are stashed in the least significant 2 bits of a
1341  // max-align-aligned pointer.
1342  kFlagFreeSharedInfo = 0x1,
1343  kFlagMaybeShared = 0x2,
1345  };
Enumerator
TAKE_OWNERSHIP 

Definition at line 227 of file IOBuf.h.

Enumerator
WRAP_BUFFER 

Definition at line 226 of file IOBuf.h.

Constructor & Destructor Documentation

folly::IOBuf::IOBuf ( CreateOp  ,
std::size_t  capacity 
)

Definition at line 195 of file IOBuf.cpp.

References allocExtBuffer(), buf_, capacity_, data_, deadlock::info(), and setSharedInfo().

196  : next_(this),
197  prev_(this),
198  data_(nullptr),
199  length_(0),
201  SharedInfo* info;
203  setSharedInfo(info);
204  data_ = buf_;
205 }
def info()
Definition: deadlock.py:447
static void allocExtBuffer(std::size_t minCapacity, uint8_t **bufReturn, SharedInfo **infoReturn, std::size_t *capacityReturn)
Definition: IOBuf.cpp:927
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
std::size_t capacity() const
Definition: IOBuf.h:593
uint8_t * data_
Definition: IOBuf.h:1432
void setSharedInfo(SharedInfo *info)
Definition: IOBuf.h:1453
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length_
Definition: IOBuf.h:1434
std::size_t capacity_
Definition: IOBuf.h:1435
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
folly::IOBuf::IOBuf ( TakeOwnershipOp  op,
void *  buf,
std::size_t  capacity,
FreeFunction  freeFn = nullptr,
void *  userData = nullptr,
bool  freeOnError = true 
)
inline

Definition at line 313 of file IOBuf.h.

References count, and type.

320  : IOBuf(op, buf, capacity, capacity, freeFn, userData, freeOnError) {}
std::size_t capacity() const
Definition: IOBuf.h:593
IOBuf() noexcept
Definition: IOBuf.cpp:361
folly::IOBuf::IOBuf ( TakeOwnershipOp  ,
void *  buf,
std::size_t  capacity,
std::size_t  length,
FreeFunction  freeFn = nullptr,
void *  userData = nullptr,
bool  freeOnError = true 
)

Definition at line 289 of file IOBuf.cpp.

References setSharedInfo().

297  : next_(this),
298  prev_(this),
299  data_(static_cast<uint8_t*>(buf)),
300  buf_(static_cast<uint8_t*>(buf)),
301  length_(length),
305  try {
306  setSharedInfo(new SharedInfo(freeFn, userData));
307  } catch (...) {
308  takeOwnershipError(freeOnError, buf, freeFn, userData);
309  throw;
310  }
311 }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
std::size_t capacity() const
Definition: IOBuf.h:593
uint8_t * data_
Definition: IOBuf.h:1432
void setSharedInfo(SharedInfo *info)
Definition: IOBuf.h:1453
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length() const
Definition: IOBuf.h:533
std::size_t length_
Definition: IOBuf.h:1434
static uintptr_t packFlagsAndSharedInfo(uintptr_t flags, SharedInfo *info)
Definition: IOBuf.h:1440
std::size_t capacity_
Definition: IOBuf.h:1435
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
folly::IOBuf::IOBuf ( WrapBufferOp  op,
const void *  buf,
std::size_t  capacity 
)
noexcept

Definition at line 338 of file IOBuf.cpp.

339  : IOBuf(
340  InternalConstructor(),
341  0,
342  // We cast away the const-ness of the buffer here.
343  // This is okay since IOBuf users must use unshare() to create a copy
344  // of this buffer before writing to the buffer.
345  static_cast<uint8_t*>(const_cast<void*>(buf)),
346  capacity,
347  static_cast<uint8_t*>(const_cast<void*>(buf)),
348  capacity) {}
std::size_t capacity() const
Definition: IOBuf.h:593
IOBuf() noexcept
Definition: IOBuf.cpp:361
folly::IOBuf::IOBuf ( WrapBufferOp  op,
ByteRange  br 
)
noexcept

Definition at line 350 of file IOBuf.cpp.

351  : IOBuf(op, br.data(), br.size()) {}
IOBuf() noexcept
Definition: IOBuf.cpp:361
folly::IOBuf::IOBuf ( CopyBufferOp  op,
const void *  buf,
std::size_t  size,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)

Definition at line 207 of file IOBuf.cpp.

References advance(), append(), and writableData().

213  : IOBuf(CREATE, headroom + size + minTailroom) {
214  advance(headroom);
215  if (size > 0) {
216  assert(buf != nullptr);
217  memcpy(writableData(), buf, size);
218  append(size);
219  }
220 }
void advance(std::size_t amount)
Definition: IOBuf.h:632
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
uint8_t * writableData()
Definition: IOBuf.h:509
std::size_t headroom() const
Definition: IOBuf.h:542
void append(std::size_t amount)
Definition: IOBuf.h:689
IOBuf() noexcept
Definition: IOBuf.cpp:361
folly::IOBuf::IOBuf ( CopyBufferOp  op,
ByteRange  br,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)

Definition at line 222 of file IOBuf.cpp.

227  : IOBuf(op, br.data(), br.size(), headroom, minTailroom) {}
std::size_t headroom() const
Definition: IOBuf.h:542
IOBuf() noexcept
Definition: IOBuf.cpp:361
folly::IOBuf::IOBuf ( CopyBufferOp  op,
const std::string buf,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)
inline

Definition at line 448 of file IOBuf.h.

References string.

453  : IOBuf(op, buf.data(), buf.size(), headroom, minTailroom) {}
std::size_t headroom() const
Definition: IOBuf.h:542
IOBuf() noexcept
Definition: IOBuf.cpp:361
folly::IOBuf::~IOBuf ( )

Destroy this IOBuf.

Deleting an IOBuf will automatically destroy all IOBufs in the chain. (See the comments above regarding the ownership model of IOBuf chains. All subsequent IOBufs in the chain are considered to be owned by the head of the chain. Users should only explicitly delete the head of a chain.)

When each individual IOBuf is destroyed, it will release its reference count on the underlying buffer. If it was the last user of the buffer, the buffer will be freed.

Definition at line 415 of file IOBuf.cpp.

References decrementRefcount(), next_, and unlink().

415  {
416  // Destroying an IOBuf destroys the entire chain.
417  // Users of IOBuf should only explicitly delete the head of any chain.
418  // The other elements in the chain will be automatically destroyed.
419  while (next_ != this) {
420  // Since unlink() returns unique_ptr() and we don't store it,
421  // it will automatically delete the unlinked element.
422  (void)next_->unlink();
423  }
424 
426 }
IOBuf * next_
Definition: IOBuf.h:1423
std::unique_ptr< IOBuf > unlink()
Definition: IOBuf.h:847
void decrementRefcount()
Definition: IOBuf.cpp:773
folly::IOBuf::IOBuf ( )
noexcept

Allocate a new null buffer.

This can be used to allocate an empty IOBuf on the stack. It will have no space allocated for it. This is generally useful only to later use move assignment to fill out the IOBuf.

Definition at line 361 of file IOBuf.cpp.

Referenced by cloneOneAsValue(), operator=(), and wrapBufferAsValue().

361 {}
folly::IOBuf::IOBuf ( IOBuf &&  other)
noexcept

Move constructor and assignment operator.

In general, you should only ever move the head of an IOBuf chain. Internal nodes in an IOBuf chain are owned by the head of the chain, and should not be moved from. (Technically, nothing prevents you from moving a non-head node, but the moved-to node will replace the moved-from node in the chain. This has implications for ownership, since non-head nodes are owned by the chain head. You are then responsible for relinquishing ownership of the moved-to node, and manually deleting the moved-from node.)

With the move assignment operator, the destination of the move should be the head of an IOBuf chain or a solitary IOBuf not part of a chain. If the move destination is part of a chain, all other IOBufs in the chain will be deleted.

Definition at line 363 of file IOBuf.cpp.

References next_, and prev_.

364  : data_(other.data_),
365  buf_(other.buf_),
366  length_(other.length_),
367  capacity_(other.capacity_),
368  flagsAndSharedInfo_(other.flagsAndSharedInfo_) {
369  // Reset other so it is a clean state to be destroyed.
370  other.data_ = nullptr;
371  other.buf_ = nullptr;
372  other.length_ = 0;
373  other.capacity_ = 0;
374  other.flagsAndSharedInfo_ = 0;
375 
376  // If other was part of the chain, assume ownership of the rest of its chain.
377  // (It's only valid to perform move assignment on the head of a chain.)
378  if (other.next_ != &other) {
379  next_ = other.next_;
380  next_->prev_ = this;
381  other.next_ = &other;
382 
383  prev_ = other.prev_;
384  prev_->next_ = this;
385  other.prev_ = &other;
386  }
387 
388  // Sanity check to make sure that other is in a valid state to be destroyed.
389  DCHECK_EQ(other.prev_, &other);
390  DCHECK_EQ(other.next_, &other);
391 }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length_
Definition: IOBuf.h:1434
std::size_t capacity_
Definition: IOBuf.h:1435
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
folly::IOBuf::IOBuf ( const IOBuf other)

Definition at line 393 of file IOBuf.cpp.

References cloneAsValue().

393  {
394  *this = other.cloneAsValue();
395 }
folly::IOBuf::IOBuf ( InternalConstructor  ,
uintptr_t  flagsAndSharedInfo,
uint8_t buf,
std::size_t  capacity,
uint8_t data,
std::size_t  length 
)
privatenoexcept

Definition at line 397 of file IOBuf.cpp.

References capacity(), data(), and length().

404  : next_(this),
405  prev_(this),
406  data_(data),
407  buf_(buf),
408  length_(length),
410  flagsAndSharedInfo_(flagsAndSharedInfo) {
411  assert(data >= buf);
412  assert(data + length <= buf + capacity);
413 }
IOBuf * next_
Definition: IOBuf.h:1423
const uint8_t * data() const
Definition: IOBuf.h:499
IOBuf * prev_
Definition: IOBuf.h:1424
std::size_t capacity() const
Definition: IOBuf.h:593
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length() const
Definition: IOBuf.h:533
std::size_t length_
Definition: IOBuf.h:1434
std::size_t capacity_
Definition: IOBuf.h:1435
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438

Member Function Documentation

void folly::IOBuf::advance ( std::size_t  amount)
inline

Shift the data forwards in the buffer.

This shifts the data pointer forwards in the buffer to increase the headroom. This is commonly used to increase the headroom in a newly allocated buffer.

The caller is responsible for ensuring that there is sufficient tailroom in the buffer before calling advance().

If there is a non-zero data length, advance() will use memmove() to shift the data forwards in the buffer. In this case, the caller is responsible for making sure the buffer is unshared, so it will not affect other IOBufs that may be sharing the same underlying buffer.

Definition at line 632 of file IOBuf.h.

References data_, and length_.

Referenced by folly::TypedIOBuf< T >::advance(), proxygen::GzipHeaderCodec::encode(), fizz::detail::evpEncrypt(), IOBuf(), and TEST().

632  {
633  // In debug builds, assert if there is a problem.
634  assert(amount <= tailroom());
635 
636  if (length_ > 0) {
637  memmove(data_ + amount, data_, length_);
638  }
639  data_ += amount;
640  }
std::size_t tailroom() const
Definition: IOBuf.h:551
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t length_
Definition: IOBuf.h:1434
void folly::IOBuf::allocExtBuffer ( std::size_t  minCapacity,
uint8_t **  bufReturn,
SharedInfo **  infoReturn,
std::size_t *  capacityReturn 
)
staticprivate

Definition at line 927 of file IOBuf.cpp.

References folly::checkedMalloc(), goodExtBufferSize(), initExtBuffer(), and uint8_t.

Referenced by coalesceAndReallocate(), IOBuf(), and unshareOneSlow().

931  {
932  size_t mallocSize = goodExtBufferSize(minCapacity);
933  uint8_t* buf = static_cast<uint8_t*>(checkedMalloc(mallocSize));
934  initExtBuffer(buf, mallocSize, infoReturn, capacityReturn);
935  *bufReturn = buf;
936 }
void * checkedMalloc(size_t size)
Definition: Malloc.h:227
static size_t goodExtBufferSize(std::size_t minCapacity)
Definition: IOBuf.cpp:938
static void initExtBuffer(uint8_t *buf, size_t mallocSize, SharedInfo **infoReturn, std::size_t *capacityReturn)
Definition: IOBuf.cpp:954
void folly::IOBuf::append ( std::size_t  amount)
inline

Adjust the tail pointer to include more valid data at the end.

This moves the tail pointer forwards to include more of the available buffer. The caller is responsible for ensuring that there is sufficient tailroom for the new data. The caller is also responsible for populating this section with valid data.

This does not modify any actual data in the buffer.

Definition at line 689 of file IOBuf.h.

References length_.

Referenced by append(), folly::TypedIOBuf< T >::append(), folly::IOBufQueue::append(), BENCHMARK(), folly::gen::detail::consumeBufferPlus(), folly::io::StreamCodec::doUncompress(), proxygen::GzipHeaderCodec::encode(), fizz::detail::evpDecrypt(), fizz::detail::evpEncrypt(), folly::AsyncPipeReader::handlerReady(), IOBuf(), main(), MoveToFbStringTest::makeBuf(), poolGetIOBuf(), proxygen::readFileToIOBuf(), CurlService::CurlClient::sendRequest(), TEST(), and TEST_F().

689  {
690  DCHECK_LE(amount, tailroom());
691  length_ += amount;
692  }
std::size_t tailroom() const
Definition: IOBuf.h:551
std::size_t length_
Definition: IOBuf.h:1434
void folly::IOBuf::appendChain ( std::unique_ptr< IOBuf > &&  iobuf)
inline

Append another IOBuf chain immediately after this IOBuf.

For example, if there are two IOBuf chains (A, B, C) and (D, E, F), and B->appendChain(D) is called, the (D, E, F) chain will be subsumed and become part of the chain starting at A, which will now look like (A, B, D, E, F, C)

The elements in the specified IOBuf chain will become part of this chain, and will be owned by the head of this chain. When this chain is destroyed, all elements in the supplied chain will also be destroyed.

For this reason, appendChain() only accepts an rvalue-reference to a unique_ptr(), to make it clear that it is taking ownership of the supplied chain. If you have a raw pointer, you can pass in a new temporary unique_ptr around the raw pointer. If you have an existing, non-temporary unique_ptr, you must call std::move(ptr) to make it clear that you are destroying the original pointer.

Definition at line 827 of file IOBuf.h.

References folly::gen::move.

Referenced by TEST(), TEST_F(), and TEST_P().

827  {
828  // Just use prependChain() on the next element in our chain
829  next_->prependChain(std::move(iobuf));
830  }
IOBuf * next_
Definition: IOBuf.h:1423
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void prependChain(std::unique_ptr< IOBuf > &&iobuf)
Definition: IOBuf.cpp:509
void folly::IOBuf::appendToIov ( folly::fbvector< struct iovec > *  iov) const

Update an existing iovec array with the IOBuf data.

New iovecs will be appended to the existing vector; anything already present in the vector will be left unchanged.

Naturally, the returned iovec data will be invalid if you modify the buffer chain.

Definition at line 1016 of file IOBuf.cpp.

References data(), length(), next(), and folly::fbvector< T, Allocator >::push_back().

Referenced by getIov().

1016  {
1017  IOBuf const* p = this;
1018  do {
1019  // some code can get confused by empty iovs, so skip them
1020  if (p->length() > 0) {
1021  iov->push_back({(void*)p->data(), folly::to<size_t>(p->length())});
1022  }
1023  p = p->next();
1024  } while (p != this);
1025 }
void push_back(const T &value)
Definition: FBVector.h:1156
IOBuf() noexcept
Definition: IOBuf.cpp:361
IOBuf::Iterator folly::IOBuf::begin ( ) const
inline

Definition at line 1684 of file IOBuf.h.

References folly::padded::cbegin().

Referenced by folly::io::StreamCodec::doUncompress().

1684  {
1685  return cbegin();
1686 }
Iterator cbegin() const
Definition: IOBuf.cpp:1001
const uint8_t* folly::IOBuf::buffer ( ) const
inline

Get the pointer to the start of the buffer.

Note that this is the pointer to the very beginning of the usable buffer, not the start of valid data within the buffer. Use the data() method to get a pointer to the start of the data within the buffer.

Definition at line 562 of file IOBuf.h.

Referenced by folly::TypedIOBuf< T >::buffer(), and TEST().

562  {
563  return buf_;
564  }
uint8_t * buf_
Definition: IOBuf.h:1433
const uint8_t* folly::IOBuf::bufferEnd ( ) const
inline

Get the pointer to the end of the buffer.

Note that this is the pointer to the very end of the usable buffer, not the end of valid data within the buffer. Use the tail() method to get a pointer to the end of the data within the buffer.

Definition at line 583 of file IOBuf.h.

Referenced by folly::TypedIOBuf< T >::bufferEnd().

583  {
584  return buf_ + capacity_;
585  }
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t capacity_
Definition: IOBuf.h:1435
std::size_t folly::IOBuf::capacity ( ) const
inline

Get the total size of the buffer.

This returns the total usable length of the buffer. Use the length() method to get the length of the actual valid data in this IOBuf.

Definition at line 593 of file IOBuf.h.

Referenced by BENCHMARK(), folly::TypedIOBuf< T >::capacity(), createCombined(), createSeparate(), folly::AsyncPipeReader::handlerReady(), IOBuf(), moveToFbString(), reserveSlow(), takeOwnership(), TEST(), testAllocSize(), wrapBuffer(), and wrapBufferAsValue().

593  {
594  return capacity_;
595  }
std::size_t capacity_
Definition: IOBuf.h:1435
IOBuf::Iterator folly::IOBuf::cbegin ( ) const

Iteration support: a chain of IOBufs may be iterated through using STL-style iterators over const ByteRanges. Iterators are only invalidated if the IOBuf that they currently point to is removed.

Definition at line 1001 of file IOBuf.cpp.

1001  {
1002  return Iterator(this, this);
1003 }
IOBuf::Iterator folly::IOBuf::cend ( ) const

Definition at line 1005 of file IOBuf.cpp.

1005  {
1006  return Iterator(nullptr, nullptr);
1007 }
void folly::IOBuf::clear ( )
inline

Clear the buffer.

Postcondition: headroom() == 0, length() == 0, tailroom() == capacity()

Definition at line 728 of file IOBuf.h.

References data_, and length_.

Referenced by folly::TypedIOBuf< T >::clear(), folly::IOBufQueue::clear(), folly::gen::detail::consumeBufferPlus(), moveToFbString(), and TEST().

728  {
729  data_ = writableBuffer();
730  length_ = 0;
731  }
uint8_t * writableBuffer()
Definition: IOBuf.h:572
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t length_
Definition: IOBuf.h:1434
void folly::IOBuf::clearFlags ( uintptr_t  flags) const
inlineprivate

Definition at line 1469 of file IOBuf.h.

1469  {
1470  DCHECK_EQ(flags & ~kFlagMask, 0u);
1472  }
flags
Definition: http_parser.h:127
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
unique_ptr< IOBuf > folly::IOBuf::clone ( ) const

Return a new IOBuf chain sharing the same data as this chain.

The new IOBuf chain will normally point to the same underlying data buffers as the original chain. (The one exception to this is if some of the IOBufs in this chain contain small internal data buffers which cannot be shared.)

Definition at line 527 of file IOBuf.cpp.

References cloneAsValue().

Referenced by BENCHMARK(), HTTP2FramerTest::dataFrameTest(), fizz::server::DualTicketCipher::decrypt(), folly::io::StreamCodec::doUncompress(), ZlibServerFilterTest::exercise_compression(), fizz::HkdfImpl< Hash >::expand(), proxygen::SPDYCodec::failSession(), proxygen::SPDYCodec::failStream(), folly::io::QueueAppender::insert(), UDPAcceptor::onDataAvailable(), proxygen::HTTP1xCodec::onIngress(), proxygen::IOBufPrinter::printChain(), TEST(), and proxygen::SecondaryAuthManager::validateAuthenticator().

527  {
528  return std::make_unique<IOBuf>(cloneAsValue());
529 }
IOBuf cloneAsValue() const
Definition: IOBuf.cpp:546
IOBuf folly::IOBuf::cloneAsValue ( ) const

Similar to clone(). But returns IOBuf by value rather than heap-allocating it.

Definition at line 546 of file IOBuf.cpp.

References cloneOneAsValue(), current, and next_.

Referenced by BENCHMARK(), clone(), and IOBuf().

546  {
547  auto tmp = cloneOneAsValue();
548 
549  for (IOBuf* current = next_; current != this; current = current->next_) {
550  tmp.prependChain(current->cloneOne());
551  }
552 
553  return tmp;
554 }
IOBuf cloneOneAsValue() const
Definition: IOBuf.cpp:556
IOBuf * next_
Definition: IOBuf.h:1423
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
unique_ptr< IOBuf > folly::IOBuf::cloneCoalesced ( ) const

Return a new unchained IOBuf that may share the same data as this chain.

If the IOBuf chain is not chained then the new IOBuf will point to the same underlying data buffer as the original chain. Otherwise, it will clone and coalesce the IOBuf chain.

The new IOBuf will have at least as much headroom as the first IOBuf in the chain, and at least as much tailroom as the last IOBuf in the chain.

Throws std::bad_alloc on error.

Definition at line 535 of file IOBuf.cpp.

References cloneCoalescedAsValue().

535  {
536  return std::make_unique<IOBuf>(cloneCoalescedAsValue());
537 }
IOBuf cloneCoalescedAsValue() const
Definition: IOBuf.cpp:570
IOBuf folly::IOBuf::cloneCoalescedAsValue ( ) const

Similar to cloneCoalesced(). But returns IOBuf by value rather than heap-allocating it.

Definition at line 570 of file IOBuf.cpp.

References cloneCoalescedAsValueWithHeadroomTailroom(), headroom(), prev(), and tailroom().

Referenced by BENCHMARK_RELATIVE(), cloneCoalesced(), folly::io::StreamCodec::doUncompress(), and folly::io::test::TEST_P().

570  {
571  const std::size_t newHeadroom = headroom();
572  const std::size_t newTailroom = prev()->tailroom();
573  return cloneCoalescedAsValueWithHeadroomTailroom(newHeadroom, newTailroom);
574 }
std::size_t tailroom() const
Definition: IOBuf.h:551
std::size_t headroom() const
Definition: IOBuf.h:542
IOBuf * prev()
Definition: IOBuf.h:610
IOBuf cloneCoalescedAsValueWithHeadroomTailroom(std::size_t newHeadroom, std::size_t newTailroom) const
Definition: IOBuf.cpp:576
IOBuf folly::IOBuf::cloneCoalescedAsValueWithHeadroomTailroom ( std::size_t  newHeadroom,
std::size_t  newTailroom 
) const

This is similar to the cloneCoalescedAsValue() method, except this allows to set a headroom and tailroom for the new IOBuf.

Definition at line 576 of file IOBuf.cpp.

References cloneOneAsValue(), computeChainDataLength(), CREATE, current, and isChained().

Referenced by cloneCoalescedAsValue(), and cloneCoalescedWithHeadroomTailroom().

578  {
579  if (!isChained()) {
580  return cloneOneAsValue();
581  }
582  // Coalesce into newBuf
583  const std::size_t newLength = computeChainDataLength();
584  const std::size_t newCapacity = newLength + newHeadroom + newTailroom;
585  IOBuf newBuf{CREATE, newCapacity};
586  newBuf.advance(newHeadroom);
587 
588  auto current = this;
589  do {
590  if (current->length() > 0) {
591  DCHECK_NOTNULL(current->data());
592  DCHECK_LE(current->length(), newBuf.tailroom());
593  memcpy(newBuf.writableTail(), current->data(), current->length());
594  newBuf.append(current->length());
595  }
596  current = current->next();
597  } while (current != this);
598 
599  DCHECK_EQ(newLength, newBuf.length());
600  DCHECK_EQ(newHeadroom, newBuf.headroom());
601  DCHECK_LE(newTailroom, newBuf.tailroom());
602 
603  return newBuf;
604 }
IOBuf cloneOneAsValue() const
Definition: IOBuf.cpp:556
bool isChained() const
Definition: IOBuf.h:760
int current
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
IOBuf() noexcept
Definition: IOBuf.cpp:361
unique_ptr< IOBuf > folly::IOBuf::cloneCoalescedWithHeadroomTailroom ( std::size_t  newHeadroom,
std::size_t  newTailroom 
) const

This is similar to the cloneCoalesced() method, except this allows to set a headroom and tailroom for the new IOBuf.

Definition at line 539 of file IOBuf.cpp.

References cloneCoalescedAsValueWithHeadroomTailroom().

541  {
542  return std::make_unique<IOBuf>(
543  cloneCoalescedAsValueWithHeadroomTailroom(newHeadroom, newTailroom));
544 }
IOBuf cloneCoalescedAsValueWithHeadroomTailroom(std::size_t newHeadroom, std::size_t newTailroom) const
Definition: IOBuf.cpp:576
void folly::IOBuf::cloneInto ( IOBuf other) const
inline

Similar to Clone(). But use other as the head node. Other nodes in the chain (if any) will be allocted on heap.

Definition at line 1213 of file IOBuf.h.

Referenced by BENCHMARK().

1213  {
1214  other = cloneAsValue();
1215  }
IOBuf cloneAsValue() const
Definition: IOBuf.cpp:546
unique_ptr< IOBuf > folly::IOBuf::cloneOne ( ) const

Return a new IOBuf with the same data as this IOBuf.

The new IOBuf returned will not be part of a chain (even if this IOBuf is part of a larger chain).

Definition at line 531 of file IOBuf.cpp.

References cloneOneAsValue().

Referenced by BENCHMARK(), ZlibServerFilterTest::exercise_compression(), proxygen::HTTP1xCodec::onBody(), proxygen::HTTP1xCodec::onParserError(), and TEST().

531  {
532  return std::make_unique<IOBuf>(cloneOneAsValue());
533 }
IOBuf cloneOneAsValue() const
Definition: IOBuf.cpp:556
IOBuf folly::IOBuf::cloneOneAsValue ( ) const

Similar to cloneOne(). But returns IOBuf by value rather than heap-allocating it.

Definition at line 556 of file IOBuf.cpp.

References buf_, capacity_, data_, flagsAndSharedInfo_, deadlock::info(), IOBuf(), kFlagMaybeShared, length_, setFlags(), and sharedInfo().

Referenced by cloneAsValue(), cloneCoalescedAsValueWithHeadroomTailroom(), and cloneOne().

556  {
557  if (SharedInfo* info = sharedInfo()) {
559  info->refcount.fetch_add(1, std::memory_order_acq_rel);
560  }
561  return IOBuf(
562  InternalConstructor(),
564  buf_,
565  capacity_,
566  data_,
567  length_);
568 }
def info()
Definition: deadlock.py:447
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length_
Definition: IOBuf.h:1434
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
std::size_t capacity_
Definition: IOBuf.h:1435
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
void setFlags(uintptr_t flags) const
Definition: IOBuf.h:1464
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::cloneOneInto ( IOBuf other) const
inline

Similar to CloneOne(). But to fill an existing IOBuf instead of a new IOBuf.

Definition at line 1221 of file IOBuf.h.

References folly::test::begin(), folly::padded::cbegin(), folly::padded::cend(), count, folly::test::end(), folly::pushmi::__adl::noexcept(), ptr, and folly::size().

Referenced by BENCHMARK().

1221  {
1222  other = cloneOneAsValue();
1223  }
IOBuf cloneOneAsValue() const
Definition: IOBuf.cpp:556
ByteRange folly::IOBuf::coalesce ( )
inline

Coalesce this IOBuf chain into a single buffer.

This method moves all of the data in this IOBuf chain into a single contiguous buffer, if it is not already in one buffer. After coalesce() returns, this IOBuf will be a chain of length one. Other IOBufs in the chain will be automatically deleted.

After coalescing, the IOBuf will have at least as much headroom as the first IOBuf in the chain, and at least as much tailroom as the last IOBuf in the chain.

Throws std::bad_alloc on error. On error the IOBuf chain will be unmodified.

Returns ByteRange that points to the data IOBuf stores.

Definition at line 1095 of file IOBuf.h.

Referenced by BENCHMARK(), folly::io::StreamCodec::doUncompress(), fizz::EncryptedReadRecordLayer::getDecryptedBuf(), wangle::SSLSessionCacheManager::onGetSuccess(), proxygen::IOBufPrinter::printChain(), wangle::StringCodec::read(), HTTPUpstreamTest< SPDY3CodecPair >::readAndLoop(), TEST_F(), folly::AsyncUDPSocket::writeGSO(), and ConnectedWriteUDPClient::writePing().

1095  {
1096  const std::size_t newHeadroom = headroom();
1097  const std::size_t newTailroom = prev()->tailroom();
1098  return coalesceWithHeadroomTailroom(newHeadroom, newTailroom);
1099  }
std::size_t tailroom() const
Definition: IOBuf.h:551
std::size_t headroom() const
Definition: IOBuf.h:542
IOBuf * prev()
Definition: IOBuf.h:610
ByteRange coalesceWithHeadroomTailroom(std::size_t newHeadroom, std::size_t newTailroom)
Definition: IOBuf.h:1107
void folly::IOBuf::coalesceAndReallocate ( size_t  newHeadroom,
size_t  newLength,
IOBuf end,
size_t  newTailroom 
)
private

Definition at line 722 of file IOBuf.cpp.

References allocExtBuffer(), buf_, capacity_, current, data_, decrementRefcount(), isChained(), length_, next_, prev_, separateChain(), setFlagsAndSharedInfo(), and uint8_t.

Referenced by coalesceSlow(), and moveToFbString().

726  {
727  std::size_t newCapacity = newLength + newHeadroom + newTailroom;
728 
729  // Allocate space for the coalesced buffer.
730  // We always convert to an external buffer, even if we happened to be an
731  // internal buffer before.
732  uint8_t* newBuf;
733  SharedInfo* newInfo;
734  std::size_t actualCapacity;
735  allocExtBuffer(newCapacity, &newBuf, &newInfo, &actualCapacity);
736 
737  // Copy the data into the new buffer
738  uint8_t* newData = newBuf + newHeadroom;
739  uint8_t* p = newData;
740  IOBuf* current = this;
741  size_t remaining = newLength;
742  do {
743  if (current->length_ > 0) {
744  assert(current->length_ <= remaining);
745  assert(current->data_ != nullptr);
746  remaining -= current->length_;
747  memcpy(p, current->data_, current->length_);
748  p += current->length_;
749  }
750  current = current->next_;
751  } while (current != end);
752  assert(remaining == 0);
753 
754  // Point at the new buffer
756 
757  // Make sure kFlagMaybeShared and kFlagFreeSharedInfo are all cleared.
758  setFlagsAndSharedInfo(0, newInfo);
759 
760  capacity_ = actualCapacity;
761  buf_ = newBuf;
762  data_ = newData;
763  length_ = newLength;
764 
765  // Separate from the rest of our chain.
766  // Since we don't store the unique_ptr returned by separateChain(),
767  // this will immediately delete the returned subchain.
768  if (isChained()) {
769  (void)separateChain(next_, current->prev_);
770  }
771 }
static void allocExtBuffer(std::size_t minCapacity, uint8_t **bufReturn, SharedInfo **infoReturn, std::size_t *capacityReturn)
Definition: IOBuf.cpp:927
Iterator end() const
Definition: IOBuf.h:1687
IOBuf * next_
Definition: IOBuf.h:1423
bool isChained() const
Definition: IOBuf.h:760
IOBuf * prev_
Definition: IOBuf.h:1424
std::unique_ptr< IOBuf > separateChain(IOBuf *head, IOBuf *tail)
Definition: IOBuf.h:883
int current
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length_
Definition: IOBuf.h:1434
std::size_t capacity_
Definition: IOBuf.h:1435
void setFlagsAndSharedInfo(uintptr_t flags, SharedInfo *info)
Definition: IOBuf.h:1474
void decrementRefcount()
Definition: IOBuf.cpp:773
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::coalesceAndReallocate ( size_t  newLength,
IOBuf end 
)
inlineprivate

Definition at line 1391 of file IOBuf.h.

References prev_, tailroom(), uint16_t, and uint8_t.

1391  {
1392  coalesceAndReallocate(headroom(), newLength, end, end->prev_->tailroom());
1393  }
Iterator end() const
Definition: IOBuf.h:1687
void coalesceAndReallocate(size_t newHeadroom, size_t newLength, IOBuf *end, size_t newTailroom)
Definition: IOBuf.cpp:722
std::size_t headroom() const
Definition: IOBuf.h:542
void folly::IOBuf::coalesceSlow ( )
private

Definition at line 677 of file IOBuf.cpp.

References coalesceAndReallocate(), end(), isChained(), length_, and next_.

Referenced by unshareChained().

677  {
678  // coalesceSlow() should only be called if we are part of a chain of multiple
679  // IOBufs. The caller should have already verified this.
680  DCHECK(isChained());
681 
682  // Compute the length of the entire chain
683  std::size_t newLength = 0;
684  IOBuf* end = this;
685  do {
686  newLength += end->length_;
687  end = end->next_;
688  } while (end != this);
689 
690  coalesceAndReallocate(newLength, end);
691  // We should be only element left in the chain now
692  DCHECK(!isChained());
693 }
Iterator end() const
Definition: IOBuf.h:1687
bool isChained() const
Definition: IOBuf.h:760
void coalesceAndReallocate(size_t newHeadroom, size_t newLength, IOBuf *end, size_t newTailroom)
Definition: IOBuf.cpp:722
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::coalesceSlow ( size_t  maxLength)
private

Definition at line 695 of file IOBuf.cpp.

References coalesceAndReallocate(), end(), isChained(), length_, and next_.

695  {
696  // coalesceSlow() should only be called if we are part of a chain of multiple
697  // IOBufs. The caller should have already verified this.
698  DCHECK(isChained());
699  DCHECK_LT(length_, maxLength);
700 
701  // Compute the length of the entire chain
702  std::size_t newLength = 0;
703  IOBuf* end = this;
704  while (true) {
705  newLength += end->length_;
706  end = end->next_;
707  if (newLength >= maxLength) {
708  break;
709  }
710  if (end == this) {
711  throw std::overflow_error(
712  "attempted to coalesce more data than "
713  "available");
714  }
715  }
716 
717  coalesceAndReallocate(newLength, end);
718  // We should have the requested length now
719  DCHECK_GE(length_, maxLength);
720 }
Iterator end() const
Definition: IOBuf.h:1687
bool isChained() const
Definition: IOBuf.h:760
void coalesceAndReallocate(size_t newHeadroom, size_t newLength, IOBuf *end, size_t newTailroom)
Definition: IOBuf.cpp:722
std::size_t length_
Definition: IOBuf.h:1434
IOBuf() noexcept
Definition: IOBuf.cpp:361
ByteRange folly::IOBuf::coalesceWithHeadroomTailroom ( std::size_t  newHeadroom,
std::size_t  newTailroom 
)
inline

This is similar to the coalesce() method, except this allows to set a headroom and tailroom after coalescing.

Returns ByteRange that points to the data IOBuf stores.

Definition at line 1107 of file IOBuf.h.

References data_, and length_.

1109  {
1110  if (isChained()) {
1112  newHeadroom, computeChainDataLength(), this, newTailroom);
1113  }
1114  return ByteRange(data_, length_);
1115  }
bool isChained() const
Definition: IOBuf.h:760
void coalesceAndReallocate(size_t newHeadroom, size_t newLength, IOBuf *end, size_t newTailroom)
Definition: IOBuf.cpp:722
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t length_
Definition: IOBuf.h:1434
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
std::size_t folly::IOBuf::computeChainDataLength ( ) const

Get the length of all the data in this IOBuf chain.

Beware that this method has to walk the entire chain.

Definition at line 501 of file IOBuf.cpp.

References current, length_, and next_.

Referenced by MoveToFbStringTest::check(), checkQError(), fizz::test::chunkIOBuf(), cloneCoalescedAsValueWithHeadroomTailroom(), folly::io::Codec::compress(), proxygen::SecondaryAuthManager::createAuthRequest(), proxygen::compress::QMINScheme::decode(), fizz::AsyncFizzBase::deliverAppData(), TestAbortPost< stage >::doAbortTest(), folly::io::StreamCodec::doCompress(), folly::io::StreamCodec::doUncompress(), proxygen::HTTP1xCodec::generateBody(), proxygen::SPDYCodec::generateBody(), proxygen::FlowControlFilter::generateBody(), proxygen::SPDYCodec::generateSynReply(), proxygen::SPDYCodec::generateSynStream(), proxygen::HTTPSession::getCertAuthSettingVal(), folly::io::Codec::getUncompressedLength(), folly::io::RWCursor< access >::insert(), isLowercase(), moveToFbString(), HTTP1xCodecCallback::onBody(), proxygen::FlowControlFilter::onBody(), proxygen::FakeHTTPCodecCallback::onBody(), proxygen::HTTPSession::onBody(), proxygen::HTTPDirectResponseHandler::onHeadersComplete(), proxygen::HTTP1xCodec::onIngress(), proxygen::SPDYCodec::onIngress(), proxygen::HTTPTransaction::onIngressBody(), MockCodecDownstreamTest::onIngressImpl(), proxygen::SPDYCodec::parseIngress(), fizz::test::LocalTransport::receiveData(), proxygen::HPACKCodec::recordCompressedSize(), proxygen::HTTPTransaction::resumeIngress(), proxygen::HTTPSession::runLoopCallback(), proxygen::HTTPTransaction::sendBody(), TEST(), TEST_F(), fizz::test::TEST_F(), folly::io::test::TEST_P(), folly::io::Codec::uncompress(), proxygen::HTTPSession::verifyCertAuthSetting(), wangle::LengthFieldPrepender::write(), proxygen::http2::writeCertificate(), and proxygen::http2::writeCertificateRequest().

501  {
502  std::size_t fullLength = length_;
503  for (IOBuf* current = next_; current != this; current = current->next_) {
504  fullLength += current->length_;
505  }
506  return fullLength;
507 }
IOBuf * next_
Definition: IOBuf.h:1423
int current
std::size_t length_
Definition: IOBuf.h:1434
IOBuf() noexcept
Definition: IOBuf.cpp:361
std::unique_ptr< IOBuf > folly::IOBuf::copyBuffer ( const void *  buf,
std::size_t  size,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)
inlinestatic

Convenience function to create a new IOBuf object that copies data from a user-supplied buffer, optionally allocating a given amount of headroom and tailroom.

Definition at line 1587 of file IOBuf.h.

References data, and folly::size().

Referenced by fizz::test::TestMessages::addPsk(), fizz::test::TestMessages::appData(), fizz::server::appendClientCertificate(), fizz::test::appWrite(), fizz::test::TestMessages::appWrite(), fizz::test::TestMessages::certificate(), fizz::test::TestMessages::certificateRequest(), fizz::test::TestMessages::certificateVerify(), fizz::test::TestMessages::clientHello(), folly::AsyncSSLSocket::clientHelloParsingCallback(), fizz::test::HandshakeTest::clientWrite(), fizz::client::test::AsyncFizzClientTest::completeEarlyHandshake(), fizz::test::TestMessages::compressedCertificate(), fizz::test::copyBuffer(), ZlibServerFilterTest::createResponseChain(), fizz::detail::decodeAuthRequest(), fizz::test::HandshakeTypesTest::decodeHex(), fizz::test::ZlibCertificateCompressorTest::decodeHex(), fizz::KeyDerivationImpl< Hash >::deriveSecret(), fizz::client::test::ClientProtocolTest::doFinishedFlow(), fizz::test::TestMessages::earlyAppWrite(), ObservingHandlerTest::MockIntToByteEncoder::encode(), fizz::server::TicketCodec< Storage >::encode(), StringToByteEncoder::encode(), proxygen::compress::QMINScheme::encode(), fizz::encodeHkdfLabel(), fizz::test::TestMessages::encryptedExt(), fizz::test::TestMessages::endOfEarlyData(), ZlibServerFilterTest::exercise_compression(), fizz::server::test::AsyncFizzServerTest::expectAppClose(), fizz::client::test::AsyncFizzClientTest::expectAppClose(), fizz::server::test::ServerProtocolTest::expectCookie(), fizz::server::test::AeadTicketCipherTest::expectDecode(), fizz::test::ProtocolTest< ClientTypes, Actions >::expectError(), fizz::test::TestMessages::finished(), fizz::server::test::AsyncFizzServerTest::fullHandshakeSuccess(), fizz::client::test::AsyncFizzClientTest::fullHandshakeSuccess(), fizz::sm::generateTicket(), fizz::test::ExtensionsTest::getBuf(), fizz::test::PlaintextRecordTest::getBuf(), fizz::extensions::test::TokenBindingConstructorTest::getBuf(), fizz::test::EncryptedRecordTest::getBuf(), fizz::test::RecordTest::getBuf(), fizz::extensions::test::ValidatorTest::getBuf(), fizz::sm::getCertificateRequest(), getChunkedRequest1st(), getChunkedRequest2nd(), fizz::sm::getClientHello(), fizz::client::test::ClientProtocolTest::getEarlyDataParams(), fizz::sm::getEarlyDataParams(), fizz::sm::getEncryptedExt(), TestData::getInBuf(), fizz::X25519KeyExchange::getKeyShare(), fizz::sm::getPskExtension(), getSimpleRequestData(), fizz::server::test::getTestResumptionState(), fizz::server::test::getV2ClientHello(), getVersionedSpdyFrame(), GSOBuf::GSOBuf(), fizz::sm::handleCertMsg(), fizz::test::TestMessages::helloRetryRequest(), makeRandom(), fizz::test::MATCHER_P(), MATCHER_P2(), fizz::sm::negotiatePsk(), fizz::test::TestMessages::newSessionTicket(), TestHandlerFactory::TestHandler::onEOM(), proxygen::HTTPSession::onSessionParseError(), proxygen::parse(), HTTPDownstreamTest< SPDY3_1CodecPair >::parseOutput(), proxygen::parseUnidirectional(), wangle::SocketPeeker::readDataAvailable(), fizz::test::HandshakeTest::resetTransportsAndStartCookieHandshake(), folly::io::test::CompressionVarintTest::runSimpleTest(), proxygen::HTTPHandlerBase::sendBody(), proxygen::HTTPHandlerBase::sendChunkedReplyWithBody(), proxygen::ZlibServerFilter::sendEOM(), UDPClient::sendPing(), UDPAcceptor::sendPong(), fizz::test::TestMessages::serverHello(), fizz::test::HandshakeTest::serverWrite(), fizz::MockKeyExchange::setDefaults(), fizz::test::MockKeyScheduler::setDefaults(), fizz::test::MockAead::setDefaults(), fizz::MockPlaintextWriteRecordLayer::setDefaults(), fizz::test::MockHandshakeContext::setDefaults(), fizz::server::test::MockTicketCipher::setDefaults(), fizz::test::AuthenticatorTest::SetUp(), fizz::client::test::ClientProtocolTest::setupAcceptingData(), fizz::server::test::ServerProtocolTest::setUpExpectingCertificate(), fizz::server::test::ServerProtocolTest::setUpExpectingCertificateVerify(), fizz::server::test::ServerProtocolTest::setUpExpectingFinished(), fizz::client::test::ClientProtocolTest::setupExpectingFinished(), fizz::client::test::ClientProtocolTest::setupExpectingServerHello(), fizz::setWriteDefaults(), folly::io::test::CompressionTest::split(), fizz::test::TEST(), fizz::server::test::TEST(), folly::test::TEST(), folly::TEST(), TEST(), fizz::server::test::TEST_F(), fizz::test::TEST_F(), fizz::client::test::TEST_F(), TEST_F(), fizz::testing::TEST_P(), fizz::test::TEST_P(), TEST_P(), folly::io::test::TEST_P(), fizz::test::toIOBuf(), toIOBuf(), ThreadPrintingHandler::transportActive(), fizz::test::TYPED_TEST(), ClientSerializeHandler::write(), ServerSerializeHandler::write(), wangle::StringCodec::write(), fizz::EncryptedWriteRecordLayer::write(), and fizz::test::writeNewSessionTicket().

1591  {
1592  std::size_t capacity = headroom + size + minTailroom;
1593  std::unique_ptr<IOBuf> buf = create(capacity);
1594  buf->advance(headroom);
1595  if (size != 0) {
1596  memcpy(buf->writableData(), data, size);
1597  }
1598  buf->append(size);
1599  return buf;
1600 }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
const uint8_t * data() const
Definition: IOBuf.h:499
std::size_t capacity() const
Definition: IOBuf.h:593
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
std::size_t headroom() const
Definition: IOBuf.h:542
static std::unique_ptr<IOBuf> folly::IOBuf::copyBuffer ( ByteRange  br,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)
inlinestatic

Definition at line 415 of file IOBuf.h.

References fizz::test::copyBuffer(), folly::Range< Iter >::data(), folly::Range< Iter >::size(), and string.

418  {
419  return copyBuffer(br.data(), br.size(), headroom, minTailroom);
420  }
std::size_t headroom() const
Definition: IOBuf.h:542
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
std::unique_ptr< IOBuf > folly::IOBuf::copyBuffer ( const std::string buf,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)
inlinestatic

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.

Definition at line 1602 of file IOBuf.h.

References fizz::test::copyBuffer().

1605  {
1606  return copyBuffer(buf.data(), buf.size(), headroom, minTailroom);
1607 }
std::size_t headroom() const
Definition: IOBuf.h:542
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
size_t folly::IOBuf::countChainElements ( ) const

Get the number of IOBufs in this chain.

Beware that this method has to walk the entire chain. Use isChained() if you just want to check if this IOBuf is part of a chain or not.

Definition at line 493 of file IOBuf.cpp.

References current, and next_.

Referenced by MoveToFbStringTest::check(), fizz::test::chunkIOBuf(), ZlibServerFilterTest::exercise_compression(), getIov(), TEST(), TEST_F(), and fizz::trimBytes().

493  {
494  size_t numElements = 1;
495  for (IOBuf* current = next_; current != this; current = current->next_) {
496  ++numElements;
497  }
498  return numElements;
499 }
IOBuf * next_
Definition: IOBuf.h:1423
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
unique_ptr< IOBuf > folly::IOBuf::create ( std::size_t  capacity)
static

Allocate a new IOBuf object with the requested capacity.

Returns a new IOBuf object that must be (eventually) deleted by the caller. The returned IOBuf may actually have slightly more capacity than requested.

The data pointer will initially point to the start of the newly allocated buffer, and will have a data length of 0.

Throws std::bad_alloc on error.

Definition at line 229 of file IOBuf.cpp.

References createCombined(), and createSeparate().

Referenced by folly::io::addOutputBuffer(), folly::IOBufQueue::append(), fizz::server::appendClientCertificate(), BENCHMARK(), fizz::test::ExtensionsTest::checkEncode(), AcceptRoutingHandlerTest::clientConnectAndWrite(), fizz::test::TestMessages::clientHello(), fizz::KeyScheduler::clientKeyUpdate(), folly::io::test::compressSome(), fizz::detail::computeFinishedTranscript(), fizz::detail::computeTranscript(), fizz::detail::computeTranscriptHash(), fizz::extensions::Validator::constructECDSASig(), fizz::extensions::Validator::constructEcKeyFromBuf(), fizz::extensions::TokenBindingUtils::constructMessage(), fizz::JavaCryptoCertificateVerifier::createAuthorities(), fizz::DefaultCertificateVerifier::createAuthorities(), fizz::test::createBuf(), createChain(), fizz::extensions::TokenBindingConstructor::createTokenBinding(), fizz::ZlibCertificateDecompressor::decompress(), proxygen::ZstdStreamDecompressor::decompress(), fizz::test::defaultCreator(), folly::ssl::OpenSSLCertUtils::derEncode(), folly::io::StreamCodec::doUncompress(), fizz::detail::ecSign(), fizz::server::TicketCodec< Storage >::encode(), fizz::encode(), fizz::encode< Alert >(), fizz::encode< CertificateRequest >(), fizz::encode< CertificateVerify >(), fizz::encode< CompressedCertificate & >(), fizz::encode< const CertificateMsg & >(), fizz::encode< const ClientHello & >(), fizz::encode< EncryptedExtensions >(), fizz::encode< EndOfEarlyData >(), fizz::encode< HelloRetryRequest >(), fizz::encode< KeyUpdate >(), fizz::encode< NewSessionTicket >(), fizz::encode< ServerHello >(), fizz::server::detail::encodeCookie(), fizz::extensions::TokenBindingConstructor::encodeEcdsaSignature(), fizz::detail::encodeECPublicKey(), fizz::encodeExtension(), fizz::encodeHandshake(), fizz::encodeHkdfLabel(), fizz::server::AeadTokenCipher< AeadType, HkdfType >::encrypt(), folly::io::Appender::ensure(), fizz::detail::evpDecrypt(), fizz::detail::evpEncrypt(), fizz::HkdfImpl< Hash >::expand(), fizz::server::test::ServerProtocolTest::expectCookie(), folly::gen::fromFile(), fizz::detail::generateEvpSharedSecret(), fizz::X25519KeyExchange::generateSharedSecret(), fizz::sm::generateTicket(), fizz::CertUtils::getCertMessage(), fizz::sm::getEarlyDataParams(), fizz::Exporter::getEkm(), fizz::HandshakeContextImpl< Hash >::getFinishedData(), fizz::detail::getFinishedData(), fizz::HandshakeContextImpl< Hash >::getHandshakeContext(), fizz::sm::getPskExtension(), fizz::server::getStatelessHelloRetryRequest(), fizz::KeyScheduler::getTrafficKey(), folly::AsyncPipeReader::handlerReady(), main(), makeBuf(), proxygen::makeBuf(), fizz::test::TestMessages::newSessionTicket(), poolGetIOBuf(), folly::IOBufQueue::preallocateSlow(), fizz::CertUtils::prepareSignData(), folly::recordio_helpers::prependHeader(), fizz::EncryptedReadRecordLayer::read(), fizz::detail::rsaPssSign(), fizz::test::TestMessages::serverHello(), fizz::KeyScheduler::serverKeyUpdate(), fizz::test::KeySchedulerTest::SetUp(), fizz::client::test::ClientProtocolTest::setupExpectingServerHello(), fizz::extensions::test::ValidatorTest::setUpWithKeyParameters(), folly::IOBufQueue::split(), takeOwnershipIov(), fizz::test::TEST(), folly::io::test::TEST(), TEST(), fizz::test::TEST_F(), TEST_F(), fizz::client::test::TEST_F(), fizz::server::test::TEST_F(), fizz::test::TEST_P(), TEST_P(), folly::io::test::TEST_P(), folly::bser::toBserIOBuf(), folly::gen::toFile(), folly::io::Appender::tryGrowChain(), folly::io::Codec::uncompress(), folly::io::test::uncompressSome(), fizz::ExportedAuthenticator::validate(), wrapIov(), wangle::LengthFieldPrepender::write(), fizz::PlaintextWriteRecordLayer::write(), and fizz::EncryptedWriteRecordLayer::write().

229  {
230  // For smaller-sized buffers, allocate the IOBuf, SharedInfo, and the buffer
231  // all with a single allocation.
232  //
233  // We don't do this for larger buffers since it can be wasteful if the user
234  // needs to reallocate the buffer but keeps using the same IOBuf object.
235  // In this case we can't free the data space until the IOBuf is also
236  // destroyed. Callers can explicitly call createCombined() or
237  // createSeparate() if they know their use case better, and know if they are
238  // likely to reallocate the buffer later.
239  if (capacity <= kDefaultCombinedBufSize) {
240  return createCombined(capacity);
241  }
242  return createSeparate(capacity);
243 }
static std::unique_ptr< IOBuf > createCombined(std::size_t capacity)
Definition: IOBuf.cpp:245
std::size_t capacity() const
Definition: IOBuf.h:593
static std::unique_ptr< IOBuf > createSeparate(std::size_t capacity)
Definition: IOBuf.cpp:268
unique_ptr< IOBuf > folly::IOBuf::createChain ( size_t  totalCapacity,
std::size_t  maxBufCapacity 
)
static

Allocate a new IOBuf chain with the requested total capacity, allocating no more than maxBufCapacity to each buffer.

Definition at line 272 of file IOBuf.cpp.

References create(), min, and folly::gen::move.

274  {
275  unique_ptr<IOBuf> out =
276  create(std::min(totalCapacity, size_t(maxBufCapacity)));
277  size_t allocatedCapacity = out->capacity();
278 
279  while (allocatedCapacity < totalCapacity) {
280  unique_ptr<IOBuf> newBuf = create(
281  std::min(totalCapacity - allocatedCapacity, size_t(maxBufCapacity)));
282  allocatedCapacity += newBuf->capacity();
283  out->prependChain(std::move(newBuf));
284  }
285 
286  return out;
287 }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
LogLevel min
Definition: LogLevel.cpp:30
unique_ptr< IOBuf > folly::IOBuf::createCombined ( std::size_t  capacity)
static

Create a new IOBuf, using a single memory allocation to allocate space for both the IOBuf object and the data storage space.

This saves one memory allocation. However, it can be wasteful if you later need to grow the buffer using reserve(). If the buffer needs to be reallocated, the space originally allocated will not be freed() until the IOBuf object itself is also freed. (It can also be slightly wasteful in some cases where you clone this IOBuf and then free the original IOBuf.)

Definition at line 245 of file IOBuf.cpp.

References capacity(), folly::checkedMalloc(), freeInternalBuf(), folly::goodMallocSize(), packFlagsAndSharedInfo(), and uint8_t.

Referenced by create().

245  {
246  // To save a memory allocation, allocate space for the IOBuf object, the
247  // SharedInfo struct, and the data itself all with a single call to malloc().
248  size_t requiredStorage = offsetof(HeapFullStorage, align) + capacity;
249  size_t mallocSize = goodMallocSize(requiredStorage);
250  auto* storage = static_cast<HeapFullStorage*>(checkedMalloc(mallocSize));
251 
252  new (&storage->hs.prefix) HeapPrefix(kIOBufInUse | kDataInUse);
253  new (&storage->shared) SharedInfo(freeInternalBuf, storage);
254 
255  uint8_t* bufAddr = reinterpret_cast<uint8_t*>(&storage->align);
256  uint8_t* storageEnd = reinterpret_cast<uint8_t*>(storage) + mallocSize;
257  size_t actualCapacity = size_t(storageEnd - bufAddr);
258  unique_ptr<IOBuf> ret(new (&storage->hs.buf) IOBuf(
259  InternalConstructor(),
260  packFlagsAndSharedInfo(0, &storage->shared),
261  bufAddr,
262  actualCapacity,
263  bufAddr,
264  0));
265  return ret;
266 }
void * checkedMalloc(size_t size)
Definition: Malloc.h:227
std::size_t capacity() const
Definition: IOBuf.h:593
static uintptr_t packFlagsAndSharedInfo(uintptr_t flags, SharedInfo *info)
Definition: IOBuf.h:1440
static void freeInternalBuf(void *buf, void *userData)
Definition: IOBuf.cpp:190
size_t goodMallocSize(size_t minSize) noexcept
Definition: Malloc.h:201
IOBuf() noexcept
Definition: IOBuf.cpp:361
unique_ptr< IOBuf > folly::IOBuf::createSeparate ( std::size_t  capacity)
static

Create a new IOBuf, using separate memory allocations for the IOBuf object for the IOBuf and the data storage space.

This requires two memory allocations, but saves space in the long run if you know that you will need to reallocate the data buffer later.

Definition at line 268 of file IOBuf.cpp.

References capacity(), and CREATE.

Referenced by create().

268  {
269  return std::make_unique<IOBuf>(CREATE, capacity);
270 }
std::size_t capacity() const
Definition: IOBuf.h:593
void folly::IOBuf::decrementRefcount ( )
private

Definition at line 773 of file IOBuf.cpp.

References flags(), freeExtBuffer(), deadlock::info(), kFlagFreeSharedInfo, folly::IOBuf::SharedInfo::refcount, sharedInfo(), and uint32_t.

Referenced by coalesceAndReallocate(), operator=(), unshareOneSlow(), and ~IOBuf().

773  {
774  // Externally owned buffers don't have a SharedInfo object and aren't managed
775  // by the reference count
776  SharedInfo* info = sharedInfo();
777  if (!info) {
778  return;
779  }
780 
781  // Decrement the refcount
782  uint32_t newcnt = info->refcount.fetch_sub(1, std::memory_order_acq_rel);
783  // Note that fetch_sub() returns the value before we decremented.
784  // If it is 1, we were the only remaining user; if it is greater there are
785  // still other users.
786  if (newcnt > 1) {
787  return;
788  }
789 
790  // We were the last user. Free the buffer
791  freeExtBuffer();
792 
793  // Free the SharedInfo if it was allocated separately.
794  //
795  // This is only used by takeOwnership().
796  //
797  // To avoid this special case handling in decrementRefcount(), we could have
798  // takeOwnership() set a custom freeFn() that calls the user's free function
799  // then frees the SharedInfo object. (This would require that
800  // takeOwnership() store the user's free function with its allocated
801  // SharedInfo object.) However, handling this specially with a flag seems
802  // like it shouldn't be problematic.
803  if (flags() & kFlagFreeSharedInfo) {
804  delete sharedInfo();
805  }
806 }
def info()
Definition: deadlock.py:447
uintptr_t flags() const
Definition: IOBuf.h:1459
void freeExtBuffer()
Definition: IOBuf.cpp:909
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
static void folly::IOBuf::destroy ( std::unique_ptr< IOBuf > &&  data)
inlinestatic

Convenience function to free a chain of IOBufs held by a unique_ptr.

Definition at line 467 of file IOBuf.h.

References data, folly::empty(), and folly::gen::move.

467  {
468  auto destroyer = std::move(data);
469  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool folly::IOBuf::empty ( ) const

Check whether the chain is empty (i.e., whether the IOBufs in the chain have a total data length of zero).

This method is semantically equivalent to i->computeChainDataLength()==0 but may run faster because it can short-circuit as soon as it encounters a buffer with length()!=0

Definition at line 482 of file IOBuf.cpp.

References current, length(), and next_.

Referenced by folly::TypedIOBuf< T >::empty(), proxygen::HTTP2Codec::parseAllData(), proxygen::HTTP2Codec::parseDataFrameData(), and folly::io::Codec::uncompress().

482  {
483  const IOBuf* current = this;
484  do {
485  if (current->length() != 0) {
486  return false;
487  }
488  current = current->next_;
489  } while (current != this);
490  return true;
491 }
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
IOBuf::Iterator folly::IOBuf::end ( ) const
inline

Definition at line 1687 of file IOBuf.h.

References folly::padded::cend(), and FOLLY_POP_WARNING.

Referenced by coalesceSlow().

1687  {
1688  return cend();
1689 }
Iterator cend() const
Definition: IOBuf.cpp:1005
size_t folly::IOBuf::fillIov ( struct iovec *  iov,
size_t  len 
) const

Fill an iovec array with the IOBuf data.

Returns the number of iovec filled. If there are more buffer than iovec, returns 0. This version is suitable to use with stack iovec arrays.

Naturally, the filled iovec data will be invalid if you modify the buffer chain.

Definition at line 1072 of file IOBuf.cpp.

References data(), i, length(), next(), and uint8_t.

Referenced by folly::AsyncUDPSocket::writeGSO(), and ConnectedWriteUDPClient::writePing().

1072  {
1073  IOBuf const* p = this;
1074  size_t i = 0;
1075  while (i < len) {
1076  // some code can get confused by empty iovs, so skip them
1077  if (p->length() > 0) {
1078  iov[i].iov_base = const_cast<uint8_t*>(p->data());
1079  iov[i].iov_len = p->length();
1080  i++;
1081  }
1082  p = p->next();
1083  if (p == this) {
1084  return i;
1085  }
1086  }
1087  return 0;
1088 }
IOBuf() noexcept
Definition: IOBuf.cpp:361
uintptr_t folly::IOBuf::flags ( ) const
inlineprivate

Definition at line 1459 of file IOBuf.h.

Referenced by decrementRefcount(), moveToFbString(), and reserveSlow().

1459  {
1460  return flagsAndSharedInfo_ & kFlagMask;
1461  }
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
void folly::IOBuf::freeExtBuffer ( )
private

Definition at line 909 of file IOBuf.cpp.

References buf_, bm::free(), folly::IOBuf::SharedInfo::freeFn, deadlock::info(), sharedInfo(), and folly::IOBuf::SharedInfo::userData.

Referenced by decrementRefcount(), and reserveSlow().

909  {
910  SharedInfo* info = sharedInfo();
911  DCHECK(info);
912 
913  if (info->freeFn) {
914  try {
915  info->freeFn(buf_, info->userData);
916  } catch (...) {
917  // The user's free function should never throw. Otherwise we might
918  // throw from the IOBuf destructor. Other code paths like coalesce()
919  // also assume that decrementRefcount() cannot throw.
920  abort();
921  }
922  } else {
923  free(buf_);
924  }
925 }
def info()
Definition: deadlock.py:447
uint8_t * buf_
Definition: IOBuf.h:1433
void free()
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
void folly::IOBuf::freeInternalBuf ( void *  buf,
void *  userData 
)
staticprivate

Definition at line 190 of file IOBuf.cpp.

References releaseStorage(), and folly::IOBuf::SharedInfo::userData.

Referenced by createCombined().

190  {
191  auto* storage = static_cast<HeapStorage*>(userData);
192  releaseStorage(storage, kDataInUse);
193 }
static void releaseStorage(HeapStorage *storage, uint16_t freeFlags)
Definition: IOBuf.cpp:157
static void folly::IOBuf::freeUniquePtrBuffer ( void *  ptr,
void *  userData 
)
inlinestaticprivate

Definition at line 1502 of file IOBuf.h.

1502  {
1503  static_cast<DeleterBase*>(userData)->dispose(ptr);
1504  }
void * ptr
void folly::IOBuf::gather ( std::size_t  maxLength)
inline

Ensure that this chain has at least maxLength bytes available as a contiguous memory range.

This method coalesces whole buffers in the chain into this buffer as necessary until this buffer's length() is at least maxLength.

After coalescing, the IOBuf will have at least as much headroom as the first IOBuf in the chain, and at least as much tailroom as the last IOBuf that was coalesced.

Throws std::bad_alloc or std::overflow_error on error. On error the IOBuf chain will be unmodified. Throws std::overflow_error if maxLength is longer than the total chain length.

Upon return, either enough of the chain was coalesced into a contiguous region, or the entire chain was coalesced. That is, length() >= maxLength || !isChained() is true.

Definition at line 1136 of file IOBuf.h.

References length_.

1136  {
1137  if (!isChained() || length_ >= maxLength) {
1138  return;
1139  }
1140  coalesceSlow(maxLength);
1141  }
bool isChained() const
Definition: IOBuf.h:760
std::size_t length_
Definition: IOBuf.h:1434
void coalesceSlow()
Definition: IOBuf.cpp:677
folly::fbvector< struct iovec > folly::IOBuf::getIov ( ) const

Return an iovector suitable for e.g. writev()

auto iov = buf->getIov(); auto xfer = writev(fd, iov.data(), iov.size());

Naturally, the returned iovector is invalid if you modify the buffer chain.

Definition at line 1009 of file IOBuf.cpp.

References appendToIov(), countChainElements(), and folly::fbvector< T, Allocator >::reserve().

1009  {
1011  iov.reserve(countChainElements());
1012  appendToIov(&iov);
1013  return iov;
1014 }
void reserve(size_type n)
Definition: FBVector.h:1003
size_t countChainElements() const
Definition: IOBuf.cpp:493
void appendToIov(folly::fbvector< struct iovec > *iov) const
Definition: IOBuf.cpp:1016
size_t folly::IOBuf::goodExtBufferSize ( std::size_t  minCapacity)
staticprivate

Definition at line 938 of file IOBuf.cpp.

References folly::goodMallocSize().

Referenced by allocExtBuffer(), and reserveSlow().

938  {
939  // Determine how much space we should allocate. We'll store the SharedInfo
940  // for the external buffer just after the buffer itself. (We store it just
941  // after the buffer rather than just before so that the code can still just
942  // use free(buf_) to free the buffer.)
943  size_t minSize = static_cast<size_t>(minCapacity) + sizeof(SharedInfo);
944  // Add room for padding so that the SharedInfo will be aligned on an 8-byte
945  // boundary.
946  minSize = (minSize + 7) & ~7;
947 
948  // Use goodMallocSize() to bump up the capacity to a decent size to request
949  // from malloc, so we can use all of the space that malloc will probably give
950  // us anyway.
951  return goodMallocSize(minSize);
952 }
size_t goodMallocSize(size_t minSize) noexcept
Definition: Malloc.h:201
std::size_t folly::IOBuf::headroom ( ) const
inline

Get the amount of head room.

Returns the number of bytes in the buffer before the start of the data.

Definition at line 542 of file IOBuf.h.

References buffer(), and data_.

Referenced by cloneCoalescedAsValue(), proxygen::SPDYCodec::generateDataFrame(), folly::TypedIOBuf< T >::headroom(), moveToFbString(), prepend(), reserveSlow(), TEST(), TEST_F(), and unshareOneSlow().

542  {
543  return std::size_t(data_ - buffer());
544  }
uint8_t * data_
Definition: IOBuf.h:1432
const uint8_t * buffer() const
Definition: IOBuf.h:562
void folly::IOBuf::initExtBuffer ( uint8_t buf,
size_t  mallocSize,
SharedInfo **  infoReturn,
std::size_t *  capacityReturn 
)
staticprivate

Definition at line 954 of file IOBuf.cpp.

References sharedInfo(), and uint8_t.

Referenced by allocExtBuffer(), and reserveSlow().

958  {
959  // Find the SharedInfo storage at the end of the buffer
960  // and construct the SharedInfo.
961  uint8_t* infoStart = (buf + mallocSize) - sizeof(SharedInfo);
962  SharedInfo* sharedInfo = new (infoStart) SharedInfo;
963 
964  *capacityReturn = std::size_t(infoStart - buf);
965  *infoReturn = sharedInfo;
966 }
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
bool folly::IOBuf::isChained ( ) const
inline

Return true if this IOBuf is part of a chain of multiple IOBufs, or false if this is the only IOBuf in its chain.

Definition at line 760 of file IOBuf.h.

Referenced by MoveToFbStringTest::check(), cloneCoalescedAsValueWithHeadroomTailroom(), coalesceAndReallocate(), coalesceSlow(), folly::io::StreamCodec::doUncompress(), ZlibServerFilterTest::exercise_compression(), makeManagedChained(), moveToFbString(), TEST(), fizz::test::TEST_F(), TEST_F(), and unshareChained().

760  {
761  assert((next_ == this) == (prev_ == this));
762  return next_ != this;
763  }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
bool folly::IOBuf::isManaged ( ) const
inline

Return true if all IOBufs in this chain are managed by the usual refcounting mechanism (and so the lifetime of the underlying memory can be extended by clone()).

Definition at line 920 of file IOBuf.h.

References current, isManagedOne(), and next_.

920  {
921  const IOBuf* current = this;
922  while (true) {
923  if (!current->isManagedOne()) {
924  return false;
925  }
926  current = current->next_;
927  if (current == this) {
928  return true;
929  }
930  }
931  }
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
bool folly::IOBuf::isManagedOne ( ) const
inline

Return true if this IOBuf is managed by the usual refcounting mechanism (and so the lifetime of the underlying memory can be extended by cloneOne()).

Definition at line 938 of file IOBuf.h.

Referenced by isManaged().

938  {
939  return sharedInfo();
940  }
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
bool folly::IOBuf::isShared ( ) const
inline

Return true if at least one of the IOBufs in this chain are shared, or false if all of the IOBufs point to unique buffers.

Use isSharedOne() to only check this IOBuf rather than the entire chain.

Definition at line 902 of file IOBuf.h.

References current, isSharedOne(), and next_.

Referenced by moveToFbString(), and TEST().

902  {
903  const IOBuf* current = this;
904  while (true) {
905  if (current->isSharedOne()) {
906  return true;
907  }
908  current = current->next_;
909  if (current == this) {
910  return false;
911  }
912  }
913  }
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
bool folly::IOBuf::isSharedOne ( ) const
inline

Return true if other IOBufs are also pointing to the buffer used by this IOBuf, and false otherwise.

If this IOBuf points at a buffer owned by another (non-IOBuf) part of the code (i.e., if the IOBuf was created using wrapBuffer(), or was cloned from such an IOBuf), it is always considered shared.

This only checks the current IOBuf, and not other IOBufs in the chain.

Definition at line 952 of file IOBuf.h.

References LIKELY, and UNLIKELY.

Referenced by proxygen::SPDYCodec::generateDataFrame(), isShared(), reserveSlow(), TEST(), unshareChained(), and folly::IOBufQueue::updateWritableTailCache().

952  {
953  // If this is a user-owned buffer, it is always considered shared
954  if (UNLIKELY(!sharedInfo())) {
955  return true;
956  }
957 
958  if (UNLIKELY(sharedInfo()->externallyShared)) {
959  return true;
960  }
961 
962  if (LIKELY(!(flags() & kFlagMaybeShared))) {
963  return false;
964  }
965 
966  // kFlagMaybeShared is set, so we need to check the reference count.
967  // (Checking the reference count requires an atomic operation, which is why
968  // we prefer to only check kFlagMaybeShared if possible.)
969  bool shared = sharedInfo()->refcount.load(std::memory_order_acquire) > 1;
970  if (!shared) {
971  // we're the last one left
973  }
974  return shared;
975  }
uintptr_t flags() const
Definition: IOBuf.h:1459
#define LIKELY(x)
Definition: Likely.h:47
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
std::atomic< uint32_t > refcount
Definition: IOBuf.h:1355
#define UNLIKELY(x)
Definition: Likely.h:48
void clearFlags(uintptr_t flags) const
Definition: IOBuf.h:1469
std::size_t folly::IOBuf::length ( ) const
inline

Get the data length.

Definition at line 533 of file IOBuf.h.

References length_.

Referenced by TestAsyncTransport::addReadEvent(), appendToIov(), folly::io::detail::CursorBase< Cursor, const IOBuf >::canAdvance(), MoveToFbStringTest::check(), checkBuf(), checkChain(), folly::io::detail::CursorBase< Cursor, const IOBuf >::cloneAtMost(), folly::gen::detail::consumeBufferPlus(), folly::io::StreamCodec::doCompress(), folly::io::StreamCodec::doUncompress(), proxygen::dumpBinToFile(), proxygen::hpack::dumpToFile(), empty(), proxygen::GzipHeaderCodec::encode(), fillBuf(), fillIov(), proxygen::SPDYCodec::generateDataFrame(), fizz::EncryptedWriteRecordLayer::getBufToEncrypt(), fizz::EncryptedReadRecordLayer::getDecryptedBuf(), IOBuf(), folly::io::detail::CursorBase< Cursor, const IOBuf >::isAtEnd(), folly::TypedIOBuf< T >::length(), moveToFbString(), proxygen::HTTPCodecPrinter::onBody(), CurlService::CurlClient::onBody(), proxygen::HTTP1xCodec::onBody(), wangle::SSLSessionCacheManager::onGetSuccess(), proxygen::HTTPCodecPrinter::onGoaway(), proxygen::HTTP1xCodec::onIngress(), proxygen::HTTP2Codec::parseGoaway(), proxygen::Hex16Printer::print(), proxygen::HexFollyPrinter::print(), proxygen::ChainInfoPrinter::print(), proxygen::BinPrinter::print(), proxygen::HTTPSession::processReadData(), wangle::StringCodec::read(), HTTPUpstreamTest< SPDY3CodecPair >::readAndLoop(), proxygen::RFC1867Codec::readToBoundary(), takeOwnership(), TEST(), TEST_F(), fizz::transformBuffer(), fizz::trimBytes(), TestAsyncTransport::writeChain(), folly::AsyncUDPSocket::writeGSO(), and ConnectedWriteUDPClient::writePing().

533  {
534  return length_;
535  }
std::size_t length_
Definition: IOBuf.h:1434
void folly::IOBuf::makeManaged ( )
inline

Ensure that the memory that IOBufs in this chain refer to will continue to be allocated for as long as the IOBufs of the chain (or any clone()s created from this point onwards) is alive.

This only has an effect for user-owned buffers (created with the WRAP_BUFFER constructor or wrapBuffer factory function), in which case those buffers are unshared.

Definition at line 1054 of file IOBuf.h.

1054  {
1055  if (isChained()) {
1057  } else {
1058  makeManagedOne();
1059  }
1060  }
bool isChained() const
Definition: IOBuf.h:760
void makeManagedChained()
Definition: IOBuf.cpp:664
void makeManagedOne()
Definition: IOBuf.h:1071
void folly::IOBuf::makeManagedChained ( )
private

Definition at line 664 of file IOBuf.cpp.

References current, isChained(), makeManagedOne(), and next_.

664  {
665  assert(isChained());
666 
667  IOBuf* current = this;
668  while (true) {
669  current->makeManagedOne();
670  current = current->next_;
671  if (current == this) {
672  break;
673  }
674  }
675 }
bool isChained() const
Definition: IOBuf.h:760
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::makeManagedOne ( )
inline

Ensure that the memory that this IOBuf refers to will continue to be allocated for as long as this IOBuf (or any clone()s created from this point onwards) is alive.

This only has an effect for user-owned buffers (created with the WRAP_BUFFER constructor or wrapBuffer factory function), in which case those buffers are unshared.

Definition at line 1071 of file IOBuf.h.

Referenced by makeManagedChained().

1071  {
1072  if (!isManagedOne()) {
1073  // We can call the internal function directly; unmanaged implies shared.
1074  unshareOneSlow();
1075  }
1076  }
void unshareOneSlow()
Definition: IOBuf.cpp:606
bool isManagedOne() const
Definition: IOBuf.h:938
void folly::IOBuf::markExternallyShared ( )

Mark the underlying buffers in this chain as shared with external memory management mechanism. This will make isShared() always returns true.

This function is not thread-safe, and only safe to call immediately after creating an IOBuf, before it has been shared with other threads.

Definition at line 656 of file IOBuf.cpp.

References current, markExternallySharedOne(), and next_.

656  {
657  IOBuf* current = this;
658  do {
659  current->markExternallySharedOne();
660  current = current->next_;
661  } while (current != this);
662 }
int current
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::markExternallySharedOne ( )
inline

Mark the underlying buffer that this IOBuf refers to as shared with external memory management mechanism. This will make isSharedOne() always returns true.

This function is not thread-safe, and only safe to call immediately after creating an IOBuf, before it has been shared with other threads.

Definition at line 1038 of file IOBuf.h.

References folly::IOBuf::SharedInfo::externallyShared, and deadlock::info().

Referenced by markExternallyShared().

1038  {
1039  SharedInfo* info = sharedInfo();
1040  if (info) {
1041  info->externallyShared = true;
1042  }
1043  }
def info()
Definition: deadlock.py:447
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
std::unique_ptr< IOBuf > folly::IOBuf::maybeCopyBuffer ( const std::string buf,
std::size_t  headroom = 0,
std::size_t  minTailroom = 0 
)
inlinestatic

A version of copyBuffer() that returns a null pointer if the input string is empty.

Definition at line 1609 of file IOBuf.h.

References fizz::test::copyBuffer().

Referenced by proxygen::ResponseBuilder::body().

1612  {
1613  if (buf.empty()) {
1614  return nullptr;
1615  }
1616  return copyBuffer(buf.data(), buf.size(), headroom, minTailroom);
1617 }
std::size_t headroom() const
Definition: IOBuf.h:542
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
fbstring folly::IOBuf::moveToFbString ( )

Destructively convert this IOBuf to a fbstring efficiently. We rely on fbstring's AcquireMallocatedString constructor to transfer memory.

Definition at line 968 of file IOBuf.cpp.

References buf_, capacity(), clear(), coalesceAndReallocate(), computeChainDataLength(), flags(), flagsAndSharedInfo_, headroom(), isChained(), isShared(), kFlagFreeSharedInfo, length(), sharedInfo(), tailroom(), writableData(), and writableTail().

Referenced by MoveToFbStringTest::check(), HTTP2FramerTest::dataFrameTest(), TEST(), TEST_F(), TEST_P(), and fizz::test::TEST_P().

968  {
969  // malloc-allocated buffers are just fine, everything else needs
970  // to be turned into one.
971  if (!sharedInfo() || // user owned, not ours to give up
972  sharedInfo()->freeFn || // not malloc()-ed
973  headroom() != 0 || // malloc()-ed block doesn't start at beginning
974  tailroom() == 0 || // no room for NUL terminator
975  isShared() || // shared
976  isChained()) { // chained
977  // We might as well get rid of all head and tailroom if we're going
978  // to reallocate; we need 1 byte for NUL terminator.
980  }
981 
982  // Ensure NUL terminated
983  *writableTail() = 0;
984  fbstring str(
985  reinterpret_cast<char*>(writableData()),
986  length(),
987  capacity(),
989 
990  if (flags() & kFlagFreeSharedInfo) {
991  delete sharedInfo();
992  }
993 
994  // Reset to a state where we can be deleted cleanly
996  buf_ = nullptr;
997  clear();
998  return str;
999 }
uintptr_t flags() const
Definition: IOBuf.h:1459
bool isChained() const
Definition: IOBuf.h:760
std::size_t capacity() const
Definition: IOBuf.h:593
std::size_t tailroom() const
Definition: IOBuf.h:551
uint8_t * writableTail()
Definition: IOBuf.h:526
AcquireMallocatedString
Definition: FBString.h:221
void coalesceAndReallocate(size_t newHeadroom, size_t newLength, IOBuf *end, size_t newTailroom)
Definition: IOBuf.cpp:722
uint8_t * buf_
Definition: IOBuf.h:1433
uint8_t * writableData()
Definition: IOBuf.h:509
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length() const
Definition: IOBuf.h:533
bool isShared() const
Definition: IOBuf.h:902
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
void clear()
Definition: IOBuf.h:728
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
basic_fbstring< char > fbstring
Definition: FBString.h:2904
const IOBuf* folly::IOBuf::next ( ) const
inline

Definition at line 603 of file IOBuf.h.

603  {
604  return next_;
605  }
IOBuf * next_
Definition: IOBuf.h:1423
void folly::IOBuf::operator delete ( void *  ptr)

Definition at line 145 of file IOBuf.cpp.

References ptr, releaseStorage(), and uint8_t.

145  {
146  auto* storageAddr = static_cast<uint8_t*>(ptr) - offsetof(HeapStorage, buf);
147  auto* storage = reinterpret_cast<HeapStorage*>(storageAddr);
148  releaseStorage(storage, kIOBufInUse);
149 }
void * ptr
static void releaseStorage(HeapStorage *storage, uint16_t freeFlags)
Definition: IOBuf.cpp:157
void folly::IOBuf::operator delete ( void *  ptr,
void *  placement 
)

Definition at line 151 of file IOBuf.cpp.

151  {
152  // Provide matching operator for `IOBuf::new` to avoid MSVC compilation
153  // warning (C4291) about memory leak when exception is thrown in the
154  // constructor.
155 }
void * folly::IOBuf::operator new ( size_t  size)

Definition at line 133 of file IOBuf.cpp.

References folly::checkedMalloc(), and folly::size().

133  {
134  size_t fullSize = offsetof(HeapStorage, buf) + size;
135  auto* storage = static_cast<HeapStorage*>(checkedMalloc(fullSize));
136 
137  new (&storage->prefix) HeapPrefix(kIOBufInUse);
138  return &(storage->buf);
139 }
void * checkedMalloc(size_t size)
Definition: Malloc.h:227
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
void * folly::IOBuf::operator new ( size_t  size,
void *  ptr 
)

Definition at line 141 of file IOBuf.cpp.

References ptr.

141  {
142  return ptr;
143 }
void * ptr
IOBuf & folly::IOBuf::operator= ( IOBuf &&  other)
noexcept

Definition at line 428 of file IOBuf.cpp.

References buf_, capacity_, data_, decrementRefcount(), flagsAndSharedInfo_, length_, next_, prev_, and unlink().

428  {
429  if (this == &other) {
430  return *this;
431  }
432 
433  // If we are part of a chain, delete the rest of the chain.
434  while (next_ != this) {
435  // Since unlink() returns unique_ptr() and we don't store it,
436  // it will automatically delete the unlinked element.
437  (void)next_->unlink();
438  }
439 
440  // Decrement our refcount on the current buffer
442 
443  // Take ownership of the other buffer's data
444  data_ = other.data_;
445  buf_ = other.buf_;
446  length_ = other.length_;
447  capacity_ = other.capacity_;
448  flagsAndSharedInfo_ = other.flagsAndSharedInfo_;
449  // Reset other so it is a clean state to be destroyed.
450  other.data_ = nullptr;
451  other.buf_ = nullptr;
452  other.length_ = 0;
453  other.capacity_ = 0;
454  other.flagsAndSharedInfo_ = 0;
455 
456  // If other was part of the chain, assume ownership of the rest of its chain.
457  // (It's only valid to perform move assignment on the head of a chain.)
458  if (other.next_ != &other) {
459  next_ = other.next_;
460  next_->prev_ = this;
461  other.next_ = &other;
462 
463  prev_ = other.prev_;
464  prev_->next_ = this;
465  other.prev_ = &other;
466  }
467 
468  // Sanity check to make sure that other is in a valid state to be destroyed.
469  DCHECK_EQ(other.prev_, &other);
470  DCHECK_EQ(other.next_, &other);
471 
472  return *this;
473 }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t length_
Definition: IOBuf.h:1434
std::unique_ptr< IOBuf > unlink()
Definition: IOBuf.h:847
std::size_t capacity_
Definition: IOBuf.h:1435
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
void decrementRefcount()
Definition: IOBuf.cpp:773
IOBuf & folly::IOBuf::operator= ( const IOBuf other)

Definition at line 475 of file IOBuf.cpp.

References IOBuf().

475  {
476  if (this != &other) {
477  *this = IOBuf(other);
478  }
479  return *this;
480 }
IOBuf() noexcept
Definition: IOBuf.cpp:361
static uintptr_t folly::IOBuf::packFlagsAndSharedInfo ( uintptr_t  flags,
SharedInfo info 
)
inlinestaticprivate

Definition at line 1440 of file IOBuf.h.

References deadlock::info().

Referenced by createCombined().

1442  {
1443  uintptr_t uinfo = reinterpret_cast<uintptr_t>(info);
1444  DCHECK_EQ(flags & ~kFlagMask, 0u);
1445  DCHECK_EQ(uinfo & kFlagMask, 0u);
1446  return flags | uinfo;
1447  }
def info()
Definition: deadlock.py:447
flags
Definition: http_parser.h:127
std::unique_ptr<IOBuf> folly::IOBuf::pop ( )
inline

Remove this IOBuf from its current chain and return a unique_ptr to the IOBuf that formerly followed it in the chain.

Definition at line 859 of file IOBuf.h.

References cpp.ast::next().

Referenced by proxygen::SPDYCodec::generateDataFrame(), poolPutIOBuf(), and folly::IOBufQueue::pop_front().

859  {
860  IOBuf* next = next_;
861  next_->prev_ = prev_;
862  prev_->next_ = next_;
863  prev_ = this;
864  next_ = this;
865  return std::unique_ptr<IOBuf>((next == this) ? nullptr : next);
866  }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
IOBuf * next()
Definition: IOBuf.h:600
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::prepend ( std::size_t  amount)
inline

Adjust the data pointer to include more valid data at the beginning.

This moves the data pointer backwards to include more of the available buffer. The caller is responsible for ensuring that there is sufficient headroom for the new data. The caller is also responsible for populating this section with valid data.

This does not modify any actual data in the buffer.

Definition at line 673 of file IOBuf.h.

References data_, and length_.

Referenced by proxygen::SPDYCodec::generateSynReply(), proxygen::SPDYCodec::generateSynStream(), prepend(), and folly::TypedIOBuf< T >::prepend().

673  {
674  DCHECK_LE(amount, headroom());
675  data_ -= amount;
676  length_ += amount;
677  }
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length_
Definition: IOBuf.h:1434
void folly::IOBuf::prependChain ( std::unique_ptr< IOBuf > &&  iobuf)

Insert another IOBuf chain immediately before this IOBuf.

For example, if there are two IOBuf chains (A, B, C) and (D, E, F), and B->prependChain(D) is called, the (D, E, F) chain will be subsumed and become part of the chain starting at A, which will now look like (A, D, E, F, B, C)

Note that since IOBuf chains are circular, head->prependChain(other) can be used to append the other chain at the very end of the chain pointed to by head. For example, if there are two IOBuf chains (A, B, C) and (D, E, F), and A->prependChain(D) is called, the chain starting at A will now consist of (A, B, C, D, E, F)

The elements in the specified IOBuf chain will become part of this chain, and will be owned by the head of this chain. When this chain is destroyed, all elements in the supplied chain will also be destroyed.

For this reason, appendChain() only accepts an rvalue-reference to a unique_ptr(), to make it clear that it is taking ownership of the supplied chain. If you have a raw pointer, you can pass in a new temporary unique_ptr around the raw pointer. If you have an existing, non-temporary unique_ptr, you must call std::move(ptr) to make it clear that you are destroying the original pointer.

Definition at line 509 of file IOBuf.cpp.

References next_, and prev_.

Referenced by BENCHMARK(), fizz::test::chunkIOBuf(), folly::io::detail::CursorBase< Cursor, const IOBuf >::cloneAtMost(), fizz::test::copyBuffer(), ZlibServerFilterTest::createResponseChain(), fizz::detail::evpEncrypt(), ZlibServerFilterTest::exercise_compression(), TestData::getInBuf(), folly::io::RWCursor< access >::insert(), main(), proxygen::RFC1867Base::parse(), TEST(), TEST_F(), and fizz::EncryptedWriteRecordLayer::write().

509  {
510  // Take ownership of the specified IOBuf
511  IOBuf* other = iobuf.release();
512 
513  // Remember the pointer to the tail of the other chain
514  IOBuf* otherTail = other->prev_;
515 
516  // Hook up prev_->next_ to point at the start of the other chain,
517  // and other->prev_ to point at prev_
518  prev_->next_ = other;
519  other->prev_ = prev_;
520 
521  // Hook up otherTail->next_ to point at us,
522  // and prev_ to point back at otherTail,
523  otherTail->next_ = this;
524  prev_ = otherTail;
525 }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
IOBuf() noexcept
Definition: IOBuf.cpp:361
const IOBuf* folly::IOBuf::prev ( ) const
inline

Definition at line 613 of file IOBuf.h.

613  {
614  return prev_;
615  }
IOBuf * prev_
Definition: IOBuf.h:1424
void folly::IOBuf::releaseStorage ( HeapStorage storage,
uint16_t  freeFlags 
)
staticprivate

Definition at line 157 of file IOBuf.cpp.

References folly::IOBuf::HeapPrefix::flags, bm::free(), folly::IOBuf::HeapPrefix::magic, folly::IOBuf::HeapStorage::prefix, and uint16_t.

Referenced by freeInternalBuf(), and operator delete().

157  {
158  CHECK_EQ(storage->prefix.magic, static_cast<uint16_t>(kHeapMagic));
159 
160  // Use relaxed memory order here. If we are unlucky and happen to get
161  // out-of-date data the compare_exchange_weak() call below will catch
162  // it and load new data with memory_order_acq_rel.
163  auto flags = storage->prefix.flags.load(std::memory_order_acquire);
164  DCHECK_EQ((flags & freeFlags), freeFlags);
165 
166  while (true) {
167  uint16_t newFlags = uint16_t(flags & ~freeFlags);
168  if (newFlags == 0) {
169  // The storage space is now unused. Free it.
170  storage->prefix.HeapPrefix::~HeapPrefix();
171  free(storage);
172  return;
173  }
174 
175  // This storage segment still contains portions that are in use.
176  // Just clear the flags specified in freeFlags for now.
177  auto ret = storage->prefix.flags.compare_exchange_weak(
178  flags, newFlags, std::memory_order_acq_rel);
179  if (ret) {
180  // We successfully updated the flags.
181  return;
182  }
183 
184  // We failed to update the flags. Some other thread probably updated them
185  // and cleared some of the other bits. Continue around the loop to see if
186  // we are the last user now, or if we need to try updating the flags again.
187  }
188 }
flags
Definition: http_parser.h:127
void free()
void folly::IOBuf::reserve ( std::size_t  minHeadroom,
std::size_t  minTailroom 
)
inline

Ensure that this buffer has at least minHeadroom headroom bytes and at least minTailroom tailroom bytes. The buffer must be writable (you must call unshare() before this, if necessary).

Postcondition: headroom() >= minHeadroom, tailroom() >= minTailroom, the data (between data() and data() + length()) is preserved.

Definition at line 741 of file IOBuf.h.

References data_.

Referenced by BENCHMARK(), folly::gen::detail::consumeBufferPlus(), folly::TypedIOBuf< T >::reserve(), and TEST().

741  {
742  // Maybe we don't need to do anything.
743  if (headroom() >= minHeadroom && tailroom() >= minTailroom) {
744  return;
745  }
746  // If the buffer is empty but we have enough total room (head + tail),
747  // move the data_ pointer around.
748  if (length() == 0 && headroom() + tailroom() >= minHeadroom + minTailroom) {
749  data_ = writableBuffer() + minHeadroom;
750  return;
751  }
752  // Bah, we have to do actual work.
753  reserveSlow(minHeadroom, minTailroom);
754  }
void reserveSlow(std::size_t minHeadroom, std::size_t minTailroom)
Definition: IOBuf.cpp:808
std::size_t tailroom() const
Definition: IOBuf.h:551
uint8_t * writableBuffer()
Definition: IOBuf.h:572
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length() const
Definition: IOBuf.h:533
void folly::IOBuf::reserveSlow ( std::size_t  minHeadroom,
std::size_t  minTailroom 
)
private

Definition at line 808 of file IOBuf.cpp.

References buf_, capacity(), capacity_, folly::checkedMalloc(), data_, flags(), freeExtBuffer(), folly::IOBuf::SharedInfo::freeFn, goodExtBufferSize(), headroom(), deadlock::info(), initExtBuffer(), isSharedOne(), folly::jemallocMinInPlaceExpandable, kFlagFreeSharedInfo, length_, setFlagsAndSharedInfo(), sharedInfo(), tailroom(), uint8_t, UNLIKELY, folly::usingJEMalloc(), writableBuffer(), and xallocx.

808  {
809  size_t newCapacity = (size_t)length_ + minHeadroom + minTailroom;
810  DCHECK_LT(newCapacity, UINT32_MAX);
811 
812  // reserveSlow() is dangerous if anyone else is sharing the buffer, as we may
813  // reallocate and free the original buffer. It should only ever be called if
814  // we are the only user of the buffer.
815  DCHECK(!isSharedOne());
816 
817  // We'll need to reallocate the buffer.
818  // There are a few options.
819  // - If we have enough total room, move the data around in the buffer
820  // and adjust the data_ pointer.
821  // - If we're using an internal buffer, we'll switch to an external
822  // buffer with enough headroom and tailroom.
823  // - If we have enough headroom (headroom() >= minHeadroom) but not too much
824  // (so we don't waste memory), we can try one of two things, depending on
825  // whether we use jemalloc or not:
826  // - If using jemalloc, we can try to expand in place, avoiding a memcpy()
827  // - If not using jemalloc and we don't have too much to copy,
828  // we'll use realloc() (note that realloc might have to copy
829  // headroom + data + tailroom, see smartRealloc in folly/memory/Malloc.h)
830  // - Otherwise, bite the bullet and reallocate.
831  if (headroom() + tailroom() >= minHeadroom + minTailroom) {
832  uint8_t* newData = writableBuffer() + minHeadroom;
833  memmove(newData, data_, length_);
834  data_ = newData;
835  return;
836  }
837 
838  size_t newAllocatedCapacity = 0;
839  uint8_t* newBuffer = nullptr;
840  std::size_t newHeadroom = 0;
841  std::size_t oldHeadroom = headroom();
842 
843  // If we have a buffer allocated with malloc and we just need more tailroom,
844  // try to use realloc()/xallocx() to grow the buffer in place.
845  SharedInfo* info = sharedInfo();
846  if (info && (info->freeFn == nullptr) && length_ != 0 &&
847  oldHeadroom >= minHeadroom) {
848  size_t headSlack = oldHeadroom - minHeadroom;
849  newAllocatedCapacity = goodExtBufferSize(newCapacity + headSlack);
850  if (usingJEMalloc()) {
851  // We assume that tailroom is more useful and more important than
852  // headroom (not least because realloc / xallocx allow us to grow the
853  // buffer at the tail, but not at the head) So, if we have more headroom
854  // than we need, we consider that "wasted". We arbitrarily define "too
855  // much" headroom to be 25% of the capacity.
856  if (headSlack * 4 <= newCapacity) {
857  size_t allocatedCapacity = capacity() + sizeof(SharedInfo);
858  void* p = buf_;
859  if (allocatedCapacity >= jemallocMinInPlaceExpandable) {
860  if (xallocx(p, newAllocatedCapacity, 0, 0) == newAllocatedCapacity) {
861  newBuffer = static_cast<uint8_t*>(p);
862  newHeadroom = oldHeadroom;
863  }
864  // if xallocx failed, do nothing, fall back to malloc/memcpy/free
865  }
866  }
867  } else { // Not using jemalloc
868  size_t copySlack = capacity() - length_;
869  if (copySlack * 2 <= length_) {
870  void* p = realloc(buf_, newAllocatedCapacity);
871  if (UNLIKELY(p == nullptr)) {
872  throw std::bad_alloc();
873  }
874  newBuffer = static_cast<uint8_t*>(p);
875  newHeadroom = oldHeadroom;
876  }
877  }
878  }
879 
880  // None of the previous reallocation strategies worked (or we're using
881  // an internal buffer). malloc/copy/free.
882  if (newBuffer == nullptr) {
883  newAllocatedCapacity = goodExtBufferSize(newCapacity);
884  newBuffer = static_cast<uint8_t*>(checkedMalloc(newAllocatedCapacity));
885  if (length_ > 0) {
886  assert(data_ != nullptr);
887  memcpy(newBuffer + minHeadroom, data_, length_);
888  }
889  if (sharedInfo()) {
890  freeExtBuffer();
891  }
892  newHeadroom = minHeadroom;
893  }
894 
895  std::size_t cap;
896  initExtBuffer(newBuffer, newAllocatedCapacity, &info, &cap);
897 
898  if (flags() & kFlagFreeSharedInfo) {
899  delete sharedInfo();
900  }
901 
902  setFlagsAndSharedInfo(0, info);
903  capacity_ = cap;
904  buf_ = newBuffer;
905  data_ = newBuffer + newHeadroom;
906  // length_ is unchanged
907 }
def info()
Definition: deadlock.py:447
void * checkedMalloc(size_t size)
Definition: Malloc.h:227
uintptr_t flags() const
Definition: IOBuf.h:1459
bool usingJEMalloc() noexcept
Definition: Malloc.h:147
void freeExtBuffer()
Definition: IOBuf.cpp:909
bool isSharedOne() const
Definition: IOBuf.h:952
std::size_t capacity() const
Definition: IOBuf.h:593
static const size_t jemallocMinInPlaceExpandable
Definition: Malloc.h:221
std::size_t tailroom() const
Definition: IOBuf.h:551
uint8_t * writableBuffer()
Definition: IOBuf.h:572
size_t(* xallocx)(void *, size_t, size_t, int)
Definition: MallocImpl.cpp:37
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length_
Definition: IOBuf.h:1434
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
std::size_t capacity_
Definition: IOBuf.h:1435
static size_t goodExtBufferSize(std::size_t minCapacity)
Definition: IOBuf.cpp:938
void setFlagsAndSharedInfo(uintptr_t flags, SharedInfo *info)
Definition: IOBuf.h:1474
#define UNLIKELY(x)
Definition: Likely.h:48
static void initExtBuffer(uint8_t *buf, size_t mallocSize, SharedInfo **infoReturn, std::size_t *capacityReturn)
Definition: IOBuf.cpp:954
void folly::IOBuf::retreat ( std::size_t  amount)
inline

Shift the data backwards in the buffer.

The caller is responsible for ensuring that there is sufficient headroom in the buffer before calling retreat().

If there is a non-zero data length, retreat() will use memmove() to shift the data backwards in the buffer. In this case, the caller is responsible for making sure the buffer is unshared, so it will not affect other IOBufs that may be sharing the same underlying buffer.

Definition at line 653 of file IOBuf.h.

References data_, and length_.

Referenced by proxygen::SPDYCodec::generateDataFrame(), and folly::TypedIOBuf< T >::retreat().

653  {
654  // In debug builds, assert if there is a problem.
655  assert(amount <= headroom());
656 
657  if (length_ > 0) {
658  memmove(data_ - amount, data_, length_);
659  }
660  data_ -= amount;
661  }
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length_
Definition: IOBuf.h:1434
std::unique_ptr<IOBuf> folly::IOBuf::separateChain ( IOBuf head,
IOBuf tail 
)
inline

Remove a subchain from this chain.

Remove the subchain starting at head and ending at tail from this chain.

Returns a unique_ptr pointing to head. (In other words, ownership of the head of the subchain is transferred to the caller.) If the caller ignores the return value and lets the unique_ptr be destroyed, the subchain will be immediately destroyed.

The subchain referenced by the specified head and tail must be part of the same chain as the current IOBuf, but must not contain the current IOBuf. However, the specified head and tail may be equal to each other (i.e., they may be a subchain of length 1).

Definition at line 883 of file IOBuf.h.

References next_, and prev_.

Referenced by coalesceAndReallocate().

883  {
884  assert(head != this);
885  assert(tail != this);
886 
887  head->prev_->next_ = tail->next_;
888  tail->next_->prev_ = head->prev_;
889 
890  head->prev_ = tail;
891  tail->next_ = head;
892 
893  return std::unique_ptr<IOBuf>(head);
894  }
const uint8_t * tail() const
Definition: IOBuf.h:516
void folly::IOBuf::setFlags ( uintptr_t  flags) const
inlineprivate

Definition at line 1464 of file IOBuf.h.

Referenced by cloneOneAsValue().

1464  {
1465  DCHECK_EQ(flags & ~kFlagMask, 0u);
1467  }
flags
Definition: http_parser.h:127
uintptr_t flags() const
Definition: IOBuf.h:1459
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
void folly::IOBuf::setFlagsAndSharedInfo ( uintptr_t  flags,
SharedInfo info 
)
inlineprivate

Definition at line 1474 of file IOBuf.h.

Referenced by coalesceAndReallocate(), reserveSlow(), and unshareOneSlow().

1474  {
1476  }
def info()
Definition: deadlock.py:447
flags
Definition: http_parser.h:127
static uintptr_t packFlagsAndSharedInfo(uintptr_t flags, SharedInfo *info)
Definition: IOBuf.h:1440
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
void folly::IOBuf::setSharedInfo ( SharedInfo info)
inlineprivate

Definition at line 1453 of file IOBuf.h.

References deadlock::info().

Referenced by IOBuf().

1453  {
1454  uintptr_t uinfo = reinterpret_cast<uintptr_t>(info);
1455  DCHECK_EQ(uinfo & kFlagMask, 0u);
1457  }
def info()
Definition: deadlock.py:447
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
SharedInfo* folly::IOBuf::sharedInfo ( ) const
inlineprivate

Definition at line 1449 of file IOBuf.h.

Referenced by cloneOneAsValue(), decrementRefcount(), freeExtBuffer(), initExtBuffer(), moveToFbString(), reserveSlow(), and unshareOneSlow().

1449  {
1450  return reinterpret_cast<SharedInfo*>(flagsAndSharedInfo_ & ~kFlagMask);
1451  }
uintptr_t flagsAndSharedInfo_
Definition: IOBuf.h:1438
const uint8_t* folly::IOBuf::tail ( ) const
inline

Get the pointer to the end of the data.

Definition at line 516 of file IOBuf.h.

References data_, and length_.

Referenced by folly::io::detail::CursorBase< Cursor, const IOBuf >::operator==(), folly::TypedIOBuf< T >::tail(), and TEST().

516  {
517  return data_ + length_;
518  }
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t length_
Definition: IOBuf.h:1434
std::size_t folly::IOBuf::tailroom ( ) const
inline

Get the amount of tail room.

Returns the number of bytes in the buffer after the end of the data.

Definition at line 551 of file IOBuf.h.

Referenced by append(), folly::IOBufQueue::append(), cloneCoalescedAsValue(), coalesceAndReallocate(), folly::IOBufQueue::dcheckCacheIntegrity(), folly::io::StreamCodec::doUncompress(), fizz::detail::evpEncrypt(), moveToFbString(), proxygen::ChainInfoPrinter::print(), reserveSlow(), folly::TypedIOBuf< T >::tailroom(), TEST(), and folly::IOBufQueue::updateWritableTailCache().

551  {
552  return std::size_t(bufferEnd() - tail());
553  }
const uint8_t * tail() const
Definition: IOBuf.h:516
const uint8_t * bufferEnd() const
Definition: IOBuf.h:583
static std::unique_ptr<IOBuf> folly::IOBuf::takeOwnership ( void *  buf,
std::size_t  capacity,
FreeFunction  freeFn = nullptr,
void *  userData = nullptr,
bool  freeOnError = true 
)
inlinestatic

Create a new IOBuf pointing to an existing data buffer.

The new IOBuffer will assume ownership of the buffer, and free it by calling the specified FreeFunction when the last IOBuf pointing to this buffer is destroyed. The function will be called with a pointer to the buffer as the first argument, and the supplied userData value as the second argument. The free function must never throw exceptions.

If no FreeFunction is specified, the buffer will be freed using free() which will result in undefined behavior if the memory was allocated using 'new'.

The IOBuf data pointer will initially point to the start 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.

Definition at line 304 of file IOBuf.h.

Referenced by folly::AsyncSocket::handleRead(), takeOwnershipIov(), and folly::ZeroCopyTestAsyncSocket::writeBuffer().

309  {
310  return takeOwnership(
311  buf, capacity, capacity, freeFn, userData, freeOnError);
312  }
std::size_t capacity() const
Definition: IOBuf.h:593
static std::unique_ptr< IOBuf > takeOwnership(void *buf, std::size_t capacity, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
Definition: IOBuf.h:304
unique_ptr< IOBuf > folly::IOBuf::takeOwnership ( void *  buf,
std::size_t  capacity,
std::size_t  length,
FreeFunction  freeFn = nullptr,
void *  userData = nullptr,
bool  freeOnError = true 
)
static

Definition at line 313 of file IOBuf.cpp.

References capacity(), length(), and TAKE_OWNERSHIP.

319  {
320  try {
321  // TODO: We could allocate the IOBuf object and SharedInfo all in a single
322  // memory allocation. We could use the existing HeapStorage class, and
323  // define a new kSharedInfoInUse flag. We could change our code to call
324  // releaseStorage(kFlagFreeSharedInfo) when this kFlagFreeSharedInfo,
325  // rather than directly calling delete.
326  //
327  // Note that we always pass freeOnError as false to the constructor.
328  // If the constructor throws we'll handle it below. (We have to handle
329  // allocation failures from std::make_unique too.)
330  return std::make_unique<IOBuf>(
331  TAKE_OWNERSHIP, buf, capacity, length, freeFn, userData, false);
332  } catch (...) {
333  takeOwnershipError(freeOnError, buf, freeFn, userData);
334  throw;
335  }
336 }
std::size_t capacity() const
Definition: IOBuf.h:593
std::size_t length() const
Definition: IOBuf.h:533
template<class UniquePtr >
std::enable_if< detail::IsUniquePtrToSL< UniquePtr >::value, std::unique_ptr< IOBuf > >::type folly::IOBuf::takeOwnership ( UniquePtr &&  buf,
size_t  count = 1 
)
static

Create a new IOBuf pointing to an existing data buffer made up of count objects of a given standard-layout type.

This is dangerous – it is essentially equivalent to doing reinterpret_cast<unsigned char*> on your data – but it's often useful for serialization / deserialization.

The new IOBuffer will assume ownership of the buffer, and free it appropriately (by calling the UniquePtr's custom deleter, or by calling delete or delete[] appropriately if there is no custom deleter) when the buffer is destroyed. The custom deleter, if any, must never throw exceptions.

The IOBuf data pointer will initially point to the start of the buffer, and the length will be the full capacity of the buffer (count * sizeof(T)).

On error, std::bad_alloc will be thrown, and the buffer will be freed before throwing the error.

Definition at line 1580 of file IOBuf.h.

References folly::size().

1580  {
1581  size_t size = count * sizeof(typename UniquePtr::element_type);
1582  auto deleter = new UniquePtrDeleter<UniquePtr>(buf.get_deleter());
1583  return takeOwnership(
1584  buf.release(), size, &IOBuf::freeUniquePtrBuffer, deleter);
1585 }
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
static void freeUniquePtrBuffer(void *ptr, void *userData)
Definition: IOBuf.h:1502
int * count
static std::unique_ptr< IOBuf > takeOwnership(void *buf, std::size_t capacity, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
Definition: IOBuf.h:304
std::unique_ptr< IOBuf > folly::IOBuf::takeOwnershipIov ( const iovec *  vec,
size_t  count,
FreeFunction  freeFn = nullptr,
void *  userData = nullptr,
bool  freeOnError = true 
)
static

A helper that takes ownerships a number of iovecs into an IOBuf chain. If count == 0, then a zero length buf is returned. This function never returns nullptr.

Definition at line 1047 of file IOBuf.cpp.

References count, create(), data(), i, folly::gen::move, takeOwnership(), and UNLIKELY.

1052  {
1053  unique_ptr<IOBuf> result = nullptr;
1054  for (size_t i = 0; i < count; ++i) {
1055  size_t len = vec[i].iov_len;
1056  void* data = vec[i].iov_base;
1057  if (len > 0) {
1058  auto buf = takeOwnership(data, len, freeFn, userData, freeOnError);
1059  if (!result) {
1060  result = std::move(buf);
1061  } else {
1062  result->prependChain(std::move(buf));
1063  }
1064  }
1065  }
1066  if (UNLIKELY(result == nullptr)) {
1067  return create(0);
1068  }
1069  return result;
1070 }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const uint8_t * data() const
Definition: IOBuf.h:499
Definition: Traits.h:588
int * count
static std::unique_ptr< IOBuf > takeOwnership(void *buf, std::size_t capacity, FreeFunction freeFn=nullptr, void *userData=nullptr, bool freeOnError=true)
Definition: IOBuf.h:304
#define UNLIKELY(x)
Definition: Likely.h:48
void folly::IOBuf::trimEnd ( std::size_t  amount)
inline

Adjust the tail pointer backwards to include less valid data.

This moves the tail pointer backwards so that the last amount bytes are no longer considered valid data. The caller is responsible for ensuring that amount is less than or equal to the actual data length.

This does not modify any actual data in the buffer.

Definition at line 718 of file IOBuf.h.

References length_.

Referenced by folly::io::detail::CursorBase< Cursor, const IOBuf >::cloneAtMost(), proxygen::ZlibStreamCompressor::compress(), proxygen::SPDYCodec::generateDataFrame(), TEST(), fizz::trimBytes(), and folly::TypedIOBuf< T >::trimEnd().

718  {
719  DCHECK_LE(amount, length_);
720  length_ -= amount;
721  }
std::size_t length_
Definition: IOBuf.h:1434
void folly::IOBuf::trimStart ( std::size_t  amount)
inline

Adjust the data pointer forwards to include less valid data.

This moves the data pointer forwards so that the first amount bytes are no longer considered valid data. The caller is responsible for ensuring that amount is less than or equal to the actual data length.

This does not modify any actual data in the buffer.

Definition at line 703 of file IOBuf.h.

References data_, and length_.

Referenced by folly::io::detail::CursorBase< Cursor, const IOBuf >::cloneAtMost(), proxygen::compress::HPACKScheme::decode(), proxygen::compress::QMINScheme::decode(), folly::io::RWCursor< access >::insert(), TEST(), folly::io::test::TEST_P(), and folly::TypedIOBuf< T >::trimStart().

703  {
704  DCHECK_LE(amount, length_);
705  data_ += amount;
706  length_ -= amount;
707  }
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t length_
Definition: IOBuf.h:1434
std::unique_ptr<IOBuf> folly::IOBuf::unlink ( )
inline

Remove this IOBuf from its current chain.

Since ownership of all elements an IOBuf chain is normally maintained by the head of the chain, unlink() transfers ownership of this IOBuf from the chain and gives it to the caller. A new unique_ptr to the IOBuf is returned to the caller. The caller must store the returned unique_ptr (or call release() on it) to take ownership, otherwise the IOBuf will be immediately destroyed.

Since unlink transfers ownership of the IOBuf to the caller, be careful not to call unlink() on the head of a chain if you already maintain ownership on the head of the chain via other means. The pop() method is a better choice for that situation.

Definition at line 847 of file IOBuf.h.

Referenced by operator=(), TEST(), and ~IOBuf().

847  {
848  next_->prev_ = prev_;
849  prev_->next_ = next_;
850  prev_ = this;
851  next_ = this;
852  return std::unique_ptr<IOBuf>(this);
853  }
IOBuf * next_
Definition: IOBuf.h:1423
IOBuf * prev_
Definition: IOBuf.h:1424
void folly::IOBuf::unshare ( )
inline

Ensure that this IOBuf has a unique buffer that is not shared by other IOBufs.

unshare() operates on an entire chain of IOBuf objects. If the chain is shared, it may also coalesce the chain when making it unique. If the chain is coalesced, subsequent IOBuf objects in the current chain will be automatically deleted.

Note that buffers owned by other (non-IOBuf) users are automatically considered shared.

Throws std::bad_alloc on error. On error the IOBuf chain will be unmodified.

Currently unshare may also throw std::overflow_error if it tries to coalesce. (TODO: In the future it would be nice if unshare() were smart enough not to coalesce the entire buffer if the data is too large. However, in practice this seems unlikely to become an issue.)

Definition at line 997 of file IOBuf.h.

Referenced by fillBuf(), and TEST().

997  {
998  if (isChained()) {
999  unshareChained();
1000  } else {
1001  unshareOne();
1002  }
1003  }
bool isChained() const
Definition: IOBuf.h:760
void unshareOne()
Definition: IOBuf.h:1015
void unshareChained()
Definition: IOBuf.cpp:632
void folly::IOBuf::unshareChained ( )
private

Definition at line 632 of file IOBuf.cpp.

References coalesceSlow(), current, isChained(), isSharedOne(), and next_.

632  {
633  // unshareChained() should only be called if we are part of a chain of
634  // multiple IOBufs. The caller should have already verified this.
635  assert(isChained());
636 
637  IOBuf* current = this;
638  while (true) {
639  if (current->isSharedOne()) {
640  // we have to unshare
641  break;
642  }
643 
644  current = current->next_;
645  if (current == this) {
646  // None of the IOBufs in the chain are shared,
647  // so return without doing anything
648  return;
649  }
650  }
651 
652  // We have to unshare. Let coalesceSlow() do the work.
653  coalesceSlow();
654 }
bool isChained() const
Definition: IOBuf.h:760
int current
void coalesceSlow()
Definition: IOBuf.cpp:677
IOBuf() noexcept
Definition: IOBuf.cpp:361
void folly::IOBuf::unshareOne ( )
inline

Ensure that this IOBuf has a unique buffer that is not shared by other IOBufs.

unshareOne() operates on a single IOBuf object. This IOBuf will have a unique buffer after unshareOne() returns, but other IOBufs in the chain may still be shared after unshareOne() returns.

Throws std::bad_alloc on error. On error the IOBuf will be unmodified.

Definition at line 1015 of file IOBuf.h.

Referenced by TEST().

1015  {
1016  if (isSharedOne()) {
1017  unshareOneSlow();
1018  }
1019  }
bool isSharedOne() const
Definition: IOBuf.h:952
void unshareOneSlow()
Definition: IOBuf.cpp:606
void folly::IOBuf::unshareOneSlow ( )
private

Definition at line 606 of file IOBuf.cpp.

References allocExtBuffer(), buf_, capacity_, data_, decrementRefcount(), headroom(), length_, setFlagsAndSharedInfo(), sharedInfo(), and uint8_t.

606  {
607  // Allocate a new buffer for the data
608  uint8_t* buf;
609  SharedInfo* sharedInfo;
610  std::size_t actualCapacity;
611  allocExtBuffer(capacity_, &buf, &sharedInfo, &actualCapacity);
612 
613  // Copy the data
614  // Maintain the same amount of headroom. Since we maintained the same
615  // minimum capacity we also maintain at least the same amount of tailroom.
616  std::size_t headlen = headroom();
617  if (length_ > 0) {
618  assert(data_ != nullptr);
619  memcpy(buf + headlen, data_, length_);
620  }
621 
622  // Release our reference on the old buffer
624  // Make sure kFlagMaybeShared and kFlagFreeSharedInfo are all cleared.
625  setFlagsAndSharedInfo(0, sharedInfo);
626 
627  // Update the buffer pointers to point to the new buffer
628  data_ = buf + headlen;
629  buf_ = buf;
630 }
static void allocExtBuffer(std::size_t minCapacity, uint8_t **bufReturn, SharedInfo **infoReturn, std::size_t *capacityReturn)
Definition: IOBuf.cpp:927
uint8_t * data_
Definition: IOBuf.h:1432
uint8_t * buf_
Definition: IOBuf.h:1433
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length_
Definition: IOBuf.h:1434
SharedInfo * sharedInfo() const
Definition: IOBuf.h:1449
std::size_t capacity_
Definition: IOBuf.h:1435
void setFlagsAndSharedInfo(uintptr_t flags, SharedInfo *info)
Definition: IOBuf.h:1474
void decrementRefcount()
Definition: IOBuf.cpp:773
unique_ptr< IOBuf > folly::IOBuf::wrapBuffer ( const void *  buf,
std::size_t  capacity 
)
static

Create a new IOBuf object that points to an existing user-owned buffer.

This should only be used when the caller knows the lifetime of the IOBuf object ahead of time and can ensure that all IOBuf objects that will point to this buffer will be destroyed before the buffer itself is destroyed.

This buffer will not be freed automatically when the last IOBuf referencing it is destroyed. It is the caller's responsibility to free the buffer after the last IOBuf has been destroyed.

The IOBuf data pointer will initially point to the start of the buffer, and the length will be the full capacity of the buffer.

An IOBuf created using wrapBuffer() will always be reported as shared. unshare() may be used to create a writable copy of the buffer.

On error, std::bad_alloc will be thrown.

Definition at line 353 of file IOBuf.cpp.

References capacity(), and WRAP_BUFFER.

Referenced by folly::AsyncSSLSocket::clientHelloParsingCallback(), fizz::server::AeadTokenCipher< AeadType, HkdfType >::createAead(), fizz::sm::getCertificateRequest(), fizz::Exporter::getEkm(), fizz::sm::getHrrKeyExchangers(), fizz::KeyScheduler::getResumptionSecret(), fizz::sm::handleCertMsg(), fizz::sm::handleEarlyAppWrite(), folly::bser::parseBser(), folly::io::test::StreamingCompressionTest::runFlushTest(), folly::io::test::CompressionTest::runSimpleIOBufTest(), folly::io::test::CompressionVarintTest::runSimpleTest(), folly::io::test::CompressionCorruptionTest::runSimpleTest(), folly::io::test::AutomaticCodecTest::runSimpleTest(), folly::io::test::StreamingCompressionTest::runUncompressStreamTest(), fizz::server::test::TEST(), folly::test::TEST(), TEST(), folly::io::test::TEST(), fizz::testing::TEST_P(), folly::io::test::TEST_P(), folly::IOBufQueue::wrapBuffer(), wrapIov(), folly::WriteChainAsyncTransportWrapper< folly::AsyncTransportWrapper >::write(), and folly::AsyncPipeWriter::write().

353  {
354  return std::make_unique<IOBuf>(WRAP_BUFFER, buf, capacity);
355 }
std::size_t capacity() const
Definition: IOBuf.h:593
static std::unique_ptr<IOBuf> folly::IOBuf::wrapBuffer ( ByteRange  br)
inlinestatic

Definition at line 387 of file IOBuf.h.

References folly::Range< Iter >::data(), folly::pushmi::__adl::noexcept(), and folly::Range< Iter >::size().

387  {
388  return wrapBuffer(br.data(), br.size());
389  }
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
Definition: IOBuf.cpp:353
IOBuf folly::IOBuf::wrapBufferAsValue ( const void *  buf,
std::size_t  capacity 
)
staticnoexcept

Similar to wrapBuffer(), but returns IOBuf by value rather than heap-allocating it.

Definition at line 357 of file IOBuf.cpp.

References capacity(), and IOBuf().

Referenced by fizz::HkdfImpl< Hash >::extract(), fizz::EncryptedReadRecordLayer::getDecryptedBuf(), and fizz::EncryptedWriteRecordLayer::write().

357  {
358  return IOBuf(WrapBufferOp::WRAP_BUFFER, buf, capacity);
359 }
std::size_t capacity() const
Definition: IOBuf.h:593
IOBuf() noexcept
Definition: IOBuf.cpp:361
static IOBuf folly::IOBuf::wrapBufferAsValue ( ByteRange  br)
inlinestaticnoexcept

Definition at line 398 of file IOBuf.h.

References fizz::test::copyBuffer(), folly::pushmi::__adl::noexcept(), and folly::size().

398  {
399  return wrapBufferAsValue(br.data(), br.size());
400  }
static IOBuf wrapBufferAsValue(const void *buf, std::size_t capacity) noexcept
Definition: IOBuf.cpp:357
unique_ptr< IOBuf > folly::IOBuf::wrapIov ( const iovec *  vec,
size_t  count 
)
static

A helper that wraps a number of iovecs into an IOBuf chain. If count == 0, then a zero length buf is returned. This function never returns nullptr.

Definition at line 1027 of file IOBuf.cpp.

References count, create(), data(), i, folly::gen::move, UNLIKELY, and wrapBuffer().

Referenced by folly::WriteChainAsyncTransportWrapper< folly::AsyncTransportWrapper >::writev().

1027  {
1028  unique_ptr<IOBuf> result = nullptr;
1029  for (size_t i = 0; i < count; ++i) {
1030  size_t len = vec[i].iov_len;
1031  void* data = vec[i].iov_base;
1032  if (len > 0) {
1033  auto buf = wrapBuffer(data, len);
1034  if (!result) {
1035  result = std::move(buf);
1036  } else {
1037  result->prependChain(std::move(buf));
1038  }
1039  }
1040  }
1041  if (UNLIKELY(result == nullptr)) {
1042  return create(0);
1043  }
1044  return result;
1045 }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
Definition: IOBuf.cpp:353
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const uint8_t * data() const
Definition: IOBuf.h:499
Definition: Traits.h:588
int * count
#define UNLIKELY(x)
Definition: Likely.h:48
uint8_t* folly::IOBuf::writableBuffer ( )
inline

Get a writable pointer to the start of the buffer.

The caller is responsible for calling unshare() first to ensure that it is actually safe to write to the buffer.

Definition at line 572 of file IOBuf.h.

Referenced by folly::AsyncPipeReader::handlerReady(), reserveSlow(), and folly::TypedIOBuf< T >::writableBuffer().

572  {
573  return buf_;
574  }
uint8_t * buf_
Definition: IOBuf.h:1433
uint8_t* folly::IOBuf::writableData ( )
inline
uint8_t* folly::IOBuf::writableTail ( )
inline

Get a writable pointer to the end of the data.

The caller is responsible for calling unshare() first to ensure that it is actually safe to write to the buffer.

Definition at line 526 of file IOBuf.h.

References data_, and length_.

Referenced by folly::IOBufQueue::append(), folly::gen::detail::consumeBufferPlus(), folly::IOBufQueue::dcheckCacheIntegrity(), folly::io::StreamCodec::doUncompress(), moveToFbString(), TEST(), folly::IOBufQueue::updateWritableTailCache(), and folly::TypedIOBuf< T >::writableTail().

526  {
527  return data_ + length_;
528  }
uint8_t * data_
Definition: IOBuf.h:1432
std::size_t length_
Definition: IOBuf.h:1434

Member Data Documentation

uint8_t* folly::IOBuf::buf_ {nullptr}
private
std::size_t folly::IOBuf::capacity_ {0}
private
uint8_t* folly::IOBuf::data_ {nullptr}
private
uintptr_t folly::IOBuf::flagsAndSharedInfo_ {0}
mutableprivate

Definition at line 1438 of file IOBuf.h.

Referenced by cloneOneAsValue(), moveToFbString(), and operator=().

std::size_t folly::IOBuf::length_ {0}
private
IOBuf* folly::IOBuf::prev_ {this}
private

Definition at line 1424 of file IOBuf.h.

Referenced by coalesceAndReallocate(), IOBuf(), operator=(), prependChain(), and separateChain().


The documentation for this class was generated from the following files: