diff options
Diffstat (limited to 'butl/fdstream')
-rw-r--r-- | butl/fdstream | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/butl/fdstream b/butl/fdstream new file mode 100644 index 0000000..01a19b7 --- /dev/null +++ b/butl/fdstream @@ -0,0 +1,86 @@ +// file : butl/fdstream -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUTL_FDSTREAM +#define BUTL_FDSTREAM + +#include <istream> + +namespace butl +{ + // An input stream that is initialized with a file descriptor + // rather than a file name. + // + // Notes and limitations: + // + // - char only + // - input only + // - no support for put back + // - throws std::system_error in case of a read() error + // - not movable, though can be easily supported + // + class fdbuf: public std::basic_streambuf<char> + { + public: + virtual + ~fdbuf (); + fdbuf () = default; + fdbuf (int fd) {open (fd);} + + fdbuf (const fdbuf&) = delete; + fdbuf& operator= (const fdbuf&) = delete; + + void + close (); + + void + open (int fd) {close (); fd_ = fd; setg (buf_, buf_, buf_);} + + bool + is_open () const {return fd_ != -1;} + + // basic_streambuf input interface. + // + public: + using int_type = std::basic_streambuf<char>::int_type; + using traits_type = std::basic_streambuf<char>::traits_type; + + virtual std::streamsize + showmanyc (); + + virtual int_type + underflow (); + + private: + bool + load (); + + private: + int fd_ = -1; + char buf_[2048]; + }; + + class ifdstream_base + { + protected: + ifdstream_base () = default; + ifdstream_base (int fd): buf_ (fd) {} + + protected: + fdbuf buf_; + }; + + class ifdstream: ifdstream_base, public std::istream + { + public: + ifdstream (): std::istream (&buf_) {} + ifdstream (int fd): ifdstream_base (fd), std::istream (&buf_) {} + + void close () {buf_.close ();} + void open (int fd) {buf_.open (fd);} + bool is_open () const {return buf_.is_open ();} + }; +} + +#endif // BUTL_FDSTREAM |