proxygen
folly::io::Appender Class Reference

#include <Cursor.h>

Inheritance diagram for folly::io::Appender:
folly::io::detail::Writable< Appender >

Public Member Functions

 Appender (IOBuf *buf, std::size_t growth)
 
uint8_twritableData ()
 
size_t length () const
 
void append (size_t n)
 
void ensure (std::size_t n)
 
size_t pushAtMost (const uint8_t *buf, size_t len)
 
void printf (FOLLY_PRINTF_FORMAT const char *fmt,...) FOLLY_PRINTF_FORMAT_ATTR(2
 
void void vprintf (const char *fmt, va_list ap)
 
void operator() (StringPiece sp)
 
- Public Member Functions inherited from folly::io::detail::Writable< Appender >
std::enable_if< std::is_arithmetic< T >::value >::type write (T value)
 
void writeBE (T value)
 
void writeLE (T value)
 
void push (const uint8_t *buf, size_t len)
 
void push (ByteRange buf)
 
void push (Cursor cursor, size_t len)
 
size_t pushAtMost (ByteRange buf)
 
size_t pushAtMost (Cursor cursor, size_t len)
 

Private Member Functions

bool tryGrowChain ()
 

Private Attributes

IOBufbuffer_
 
IOBufcrtBuf_
 
std::size_t growth_
 

Detailed Description

Append to the end of a buffer chain, growing the chain (by allocating new buffers) in increments of at least growth bytes every time. Won't grow (and push() and ensure() will throw) if growth == 0.

TODO(tudorb): add a flavor of Appender that reallocates one IOBuf instead of chaining.

Definition at line 969 of file Cursor.h.

Constructor & Destructor Documentation

folly::io::Appender::Appender ( IOBuf buf,
std::size_t  growth 
)
inline

Definition at line 971 of file Cursor.h.

972  : buffer_(buf), crtBuf_(buf->prev()), growth_(growth) {}
std::size_t growth_
Definition: Cursor.h:1098

Member Function Documentation

void folly::io::Appender::append ( size_t  n)
inline

Mark n bytes (must be <= length()) as appended, as per the IOBuf::append() method.

Definition at line 986 of file Cursor.h.

References folly::io::detail::CursorBase< Derived, BufType >::crtBuf_.

Referenced by vprintf().

986  {
987  crtBuf_->append(n);
988  }
void append(std::size_t amount)
Definition: IOBuf.h:689
void folly::io::Appender::ensure ( std::size_t  n)
inline

Ensure at least n contiguous bytes available to write. Postcondition: length() >= n.

Definition at line 994 of file Cursor.h.

References folly::io::detail::CursorBase< Derived, BufType >::buffer_, folly::IOBuf::create(), folly::io::detail::CursorBase< Derived, BufType >::crtBuf_, folly::io::detail::CursorBase< Derived, BufType >::length(), LIKELY, and max.

Referenced by vprintf().

994  {
995  if (LIKELY(length() >= n)) {
996  return;
997  }
998 
999  // Waste the rest of the current buffer and allocate a new one.
1000  // Don't make it too small, either.
1001  if (growth_ == 0) {
1002  throw_exception<std::out_of_range>("can't grow buffer chain");
1003  }
1004 
1005  n = std::max(n, growth_);
1007  crtBuf_ = buffer_->prev();
1008  }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
LogLevel max
Definition: LogLevel.cpp:31
#define LIKELY(x)
Definition: Likely.h:47
size_t length() const
Definition: Cursor.h:978
std::size_t growth_
Definition: Cursor.h:1098
void prependChain(std::unique_ptr< IOBuf > &&iobuf)
Definition: IOBuf.cpp:509
IOBuf * prev()
Definition: IOBuf.h:610
size_t folly::io::Appender::length ( ) const
inline

Definition at line 978 of file Cursor.h.

References folly::io::detail::CursorBase< Derived, BufType >::crtBuf_.

Referenced by vprintf().

978  {
979  return crtBuf_->tailroom();
980  }
std::size_t tailroom() const
Definition: IOBuf.h:551
void folly::io::Appender::operator() ( StringPiece  sp)
inline

Definition at line 1080 of file Cursor.h.

1080  {
1081  push(ByteRange(sp));
1082  }
void push(const uint8_t *buf, size_t len)
Definition: Cursor.h:755
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
void folly::io::Appender::printf ( FOLLY_PRINTF_FORMAT const char *  fmt,
  ... 
)

Definition at line 26 of file Cursor.cpp.

References vprintf().

Referenced by TEST().

26  {
27  va_list ap;
28  va_start(ap, fmt);
29  vprintf(fmt, ap);
30  va_end(ap);
31 }
void void vprintf(const char *fmt, va_list ap)
Definition: Cursor.cpp:33
size_t folly::io::Appender::pushAtMost ( const uint8_t buf,
size_t  len 
)
inline

Definition at line 1011 of file Cursor.h.

References append(), FOLLY_PRINTF_FORMAT, FOLLY_PRINTF_FORMAT_ATTR, folly::io::detail::CursorBase< Derived, BufType >::length(), LIKELY, and UNLIKELY.

1011  {
1012  // We have to explicitly check for an input length of 0.
1013  // We support buf being nullptr in this case, but we need to avoid calling
1014  // memcpy() with a null source pointer, since that is undefined behavior
1015  // even if the length is 0.
1016  if (len == 0) {
1017  return 0;
1018  }
1019 
1020  // If the length of this buffer is 0 try growing it.
1021  // Otherwise on the first iteration of the following loop memcpy is called
1022  // with a null source pointer.
1023  if (UNLIKELY(length() == 0 && !tryGrowChain())) {
1024  return 0;
1025  }
1026 
1027  size_t copied = 0;
1028  for (;;) {
1029  // Fast path: it all fits in one buffer.
1030  size_t available = length();
1031  if (LIKELY(available >= len)) {
1032  memcpy(writableData(), buf, len);
1033  append(len);
1034  return copied + len;
1035  }
1036 
1037  memcpy(writableData(), buf, available);
1038  append(available);
1039  copied += available;
1040  if (UNLIKELY(!tryGrowChain())) {
1041  return copied;
1042  }
1043  buf += available;
1044  len -= available;
1045  }
1046  }
bool tryGrowChain()
Definition: Cursor.h:1085
#define LIKELY(x)
Definition: Likely.h:47
void append(size_t n)
Definition: Cursor.h:986
size_t length() const
Definition: Cursor.h:978
#define UNLIKELY(x)
Definition: Likely.h:48
uint8_t * writableData()
Definition: Cursor.h:974
bool folly::io::Appender::tryGrowChain ( )
inlineprivate

Definition at line 1085 of file Cursor.h.

References folly::io::detail::CursorBase< Derived, BufType >::buffer_, folly::IOBuf::create(), and folly::io::detail::CursorBase< Derived, BufType >::crtBuf_.

1085  {
1086  assert(crtBuf_->next() == buffer_);
1087  if (growth_ == 0) {
1088  return false;
1089  }
1090 
1092  crtBuf_ = buffer_->prev();
1093  return true;
1094  }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
std::size_t growth_
Definition: Cursor.h:1098
IOBuf * next()
Definition: IOBuf.h:600
void prependChain(std::unique_ptr< IOBuf > &&iobuf)
Definition: IOBuf.cpp:509
IOBuf * prev()
Definition: IOBuf.h:610
void folly::io::Appender::vprintf ( const char *  fmt,
va_list  ap 
)

Definition at line 33 of file Cursor.cpp.

References append(), ensure(), length(), SCOPE_EXIT, and writableData().

Referenced by printf().

33  {
34  // Make a copy of ap in case we need to retry.
35  // We use ap on the first attempt, so it always gets advanced
36  // passed the used arguments. We'll only use apCopy if we need to retry.
37  va_list apCopy;
38  va_copy(apCopy, ap);
39  SCOPE_EXIT {
40  va_end(apCopy);
41  };
42 
43  // First try writing into our available data space.
44  int ret =
45  vsnprintf(reinterpret_cast<char*>(writableData()), length(), fmt, ap);
46  if (ret < 0) {
47  throw std::runtime_error("error formatting printf() data");
48  }
49  auto len = size_t(ret);
50  // vsnprintf() returns the number of characters that would be printed,
51  // not including the terminating nul.
52  if (len < length()) {
53  // All of the data was successfully written.
54  append(len);
55  return;
56  }
57 
58  // There wasn't enough room for the data.
59  // Allocate more room, and then retry.
60  ensure(len + 1);
61  ret =
62  vsnprintf(reinterpret_cast<char*>(writableData()), length(), fmt, apCopy);
63  if (ret < 0) {
64  throw std::runtime_error("error formatting printf() data");
65  }
66  len = size_t(ret);
67  if (len >= length()) {
68  // This shouldn't ever happen.
69  throw std::runtime_error(
70  "unexpectedly out of buffer space on second "
71  "vsnprintf() attmept");
72  }
73  append(len);
74 }
void append(size_t n)
Definition: Cursor.h:986
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
size_t length() const
Definition: Cursor.h:978
void ensure(std::size_t n)
Definition: Cursor.h:994
uint8_t * writableData()
Definition: Cursor.h:974
uint8_t* folly::io::Appender::writableData ( )
inline

Definition at line 974 of file Cursor.h.

References folly::io::detail::CursorBase< Derived, BufType >::crtBuf_.

Referenced by vprintf().

974  {
975  return crtBuf_->writableTail();
976  }
uint8_t * writableTail()
Definition: IOBuf.h:526

Member Data Documentation

IOBuf* folly::io::Appender::buffer_
private

Definition at line 1096 of file Cursor.h.

IOBuf* folly::io::Appender::crtBuf_
private

Definition at line 1097 of file Cursor.h.

std::size_t folly::io::Appender::growth_
private

Definition at line 1098 of file Cursor.h.


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