// 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