aboutsummaryrefslogtreecommitdiff
path: root/butl/fdstream
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-17 11:07:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-06-17 11:07:21 +0200
commita8fc877aa93bb9c2dcc9ccde372a943dcfd25cfb (patch)
treed8aba766721b486b17f2d9378516784a977d4418 /butl/fdstream
parenteac6ad21038ccfb1edd33612f33539bd0bb45b2a (diff)
Implement ifdstream, file descriptor input stream
This is a portable replacement for GNU <ext/stdio_filebuf>.
Diffstat (limited to 'butl/fdstream')
-rw-r--r--butl/fdstream86
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