X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2FPrebufferedStreambuf.cc;fp=src%2Fceph%2Fsrc%2Fcommon%2FPrebufferedStreambuf.cc;h=fe27ef5db0e57e73b374ef21ab84ffffbe603716;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/common/PrebufferedStreambuf.cc b/src/ceph/src/common/PrebufferedStreambuf.cc new file mode 100644 index 0000000..fe27ef5 --- /dev/null +++ b/src/ceph/src/common/PrebufferedStreambuf.cc @@ -0,0 +1,102 @@ + +#include "common/PrebufferedStreambuf.h" +#include +PrebufferedStreambuf::PrebufferedStreambuf(char *buf, size_t len) + : m_buf(buf), m_buf_len(len) +{ + // init output buffer + this->setp(m_buf, m_buf + m_buf_len); + + // so we underflow on first read + this->setg(0, 0, 0); +} + +PrebufferedStreambuf::int_type PrebufferedStreambuf::overflow(int_type c) +{ + int old_len = m_overflow.size(); + if (old_len == 0) { + m_overflow.resize(80); + } else { + m_overflow.resize(old_len * 2); + } + m_overflow[old_len] = c; + this->setp(&m_overflow[old_len + 1], &*m_overflow.begin() + m_overflow.size()); + return std::char_traits::not_eof(c); +} + +PrebufferedStreambuf::int_type PrebufferedStreambuf::underflow() +{ + if (this->gptr() == 0) { + // first read; start with the static buffer + if (m_overflow.size()) + // there is overflow, so start with entire prealloc buffer + this->setg(m_buf, m_buf, m_buf + m_buf_len); + else if (this->pptr() == m_buf) + // m_buf is empty + return traits_ty::eof(); // no data + else + // set up portion of m_buf we've filled + this->setg(m_buf, m_buf, this->pptr()); + return *this->gptr(); + } + if (this->gptr() == m_buf + m_buf_len && m_overflow.size()) { + // at end of m_buf; continue with the overflow string + this->setg(&m_overflow[0], &m_overflow[0], this->pptr()); + return *this->gptr(); + } + + // otherwise we must be at the end (of m_buf and/or m_overflow) + return traits_ty::eof(); +} + +std::string PrebufferedStreambuf::get_str() const +{ + if (m_overflow.size()) { + std::string s(m_buf, m_buf + m_buf_len); + s.append(&m_overflow[0], this->pptr() - &m_overflow[0]); + return s; + } else if (this->pptr() == m_buf) { + return std::string(); + } else { + return std::string(m_buf, this->pptr() - m_buf); + } +} +// returns current size of content +size_t PrebufferedStreambuf::size() const +{ + if (m_overflow.size() == 0) { + return this->pptr() - m_buf; + } else { + return m_buf_len + this->pptr() - &m_overflow[0]; + } +} + +// extracts up to avail chars of content +int PrebufferedStreambuf::snprintf(char* dst, size_t avail) const +{ + size_t o_size = m_overflow.size(); + size_t len_a; + size_t len_b; + if (o_size>0) { + len_a = m_buf_len; + len_b = this->pptr() - &m_overflow[0]; + } else { + len_a = this->pptr() - m_buf; + len_b = 0; + } + if (avail > len_a + len_b) { + memcpy(dst, m_buf, len_a); + memcpy(dst + m_buf_len, m_overflow.c_str(), len_b); + dst[len_a + len_b] = 0; + } else { + if (avail > len_a) { + memcpy(dst, m_buf, len_a); + memcpy(dst + m_buf_len, m_overflow.c_str(), avail - len_a - 1); + dst[avail - 1] = 0; + } else { + memcpy(dst, m_buf, avail - 1); + dst[avail - 1] = 0; + } + } + return len_a + len_b; +}