}
}
+void
+IOBufQueue::wrapBuffer(const void* buf, size_t len, uint32_t blockSize) {
+ auto src = static_cast<const uint8_t*>(buf);
+ while (len != 0) {
+ size_t n = std::min(len, size_t(blockSize));
+ append(IOBuf::wrapBuffer(src, n));
+ src += n;
+ len -= n;
+ }
+}
+
pair<void*,uint32_t>
IOBufQueue::preallocate(uint32_t min, uint32_t max) {
if (head_ != NULL) {
append(buf.data(), buf.length());
}
+ /**
+ * Append a chain of IOBuf objects that point to consecutive regions
+ * within buf.
+ *
+ * Just like IOBuf::wrapBuffer, this should only be used when the caller
+ * knows 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;
+ * all other caveats from wrapBuffer also apply.
+ *
+ * Every buffer except for the last will wrap exactly blockSize bytes.
+ * 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
+
/**
* Obtain a writable block of contiguous bytes at the end of this
* queue, allocating more space if necessary. The amount of space
*/
#include "folly/experimental/io/IOBufQueue.h"
+#include "folly/Range.h"
#include <gflags/gflags.h>
#include <gtest/gtest.h>
using folly::IOBuf;
using folly::IOBufQueue;
+using folly::StringPiece;
using std::pair;
using std::string;
using std::unique_ptr;
EXPECT_GE(4096, writable.second);
}
+TEST(IOBufQueue, Wrap) {
+ IOBufQueue queue(clOptions);
+ const char* buf = "hello world goodbye";
+ size_t len = strlen(buf);
+ queue.wrapBuffer(buf, len, 6);
+ auto iob = queue.move();
+ EXPECT_EQ((len - 1) / 6 + 1, iob->countChainElements());
+ iob->unshare();
+ iob->coalesce();
+ EXPECT_EQ(StringPiece(buf),
+ StringPiece(reinterpret_cast<const char*>(iob->data()),
+ iob->length()));
+}
+
TEST(IOBufQueue, trim) {
IOBufQueue queue(clOptions);
unique_ptr<IOBuf> a = IOBuf::create(4);