1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#ifndef BUFFERFD_H
#define BUFFERFD_H
class read_bufferfd : public autofd {
static const size_t DEFAULT_BUF_SIZE;
const size_t buf_size;
auto_array<char> buffer;
mutable size_t startpos, endpos;
ssize_t buffer_copy( void *buf, size_t count ) const;
public:
explicit read_bufferfd( size_t bufsize=DEFAULT_BUF_SIZE ) : buf_size(bufsize),
buffer(new char [bufsize]), startpos(0), endpos(0)
{
}
read_bufferfd( const autofd &rhs, size_t bufsize=DEFAULT_BUF_SIZE ) : autofd(rhs),
buf_size(bufsize), buffer(new char [bufsize]), startpos(0), endpos(0)
{
}
// We're actually ok with default copy constructor
// We would be ok with default operator=, except that it needs to change some read-only vars
read_bufferfd &operator=( const read_bufferfd &rhs ) {
*static_cast<autofd *>(this)=rhs;
const_cast<size_t &>(buf_size)=rhs.buf_size;
buffer=const_cast<auto_array<char> &>(rhs.buffer);
startpos=rhs.startpos;
endpos=rhs.endpos;
return *this;
}
ssize_t read( void *buf, size_t count ) const;
};
class write_bufferfd : public autofd {
static const size_t DEFAULT_BUF_SIZE;
const size_t buf_size;
auto_array<char> buffer;
mutable int buffill;
mutable bool error;
public:
write_bufferfd( size_t bufsize=DEFAULT_BUF_SIZE ) : buf_size(bufsize),
buffer(new char [bufsize]), buffill(0), error(false)
{
}
write_bufferfd( const autofd &rhs, size_t bufsize=DEFAULT_BUF_SIZE ) : autofd(rhs),
buf_size(bufsize), buffer(new char [bufsize]), buffill(0), error(false)
{
}
// This is not exactly the copy constructor, as the right hand side is not const
write_bufferfd( write_bufferfd &rhs ) : autofd(rhs), buf_size(rhs.buf_size), error(false)
{
rhs.flush();
static_cast<autofd &>(*this)=rhs;
buffer=rhs.buffer;
buffill=0;
}
// A close relative - the operator=
write_bufferfd &operator=( write_bufferfd &rhs )
{
flush();
rhs.flush();
// Do not copy the buffer size, obviously
static_cast<autofd &>(*this)=rhs;
error=false;
return *this;
}
~write_bufferfd()
{
if( !error )
flush();
}
ssize_t write( void *buf, size_t count );
void flush();
void clear() {
flush();
autofd::clear();
}
};
#endif // BUFFERFD_H
|