Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / PrebufferedStreambuf.cc
1
2 #include "common/PrebufferedStreambuf.h"
3 #include <string.h>
4 PrebufferedStreambuf::PrebufferedStreambuf(char *buf, size_t len)
5   : m_buf(buf), m_buf_len(len)
6 {
7   // init output buffer
8   this->setp(m_buf, m_buf + m_buf_len);
9
10   // so we underflow on first read
11   this->setg(0, 0, 0);
12 }
13
14 PrebufferedStreambuf::int_type PrebufferedStreambuf::overflow(int_type c)
15 {
16   int old_len = m_overflow.size();
17   if (old_len == 0) {
18     m_overflow.resize(80);
19   } else {
20     m_overflow.resize(old_len * 2);
21   }
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);
25 }
26
27 PrebufferedStreambuf::int_type PrebufferedStreambuf::underflow()
28 {
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)
35       // m_buf is empty
36       return traits_ty::eof();  // no data
37     else
38       // set up portion of m_buf we've filled
39       this->setg(m_buf, m_buf, this->pptr());
40     return *this->gptr();
41   }
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());
45     return *this->gptr();
46   }
47
48   // otherwise we must be at the end (of m_buf and/or m_overflow)
49   return traits_ty::eof();
50 }
51
52 std::string PrebufferedStreambuf::get_str() const
53 {
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]);
57     return s;
58   } else if (this->pptr() == m_buf) {
59     return std::string();
60   } else {
61     return std::string(m_buf, this->pptr() - m_buf);
62   }  
63 }
64 // returns current size of content
65 size_t PrebufferedStreambuf::size() const
66 {
67   if (m_overflow.size() == 0) {
68     return this->pptr() - m_buf;
69   } else {
70     return m_buf_len + this->pptr() - &m_overflow[0];
71   }
72 }
73
74 // extracts up to avail chars of content
75 int PrebufferedStreambuf::snprintf(char* dst, size_t avail) const
76 {
77   size_t o_size = m_overflow.size();
78   size_t len_a;
79   size_t len_b;
80   if (o_size>0) {
81     len_a = m_buf_len;
82     len_b = this->pptr() - &m_overflow[0];
83   } else {
84     len_a = this->pptr() - m_buf;
85     len_b = 0;
86   }
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;
91   } else {
92     if (avail > len_a) {
93       memcpy(dst, m_buf, len_a);
94       memcpy(dst + m_buf_len, m_overflow.c_str(), avail - len_a - 1);
95       dst[avail - 1] = 0;
96     } else {
97       memcpy(dst, m_buf, avail - 1);
98       dst[avail - 1] = 0;
99     }
100   }
101   return len_a + len_b;
102 }