aboutsummaryrefslogtreecommitdiff
path: root/butl/fdstream.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'butl/fdstream.cxx')
-rw-r--r--butl/fdstream.cxx71
1 files changed, 71 insertions, 0 deletions
diff --git a/butl/fdstream.cxx b/butl/fdstream.cxx
new file mode 100644
index 0000000..6d7532a
--- /dev/null
+++ b/butl/fdstream.cxx
@@ -0,0 +1,71 @@
+// file : butl/fdstream.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <butl/fdstream>
+
+#ifndef _WIN32
+# include <unistd.h> // close, read
+#else
+# include <io.h> // _close, _read
+#endif
+
+#include <system_error>
+
+using namespace std;
+
+namespace butl
+{
+ fdbuf::
+ ~fdbuf () {close ();}
+
+ void fdbuf::
+ close ()
+ {
+ if (fd_ != -1)
+ {
+#ifndef _WIN32
+ ::close (fd_);
+#else
+ _close (fd_);
+#endif
+ fd_ = -1;
+ }
+ }
+
+ streamsize fdbuf::
+ showmanyc ()
+ {
+ return is_open () ? static_cast<streamsize> (egptr () - gptr ()) : -1;
+ }
+
+ fdbuf::int_type fdbuf::
+ underflow ()
+ {
+ int_type r = traits_type::eof ();
+
+ if (is_open ())
+ {
+ if (gptr () < egptr () || load ())
+ r = traits_type::to_int_type (*gptr ());
+ }
+
+ return r;
+ }
+
+ bool fdbuf::
+ load ()
+ {
+#ifndef _WIN32
+ ssize_t n (::read (fd_, buf_, sizeof (buf_)));
+#else
+ int n (_read (fd_, buf_, sizeof (buf_)));
+#endif
+
+ if (n == -1)
+ throw system_error (errno, system_category ());
+
+ setg (buf_, buf_, buf_ + n);
+ return n != 0;
+ }
+}