31 template <
typename T,
int N=1024>
class fbuf ;
54template <
typename T,
int N>
58 using read_fn_t = std::function<ssize_t(T,
char*,std::size_t)> ;
59 using write_fn_t = std::function<ssize_t(T,
const char*,std::size_t)> ;
60 using close_fn_t = std::function<void(T)> ;
62 explicit fbuf( read_fn_t , write_fn_t , close_fn_t ) ;
65 explicit fbuf( T
file , read_fn_t , write_fn_t , close_fn_t ) ;
91 fbuf<T,N> & operator=( const
fbuf<T,N> & ) = delete ;
92 fbuf<T,N> & operator=(
fbuf<T,N> && ) = delete ;
95 using traits_type =
std::streambuf::traits_type ;
99 static constexpr
int sync_ok = 0 ;
100 static constexpr
int sync_fail = -1 ;
101 read_fn_t m_read_fn ;
102 write_fn_t m_write_fn ;
103 close_fn_t m_close_fn ;
104 std::vector<
char> m_input ;
105 std::vector<
char> m_output ;
110template <typename T,
int N>
111G::
fbuf<T,N>::
fbuf(
G::
fbuf<T,N>::read_fn_t read ,
G::
fbuf<T,N>::write_fn_t write ,
G::
fbuf<T,N>::close_fn_t close ) :
115 m_input(static_cast<
std::
size_t>(N)) ,
116 m_output(static_cast<
std::
size_t>(N)) ,
120 static_assert( N > 0 ,
"" ) ;
123template <
typename T,
int N>
124G::fbuf<T,N>::fbuf( T
file , G::fbuf<T,N>::read_fn_t read , G::fbuf<T,N>::write_fn_t write , G::fbuf<T,N>::close_fn_t close ) :
128 m_input(static_cast<
std::size_t>(N)) ,
129 m_output(static_cast<
std::size_t>(N)) ,
133 static_assert( N > 0 ,
"" ) ;
139 template <
typename T,
int N>
152template <
typename T,
int N>
160 char * input_begin = m_input.data() ;
161 setg( input_begin , input_begin , input_begin ) ;
163 char * output_begin = m_output.data() ;
164 char * output_end = output_begin + m_output.size() ;
165 setp( output_begin , output_end-1 ) ;
168template <
typename T,
int N>
174 m_close_fn( m_file ) ;
175 m_file_open = false ;
179template <
typename T,
int N>
182 if( !traits_type::eq_int_type( c , traits_type::eof() ) )
184 *pptr() = traits_type::to_char_type( c ) ;
187 return sync() == sync_fail ? traits_type::eof() : traits_type::not_eof(c) ;
190template <
typename T,
int N>
193 if( pbase() == pptr() )
199 std::size_t size = pptr() - pbase() ;
200 ssize_t nwrite = m_write_fn( m_file , pbase() , size ) ;
205 else if(
static_cast<std::size_t
>(nwrite) < size )
207 std::copy( pbase()+nwrite , pptr() , pbase() ) ;
208 setp( pbase() , epptr() ) ;
209 pbump(
static_cast<int>(size-nwrite) ) ;
214 setp( pbase() , epptr() ) ;
220template <
typename T,
int N>
223 if( gptr() == egptr() )
225 char * input_begin = m_input.data() ;
226 ssize_t nread = m_read_fn( m_file , input_begin , m_input.size() ) ;
228 return traits_type::eof() ;
229 std::size_t nreadu = nread >= 0 ?
static_cast<std::size_t
>(nread) : std::size_t(0U) ;
230 setg( input_begin , input_begin , input_begin+nreadu ) ;
232 return traits_type::to_int_type( *gptr() ) ;
235template <
typename T,
int N>
A simple file streambuf using a "file descriptor" and three function pointers for read,...
int underflow() override
Called to pull a character out of the input buffer, and pre-fill the input buffer if necessary.
void open(T file)
Installs the given file descriptor.
int overflow(int c) override
Called to put a character into the output buffer.
fbuf(T file, read_fn_t, write_fn_t, close_fn_t)
Constructor passed an open file descriptor.
~fbuf() override
Destructor. Closes the file.
T file() const
Returns the current file descriptor.
int sync() final
Called to sync the stream.
fbuf(read_fn_t, write_fn_t, close_fn_t)
Constructor. Use open() to initialise.