11 Buffered::Buffered(Base &b, unsigned s):
14 buf(new char[buf_size]),
18 mode = below.get_mode();
19 below.signal_flush_required.connect(sigc::mem_fun(this, &Buffered::flush));
34 void Buffered::set_block(bool)
36 throw logic_error("Buffered::set_block");
39 void Buffered::set_inherit(bool)
41 throw logic_error("Buffered::set_block");
44 void Buffered::flush()
48 unsigned used = end-begin;
51 unsigned len = below.write(begin, used);
56 throw runtime_error("Couldn't flush all data");
59 else if(cur_op==M_READ)
63 size_t Buffered::do_write(const char *data, size_t size)
67 if(end+size<buf+buf_size)
69 // All data fits in buffer with whatever is already there
70 memcpy(end, data, size);
77 // Clear the buffer to make more room
82 // Put new data in the buffer to wait for more
83 memcpy(end, data, size);
89 // New data still doesn't fit in the buffer, so write it directly
90 return below.write(data, size);
94 size_t Buffered::do_read(char *data, size_t size)
100 // The request can be served from the buffer
101 memcpy(data, begin, size);
104 eof_flag = (below.eof() && begin==end);
110 // Give out whatever is in the buffer already
111 memcpy(data, begin, end-begin);
112 size_t ret = end-begin;
120 // Fill the buffer and serve the rest of the request from it
121 size_t len = below.read(end, buf+buf_size-end);
124 len = min<size_t>(end-begin, size);
125 memcpy(data, begin, len);
130 // Read the rest directly from the underlying object
131 ret += below.read(data, size);
133 eof_flag = (below.eof() && begin==end);
139 size_t Buffered::put(char c)
149 return do_write(&c, 1);
152 bool Buffered::getline(string &line)
156 for(char *i=begin; i!=end; ++i)
159 line.assign(begin, i-begin);
164 return Base::getline(line);
172 return static_cast<unsigned char>(*begin++);
175 if(do_read(&c, 1)==0)
177 return static_cast<unsigned char>(c);
180 const Handle &Buffered::get_handle(Mode)
182 throw logic_error("Buffered::get_handle");
185 void Buffered::set_op(Mode op)
192 size_t Buffered::get_current_size() const