#include <folly/Range.h>
#include <folly/io/Cursor.h>
#include <folly/portability/GTest.h>
+#include <numeric>
+#include <vector>
using folly::ByteRange;
using folly::format;
wcursor.writeLE((uint64_t)1);
wcursor.write((uint8_t)1);
- EXPECT_EQ(1, rcursor.readLE<uint64_t>());
+ EXPECT_EQ(1u, rcursor.readLE<uint64_t>());
rcursor.skip(8);
- EXPECT_EQ(1, rcursor.readLE<uint32_t>());
+ EXPECT_EQ(1u, rcursor.readLE<uint32_t>());
rcursor.skip(0);
- EXPECT_EQ(0, rcursor.read<uint8_t>());
- EXPECT_EQ(0, rcursor.read<uint8_t>());
- EXPECT_EQ(0, rcursor.read<uint8_t>());
- EXPECT_EQ(0, rcursor.read<uint8_t>());
- EXPECT_EQ(1, rcursor.read<uint8_t>());
+ EXPECT_EQ(0u, rcursor.read<uint8_t>());
+ EXPECT_EQ(0u, rcursor.read<uint8_t>());
+ EXPECT_EQ(0u, rcursor.read<uint8_t>());
+ EXPECT_EQ(0u, rcursor.read<uint8_t>());
+ EXPECT_EQ(1u, rcursor.read<uint8_t>());
}
TEST(IOBuf, skip) {
append(head, "hello");
Appender app(head.get(), 10);
- uint32_t cap = head->capacity();
- uint32_t len1 = app.length();
+ auto cap = head->capacity();
+ auto len1 = app.length();
EXPECT_EQ(cap - 5, len1);
app.ensure(len1); // won't grow
EXPECT_EQ(len1, app.length());
"longer than our original allocation size,",
"and will therefore require a new allocation", 0x12345678);
// The tailroom should start with a nul byte now.
- EXPECT_GE(head.prev()->tailroom(), 1);
+ EXPECT_GE(head.prev()->tailroom(), 1u);
EXPECT_EQ(0, *head.prev()->tail());
EXPECT_EQ("test32this string is longer than our original "
}
// There must be a goodMallocSize between 100 and 1024...
- EXPECT_LT(1, queue.front()->countChainElements());
+ EXPECT_LT(1u, queue.front()->countChainElements());
const IOBuf* buf = queue.front();
do {
- EXPECT_LE(100, buf->capacity());
+ EXPECT_LE(100u, buf->capacity());
buf = buf->next();
} while (buf != queue.front());
EXPECT_THROW({cursor.readBE<uint32_t>();}, std::out_of_range);
}
+TEST(IOBuf, QueueAppenderPushAtMostFillBuffer) {
+ folly::IOBufQueue queue;
+ // There should be a goodMallocSize between 125 and 1000
+ QueueAppender appender{&queue, 125};
+ std::vector<uint8_t> data;
+ data.resize(1000);
+ std::iota(data.begin(), data.end(), 0);
+ // Add 100 byte
+ appender.pushAtMost(data.data(), 100);
+ // Add 900 bytes
+ appender.pushAtMost(data.data() + 100, data.size() - 100);
+ const auto buf = queue.front();
+ // Should fill the current buffer before adding another
+ EXPECT_LE(2, buf->countChainElements());
+ EXPECT_EQ(0, buf->tailroom());
+ EXPECT_LE(125, buf->length());
+ EXPECT_EQ(1000, buf->computeChainDataLength());
+ const StringPiece sp{(const char*)data.data(), data.size()};
+ EXPECT_EQ(sp, toString(*buf));
+}
+
+TEST(IOBuf, QueueAppenderInsertOwn) {
+ auto buf = IOBuf::create(10);
+ folly::IOBufQueue queue;
+ QueueAppender appender{&queue, 128};
+ appender.insert(std::move(buf));
+
+ std::vector<uint8_t> data;
+ data.resize(256);
+ std::iota(data.begin(), data.end(), 0);
+ appender.pushAtMost(folly::range(data));
+ // Buffer is owned, so we should write to it
+ EXPECT_LE(2, queue.front()->countChainElements());
+ EXPECT_EQ(0, queue.front()->tailroom());
+ const StringPiece sp{(const char*)data.data(), data.size()};
+ EXPECT_EQ(sp, toString(*queue.front()));
+}
+
+TEST(IOBuf, QueueAppenderInsertClone) {
+ IOBuf buf{IOBuf::CREATE, 100};
+ folly::IOBufQueue queue;
+ QueueAppender appender{&queue, 100};
+ // Buffer is shared, so we create a new buffer to write to
+ appender.insert(buf);
+ uint8_t x = 42;
+ appender.pushAtMost(&x, 1);
+ EXPECT_EQ(2, queue.front()->countChainElements());
+ EXPECT_EQ(0, queue.front()->length());
+ EXPECT_LT(0, queue.front()->tailroom());
+ EXPECT_EQ(1, queue.front()->next()->length());
+ EXPECT_EQ(x, queue.front()->next()->data()[0]);
+}
+
TEST(IOBuf, CursorOperators) {
// Test operators on a single-item chain
{