From 6a15c8431f8fbf078003a8f000f21e1968cb7da8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 25 Nov 2015 12:50:09 +0200 Subject: Implement ofdstream --- butl/fdstream.cxx | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 4 deletions(-) (limited to 'butl/fdstream.cxx') diff --git a/butl/fdstream.cxx b/butl/fdstream.cxx index 6d7532a..0386f49 100644 --- a/butl/fdstream.cxx +++ b/butl/fdstream.cxx @@ -5,9 +5,9 @@ #include #ifndef _WIN32 -# include // close, read +# include // close(), read(), write() #else -# include // _close, _read +# include // _close(), _read(), _write() #endif #include @@ -20,9 +20,18 @@ namespace butl ~fdbuf () {close ();} void fdbuf:: + open (int fd) + { + close (); + fd_ = fd; + setg (buf_, buf_, buf_); + setp (buf_, buf_ + sizeof (buf_) - 1); // Keep space for overflow's char. + } + + void fdbuf:: close () { - if (fd_ != -1) + if (is_open ()) { #ifndef _WIN32 ::close (fd_); @@ -42,7 +51,7 @@ namespace butl fdbuf::int_type fdbuf:: underflow () { - int_type r = traits_type::eof (); + int_type r (traits_type::eof ()); if (is_open ()) { @@ -68,4 +77,55 @@ namespace butl setg (buf_, buf_, buf_ + n); return n != 0; } + + fdbuf::int_type fdbuf:: + overflow (int_type c) + { + int_type r (traits_type::eof ()); + + if (is_open () && c != traits_type::eof ()) + { + // Store last character in the space we reserved in open(). Note + // that pbump() doesn't do any checks. + // + *pptr () = traits_type::to_char_type (c); + pbump (1); + + if (save ()) + r = c; + } + + return r; + } + + int fdbuf:: + sync () + { + return is_open () && save () ? 0 : -1; + } + + bool fdbuf:: + save () + { + size_t n (pptr () - pbase ()); + + if (n != 0) + { +#ifndef _WIN32 + ssize_t m (::write (fd_, buf_, n)); +#else + int m (_write (fd_, buf_, static_cast (sizeof (buf_)))); +#endif + + if (m == -1) + throw system_error (errno, system_category ()); + + if (n != static_cast (m)) + return false; + + setp (buf_, buf_ + sizeof (buf_) - 1); + } + + return true; + } } -- cgit v1.1