2 #include "common/PrebufferedStreambuf.h"
4 PrebufferedStreambuf::PrebufferedStreambuf(char *buf, size_t len)
5 : m_buf(buf), m_buf_len(len)
8 this->setp(m_buf, m_buf + m_buf_len);
10 // so we underflow on first read
14 PrebufferedStreambuf::int_type PrebufferedStreambuf::overflow(int_type c)
16 int old_len = m_overflow.size();
18 m_overflow.resize(80);
20 m_overflow.resize(old_len * 2);
22 m_overflow[old_len] = c;
23 this->setp(&m_overflow[old_len + 1], &*m_overflow.begin() + m_overflow.size());
24 return std::char_traits<char>::not_eof(c);
27 PrebufferedStreambuf::int_type PrebufferedStreambuf::underflow()
29 if (this->gptr() == 0) {
30 // first read; start with the static buffer
31 if (m_overflow.size())
32 // there is overflow, so start with entire prealloc buffer
33 this->setg(m_buf, m_buf, m_buf + m_buf_len);
34 else if (this->pptr() == m_buf)
36 return traits_ty::eof(); // no data
38 // set up portion of m_buf we've filled
39 this->setg(m_buf, m_buf, this->pptr());
42 if (this->gptr() == m_buf + m_buf_len && m_overflow.size()) {
43 // at end of m_buf; continue with the overflow string
44 this->setg(&m_overflow[0], &m_overflow[0], this->pptr());
48 // otherwise we must be at the end (of m_buf and/or m_overflow)
49 return traits_ty::eof();
52 std::string PrebufferedStreambuf::get_str() const
54 if (m_overflow.size()) {
55 std::string s(m_buf, m_buf + m_buf_len);
56 s.append(&m_overflow[0], this->pptr() - &m_overflow[0]);
58 } else if (this->pptr() == m_buf) {
61 return std::string(m_buf, this->pptr() - m_buf);
64 // returns current size of content
65 size_t PrebufferedStreambuf::size() const
67 if (m_overflow.size() == 0) {
68 return this->pptr() - m_buf;
70 return m_buf_len + this->pptr() - &m_overflow[0];
74 // extracts up to avail chars of content
75 int PrebufferedStreambuf::snprintf(char* dst, size_t avail) const
77 size_t o_size = m_overflow.size();
82 len_b = this->pptr() - &m_overflow[0];
84 len_a = this->pptr() - m_buf;
87 if (avail > len_a + len_b) {
88 memcpy(dst, m_buf, len_a);
89 memcpy(dst + m_buf_len, m_overflow.c_str(), len_b);
90 dst[len_a + len_b] = 0;
93 memcpy(dst, m_buf, len_a);
94 memcpy(dst + m_buf_len, m_overflow.c_str(), avail - len_a - 1);
97 memcpy(dst, m_buf, avail - 1);
101 return len_a + len_b;