From a8fc877aa93bb9c2dcc9ccde372a943dcfd25cfb Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 17 Jun 2015 11:07:21 +0200 Subject: Implement ifdstream, file descriptor input stream This is a portable replacement for GNU . --- butl/fdstream | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 butl/fdstream (limited to 'butl/fdstream') 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 + +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 + { + 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::int_type; + using traits_type = std::basic_streambuf::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 -- cgit v1.1