* An IOBufQueue encapsulates a chain of IOBufs and provides
* convenience functions to append data to the back of the chain
* and remove data from the front.
+ *
+ * You may also prepend data into the headroom of the first buffer in the
+ * chain, if any.
*/
class IOBufQueue {
public:
bool cacheChainLength;
};
+ /**
+ * Commonly used Options, currently the only possible value other than
+ * the default.
+ */
+ static Options cacheChainLength() {
+ Options options;
+ options.cacheChainLength = true;
+ return options;
+ }
+
explicit IOBufQueue(const Options& options = Options());
+ /**
+ * Return a space to prepend bytes and the amount of headroom available.
+ */
+ std::pair<void*, uint32_t> headroom();
+
+ /**
+ * Indicate that n bytes from the headroom have been used.
+ */
+ void markPrepended(uint32_t n);
+
+ /**
+ * Prepend an existing range; throws std::overflow_error if not enough
+ * room.
+ */
+ void prepend(const void* buf, uint32_t n);
+
/**
* Add a buffer or buffer chain to the end of this queue. The
* queue takes ownership of buf.
/**
* Obtain a writable block of contiguous bytes at the end of this
* queue, allocating more space if necessary. The amount of space
- * reserved will be between min and max, inclusive; the IOBufQueue
- * implementation may pick a value in that range that makes efficient
- * use of already-allocated internal space.
+ * reserved will be at least min. If min contiguous space is not
+ * available at the end of the queue, and IOBuf with size newAllocationSize
+ * is appended to the chain and returned. The actual available space
+ * may be larger than newAllocationSize, but will be truncated to max,
+ * if specified.
*
* If the caller subsequently writes anything into the returned space,
* it must call the postallocate() method.
* callback, tell the application how much of the buffer they've
* filled with data.
*/
- std::pair<void*,uint32_t> preallocate(uint32_t min, uint32_t max);
+ std::pair<void*,uint32_t> preallocate(
+ uint32_t min, uint32_t newAllocationSize,
+ uint32_t max = std::numeric_limits<uint32_t>::max());
/**
* Tell the queue that the caller has written data into the first n
*/
void postallocate(uint32_t n);
+ /**
+ * Obtain a writable block of n contiguous bytes, allocating more space
+ * if necessary, and mark it as used. The caller can fill it later.
+ */
+ void* allocate(uint32_t n) {
+ void* p = preallocate(n, n).first;
+ postallocate(n);
+ return p;
+ }
+
/**
* Split off the first n bytes of the queue into a separate IOBuf chain,
* and transfer ownership of the new chain to the caller. The IOBufQueue
/**
* Transfer ownership of the queue's entire IOBuf chain to the caller.
*/
- std::unique_ptr<folly::IOBuf>&& move() {
+ std::unique_ptr<folly::IOBuf> move() {
chainLength_ = 0;
return std::move(head_);
}