}
}
+ template<bool is_const>
+ size_t buffer::list::iterator_impl<is_const>::get_ptr_and_advance(
+ size_t want, const char **data)
+ {
+ if (p == ls->end()) {
+ seek(off);
+ if (p == ls->end()) {
+ return 0;
+ }
+ }
+ *data = p->c_str() + p_off;
+ size_t l = MIN(p->length() - p_off, want);
+ p_off += l;
+ if (p_off == p->length()) {
+ ++p;
+ p_off = 0;
+ }
+ return l;
+ }
+
// explicitly instantiate only the iterator types we need, so we can hide the
// details in this compilation unit without introducing unnecessary link time
// dependencies.
void copy(unsigned len, std::string &dest);
void copy_all(list &dest);
+ // get a pointer to the currenet iterator position, return the
+ // number of bytes we can read from that position (up to want),
+ // and advance the iterator by that amount.
+ size_t get_ptr_and_advance(size_t want, const char **p);
+
friend bool operator==(const iterator_impl& lhs,
const iterator_impl& rhs) {
return &lhs.get_bl() == &rhs.get_bl() && lhs.get_off() == rhs.get_off();
}
}
+TEST(BufferListIterator, get_ptr_and_advance)
+{
+ bufferptr a("one", 3);
+ bufferptr b("two", 3);
+ bufferptr c("three", 5);
+ bufferlist bl;
+ bl.append(a);
+ bl.append(b);
+ bl.append(c);
+ const char *ptr;
+ bufferlist::iterator p = bl.begin();
+ ASSERT_EQ(3u, p.get_ptr_and_advance(11, &ptr));
+ ASSERT_EQ(0, memcmp(ptr, "one", 3));
+ ASSERT_EQ(2u, p.get_ptr_and_advance(2, &ptr));
+ ASSERT_EQ(0, memcmp(ptr, "tw", 2));
+ ASSERT_EQ(1u, p.get_ptr_and_advance(4, &ptr));
+ ASSERT_EQ(0, memcmp(ptr, "o", 1));
+ ASSERT_EQ(5u, p.get_ptr_and_advance(5, &ptr));
+ ASSERT_EQ(0, memcmp(ptr, "three", 5));
+}
+
TEST(BufferListIterator, seek) {
bufferlist bl;
bl.append("ABC", 3);