if (LIKELY(length() >= sizeof(T))) {
val = loadUnaligned<T>(data());
offset_ += sizeof(T);
+ advanceBufferIfEmpty();
} else {
pullSlow(&val, sizeof(T));
}
if (LIKELY(length() >= len)) {
str.append(reinterpret_cast<const char*>(data()), len);
offset_ += len;
+ advanceBufferIfEmpty();
} else {
readFixedStringSlow(&str, len);
}
}
skip(i);
-
- if (UNLIKELY(!tryAdvanceBuffer())) {
- throw std::out_of_range("string underflow");
- }
}
}
size_t skipAtMost(size_t len) {
if (LIKELY(length() >= len)) {
offset_ += len;
+ advanceBufferIfEmpty();
return len;
}
return skipAtMostSlow(len);
void skip(size_t len) {
if (LIKELY(length() >= len)) {
offset_ += len;
+ advanceBufferIfEmpty();
} else {
skipSlow(len);
}
if (LIKELY(length() >= len)) {
memcpy(buf, data(), len);
offset_ += len;
+ advanceBufferIfEmpty();
return len;
}
return pullAtMostSlow(buf, len);
if (LIKELY(length() >= len)) {
memcpy(buf, data(), len);
offset_ += len;
+ advanceBufferIfEmpty();
} else {
pullSlow(buf, len);
}
}
offset_ += len;
+ advanceBufferIfEmpty();
return copied + len;
}
return true;
}
+ void advanceBufferIfEmpty() {
+ if (length() == 0) {
+ tryAdvanceBuffer();
+ }
+ }
+
BufType* crtBuf_;
size_t offset_ = 0;
}
str->append(reinterpret_cast<const char*>(data()), len);
offset_ += len;
+ advanceBufferIfEmpty();
}
size_t pullAtMostSlow(void* buf, size_t len) {
}
memcpy(p, data(), len);
offset_ += len;
+ advanceBufferIfEmpty();
return copied + len;
}
len -= available;
}
offset_ += len;
+ advanceBufferIfEmpty();
return skipped + len;
}
}
}
+TEST(IOBuf, cloneWithEmptyBufAtStart) {
+ folly::IOBufEqual eq;
+ auto empty = IOBuf::create(0);
+ auto hel = IOBuf::create(3);
+ append(hel, "hel");
+ auto lo = IOBuf::create(2);
+ append(lo, "lo");
+
+ auto iobuf = empty->clone();
+ iobuf->prependChain(hel->clone());
+ iobuf->prependChain(lo->clone());
+ iobuf->prependChain(empty->clone());
+ iobuf->prependChain(hel->clone());
+ iobuf->prependChain(lo->clone());
+ iobuf->prependChain(empty->clone());
+ iobuf->prependChain(lo->clone());
+ iobuf->prependChain(hel->clone());
+ iobuf->prependChain(lo->clone());
+ iobuf->prependChain(lo->clone());
+
+ Cursor cursor(iobuf.get());
+ std::unique_ptr<IOBuf> cloned;
+ char data[3];
+ cursor.pull(&data, 3);
+ cursor.clone(cloned, 2);
+ EXPECT_EQ(1, cloned->countChainElements());
+ EXPECT_EQ(2, cloned->length());
+ EXPECT_TRUE(eq(lo, cloned));
+
+ cursor.pull(&data, 3);
+ EXPECT_EQ("hel", std::string(data, sizeof(data)));
+
+ cursor.skip(2);
+ cursor.clone(cloned, 2);
+ EXPECT_TRUE(eq(lo, cloned));
+
+ std::string hello = cursor.readFixedString(5);
+ cursor.clone(cloned, 2);
+ EXPECT_TRUE(eq(lo, cloned));
+}
+
TEST(IOBuf, Appender) {
std::unique_ptr<IOBuf> head(IOBuf::create(10));
append(head, "hello");