Ensure curly-braces around control-flow
[folly.git] / folly / io / IOBufQueue.h
index f499492e9049a0193fa08eada52d7fa1d863a043..c801920d34f793cd9e60608af254207652657564 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#ifndef FOLLY_IO_IOBUF_QUEUE_H
-#define FOLLY_IO_IOBUF_QUEUE_H
+#pragma once
 
-#include "folly/io/IOBuf.h"
+#include <folly/io/IOBuf.h>
 
 #include <stdexcept>
 #include <string>
@@ -54,18 +53,18 @@ class IOBufQueue {
   /**
    * Return a space to prepend bytes and the amount of headroom available.
    */
-  std::pair<void*, uint32_t> headroom();
+  std::pair<void*, uint64_t> headroom();
 
   /**
    * Indicate that n bytes from the headroom have been used.
    */
-  void markPrepended(uint32_t n);
+  void markPrepended(uint64_t n);
 
   /**
    * Prepend an existing range; throws std::overflow_error if not enough
    * room.
    */
-  void prepend(const void* buf, uint32_t n);
+  void prepend(const void* buf, uint64_t n);
 
   /**
    * Add a buffer or buffer chain to the end of this queue. The
@@ -98,8 +97,8 @@ class IOBufQueue {
    * Copy a string to the end of this queue.
    * The caller retains ownership of the source data.
    */
-  void append(const std::string& buf) {
-    append(buf.data(), buf.length());
+  void append(StringPiece sp) {
+    append(sp.data(), sp.size());
   }
 
   /**
@@ -115,7 +114,7 @@ class IOBufQueue {
    * Importantly, this method may be used to wrap buffers larger than 4GB.
    */
   void wrapBuffer(const void* buf, size_t len,
-                  uint32_t blockSize=(1U << 31));  // default block size: 2GB
+                  uint64_t blockSize=(1U << 31));  // default block size: 2GB
 
   /**
    * Obtain a writable block of contiguous bytes at the end of this
@@ -137,9 +136,9 @@ class IOBufQueue {
    *       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 newAllocationSize,
-    uint32_t max = std::numeric_limits<uint32_t>::max()) {
+  std::pair<void*,uint64_t> preallocate(
+    uint64_t min, uint64_t newAllocationSize,
+    uint64_t max = std::numeric_limits<uint64_t>::max()) {
     auto buf = tailBuf();
     if (LIKELY(buf && buf->tailroom() >= min)) {
       return std::make_pair(buf->writableTail(),
@@ -159,7 +158,7 @@ class IOBufQueue {
    *       invoke any other non-const methods on this IOBufQueue between
    *       the call to preallocate and the call to postallocate().
    */
-  void postallocate(uint32_t n) {
+  void postallocate(uint64_t n) {
     head_->prev()->append(n);
     chainLength_ += n;
   }
@@ -168,7 +167,7 @@ class IOBufQueue {
    * 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* allocate(uint64_t n) {
     void* p = preallocate(n, n).first;
     postallocate(n);
     return p;
@@ -196,7 +195,17 @@ class IOBufQueue {
    * @throws std::underflow_error if n exceeds the number of bytes
    *         in the queue.
    */
-  std::unique_ptr<folly::IOBuf> split(size_t n);
+  std::unique_ptr<folly::IOBuf> split(size_t n) {
+    return split(n, true);
+  }
+
+  /**
+   * Similar to split, but will return the entire queue instead of throwing
+   * if n exceeds the number of bytes in the queue.
+   */
+  std::unique_ptr<folly::IOBuf> splitAtMost(size_t n) {
+    return split(n, false);
+  }
 
   /**
    * Similar to IOBuf::trimStart, but works on the whole queue.  Will
@@ -204,12 +213,24 @@ class IOBufQueue {
    */
   void trimStart(size_t amount);
 
+  /**
+   * Similar to trimStart, but will trim at most amount bytes and returns
+   * the number of bytes trimmed.
+   */
+  size_t trimStartAtMost(size_t amount);
+
   /**
    * Similar to IOBuf::trimEnd, but works on the whole queue.  Will
    * pop off buffers that have been completely trimmed.
    */
   void trimEnd(size_t amount);
 
+  /**
+   * Similar to trimEnd, but will trim at most amount bytes and returns
+   * the number of bytes trimmed.
+   */
+  size_t trimEndAtMost(size_t amount);
+
   /**
    * Transfer ownership of the queue's entire IOBuf chain to the caller.
    */
@@ -261,18 +282,32 @@ class IOBufQueue {
    */
   void clear();
 
+  /**
+   * Append the queue to a std::string. Non-destructive.
+   */
+  void appendToString(std::string& out) const;
+
+  /**
+   * Calls IOBuf::gather() on the head of the queue, if it exists.
+   */
+  void gather(uint64_t maxLength);
+
   /** Movable */
-  IOBufQueue(IOBufQueue&&);
+  IOBufQueue(IOBufQueue&&) noexcept;
   IOBufQueue& operator=(IOBufQueue&&);
 
  private:
   IOBuf* tailBuf() const {
-    if (UNLIKELY(!head_)) return nullptr;
+    if (UNLIKELY(!head_)) {
+      return nullptr;
+    }
     IOBuf* buf = head_->prev();
     return LIKELY(!buf->isSharedOne()) ? buf : nullptr;
   }
-  std::pair<void*,uint32_t> preallocateSlow(
-    uint32_t min, uint32_t newAllocationSize, uint32_t max);
+  std::pair<void*,uint64_t> preallocateSlow(
+    uint64_t min, uint64_t newAllocationSize, uint64_t max);
+
+  std::unique_ptr<folly::IOBuf> split(size_t n, bool throwOnUnderflow);
 
   static const size_t kChainLengthNotCached = (size_t)-1;
   /** Not copyable */
@@ -289,6 +324,4 @@ class IOBufQueue {
   std::unique_ptr<folly::IOBuf> head_;
 };
 
-} // folly
-
-#endif // FOLLY_IO_IOBUF_QUEUE_H
+} // namespace folly