Boost logo

Boost-Commit :

From: technews_at_[hidden]
Date: 2008-01-07 18:03:38


Author: turkanis
Date: 2008-01-07 18:03:38 EST (Mon, 07 Jan 2008)
New Revision: 42593
URL: http://svn.boost.org/trac/boost/changeset/42593

Log:
Simplified implementation with the help to the C-runtime function _get_osfhandle so that on Windows only a single HANDLE is stored and the POSIX-style implementation is never needed; added the handle_type on POSIX systems (typedef for int) and a function returning the underlying handle as an instance of handle_type
Text files modified:
   branches/iostreams_dev/boost/iostreams/device/file_descriptor.hpp | 66 +++++++++----------
   branches/iostreams_dev/libs/iostreams/src/file_descriptor.cpp | 131 +++++++++++++++++++++++----------------
   2 files changed, 107 insertions(+), 90 deletions(-)

Modified: branches/iostreams_dev/boost/iostreams/device/file_descriptor.hpp
==============================================================================
--- branches/iostreams_dev/boost/iostreams/device/file_descriptor.hpp (original)
+++ branches/iostreams_dev/boost/iostreams/device/file_descriptor.hpp 2008-01-07 18:03:38 EST (Mon, 07 Jan 2008)
@@ -32,29 +32,25 @@
 class BOOST_IOSTREAMS_DECL file_descriptor {
 public:
 #ifdef BOOST_IOSTREAMS_WINDOWS
- typedef void* handle_type;
+ typedef void* handle_type; // A.k.a HANDLE
+#else
+ typedef int handle_type;
 #endif
     typedef char char_type;
     struct category
         : seekable_device_tag,
           closable_tag
         { };
- file_descriptor() : pimpl_(new impl) { }
- explicit file_descriptor(int fd, bool close_on_exit = false)
- : pimpl_(new impl(fd, close_on_exit))
- { }
+ file_descriptor();
+ explicit file_descriptor(handle_type fd, bool close_on_exit = false);
 #ifdef BOOST_IOSTREAMS_WINDOWS
- explicit file_descriptor(handle_type handle, bool close_on_exit = false)
- : pimpl_(new impl(handle, close_on_exit))
- { }
+ explicit file_descriptor(int fd, bool close_on_exit = false);
 #endif
     explicit file_descriptor( const std::string& path,
                               BOOST_IOS::openmode mode =
                                   BOOST_IOS::in | BOOST_IOS::out,
                               BOOST_IOS::openmode base_mode =
- BOOST_IOS::in | BOOST_IOS::out )
- : pimpl_(new impl)
- { open(path, mode, base_mode); }
+ BOOST_IOS::in | BOOST_IOS::out );
     void open( const std::string& path,
                BOOST_IOS::openmode =
                    BOOST_IOS::in | BOOST_IOS::out,
@@ -65,41 +61,37 @@
     std::streamsize write(const char_type* s, std::streamsize n);
     std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
     void close();
+ handle_type handle() const { return pimpl_->handle_; }
 private:
     struct impl {
- impl() : fd_(-1), flags_(0) { }
- impl(int fd, bool close_on_exit)
- : fd_(fd), flags_(0)
- { if (close_on_exit) flags_ |= impl::close_on_exit; }
- #ifdef BOOST_IOSTREAMS_WINDOWS
- impl(handle_type handle, bool close_on_exit)
- : handle_(handle), flags_(has_handle)
+ impl() : handle_(reinterpret_cast<handle_type>(-1)), flags_(0) { }
+ impl(handle_type fd, bool close_on_exit)
+ : handle_(fd), flags_(0)
         { if (close_on_exit) flags_ |= impl::close_on_exit; }
- #endif
- ~impl() {
- if (flags_ & close_on_exit) close_impl(*this);
- }
+ ~impl()
+ { if (flags_ & close_on_exit) close_impl(*this); }
         enum flags {
             close_on_exit = 1,
- has_handle = 2,
             append = 4
         };
- int fd_;
- #ifdef BOOST_IOSTREAMS_WINDOWS
         handle_type handle_;
- #endif
         int flags_;
     };
     friend struct impl;
 
     static void close_impl(impl&);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ static handle_type int_to_handle(int fd);
+#endif
 
     shared_ptr<impl> pimpl_;
 };
 
 struct file_descriptor_source : private file_descriptor {
 #ifdef BOOST_IOSTREAMS_WINDOWS
- typedef void* handle_type;
+ typedef void* handle_type; // A.k.a HANDLE
+#else
+ typedef int handle_type;
 #endif
     typedef char char_type;
     struct category
@@ -112,14 +104,14 @@
     using file_descriptor::open;
     using file_descriptor::is_open;
     using file_descriptor::close;
+ using file_descriptor::handle;
     file_descriptor_source() { }
- explicit file_descriptor_source(int fd, bool close_on_exit = false)
+ explicit file_descriptor_source(handle_type fd, bool close_on_exit = false)
         : file_descriptor(fd, close_on_exit)
         { }
 #ifdef BOOST_IOSTREAMS_WINDOWS
- explicit file_descriptor_source( handle_type handle,
- bool close_on_exit = false )
- : file_descriptor(handle, close_on_exit)
+ explicit file_descriptor_source(int fd, bool close_on_exit = false)
+ : file_descriptor(fd, close_on_exit)
         { }
 #endif
     explicit file_descriptor_source( const std::string& path,
@@ -130,7 +122,9 @@
 
 struct file_descriptor_sink : private file_descriptor {
 #ifdef BOOST_IOSTREAMS_WINDOWS
- typedef void* handle_type;
+ typedef void* handle_type; // A.k.a HANDLE
+#else
+ typedef int handle_type;
 #endif
     typedef char char_type;
     struct category
@@ -143,14 +137,14 @@
     using file_descriptor::open;
     using file_descriptor::is_open;
     using file_descriptor::close;
+ using file_descriptor::handle;
     file_descriptor_sink() { }
- explicit file_descriptor_sink(int fd, bool close_on_exit = false)
+ explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false)
         : file_descriptor(fd, close_on_exit)
         { }
 #ifdef BOOST_IOSTREAMS_WINDOWS
- explicit file_descriptor_sink( handle_type handle,
- bool close_on_exit = false )
- : file_descriptor(handle, close_on_exit)
+ explicit file_descriptor_sink(int fd, bool close_on_exit = false)
+ : file_descriptor(fd, close_on_exit)
         { }
 #endif
     explicit file_descriptor_sink( const std::string& path,

Modified: branches/iostreams_dev/libs/iostreams/src/file_descriptor.cpp
==============================================================================
--- branches/iostreams_dev/libs/iostreams/src/file_descriptor.cpp (original)
+++ branches/iostreams_dev/libs/iostreams/src/file_descriptor.cpp 2008-01-07 18:03:38 EST (Mon, 07 Jan 2008)
@@ -44,6 +44,24 @@
 
 //------------------Implementation of file_descriptor-------------------------//
 
+file_descriptor::file_descriptor() : pimpl_(new impl) { }
+
+file_descriptor::file_descriptor(handle_type fd, bool close_on_exit)
+ : pimpl_(new impl(fd, close_on_exit))
+ { }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ file_descriptor::file_descriptor(int fd, bool close_on_exit)
+ : pimpl_(new impl(int_to_handle(fd), close_on_exit))
+ { }
+#endif
+
+file_descriptor::file_descriptor( const std::string& path,
+ BOOST_IOS::openmode mode,
+ BOOST_IOS::openmode base_mode )
+ : pimpl_(new impl)
+{ open(path, mode, base_mode); }
+
 void file_descriptor::open
     ( const std::string& path, BOOST_IOS::openmode m,
       BOOST_IOS::openmode base )
@@ -88,7 +106,7 @@
                        NULL ); // hTemplateFile
     if (handle != INVALID_HANDLE_VALUE) {
         pimpl_->handle_ = handle;
- pimpl_->flags_ |= impl::close_on_exit | impl::has_handle;
+ pimpl_->flags_ |= impl::close_on_exit;
     } else {
         pimpl_->flags_ = 0;
         throw BOOST_IOSTREAMS_FAILURE("bad open");
@@ -131,7 +149,7 @@
     if (fd == -1) {
         throw BOOST_IOSTREAMS_FAILURE("bad open");
     } else {
- pimpl_->fd_ = fd;
+ pimpl_->handle_ = fd;
         pimpl_->flags_ = impl::close_on_exit;
     }
 #endif // #ifndef BOOST_IOSTREAMS_WINDOWS //----------------------------------//
@@ -140,43 +158,41 @@
 std::streamsize file_descriptor::read(char_type* s, std::streamsize n)
 {
 #ifdef BOOST_IOSTREAMS_WINDOWS
- if (pimpl_->flags_ & impl::has_handle) {
- DWORD result;
- if (!::ReadFile(pimpl_->handle_, s, n, &result, NULL))
- throw detail::bad_read();
- return static_cast<std::streamsize>(result);
- }
-#endif
+ DWORD result;
+ if (!::ReadFile(pimpl_->handle_, s, n, &result, NULL))
+ throw detail::bad_read();
+ return static_cast<std::streamsize>(result);
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
     errno = 0;
- std::streamsize result = BOOST_IOSTREAMS_FD_READ(pimpl_->fd_, s, n);
+ std::streamsize result = BOOST_IOSTREAMS_FD_READ(pimpl_->handle_, s, n);
     if (errno != 0)
         throw detail::bad_read();
     return result == 0 ? -1 : result;
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
 std::streamsize file_descriptor::write(const char_type* s, std::streamsize n)
 {
 #ifdef BOOST_IOSTREAMS_WINDOWS
- if (pimpl_->flags_ & impl::has_handle) {
- if (pimpl_->flags_ & impl::append) {
- DWORD const dwResult =
- ::SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END);
- if ( dwResult == INVALID_SET_FILE_POINTER &&
- ::GetLastError() != NO_ERROR )
- {
- throw detail::bad_seek();
- }
+ if (pimpl_->flags_ & impl::append) {
+ DWORD const dwResult =
+ ::SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END);
+ if ( dwResult == INVALID_SET_FILE_POINTER &&
+ ::GetLastError() != NO_ERROR )
+ {
+ throw detail::bad_seek();
         }
- DWORD ignore;
- if (!::WriteFile(pimpl_->handle_, s, n, &ignore, NULL))
- throw detail::bad_write();
- return n;
     }
-#endif
- int amt = BOOST_IOSTREAMS_FD_WRITE(pimpl_->fd_, s, n);
+ DWORD ignore;
+ if (!::WriteFile(pimpl_->handle_, s, n, &ignore, NULL))
+ throw detail::bad_write();
+ return n;
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
+ int amt = BOOST_IOSTREAMS_FD_WRITE(pimpl_->handle_, s, n);
     if (amt < n)
         throw detail::bad_write(); // Handles blocking fd's only.
     return n;
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
 std::streampos file_descriptor::seek
@@ -184,29 +200,27 @@
 {
     using namespace std;
 #ifdef BOOST_IOSTREAMS_WINDOWS
- if (pimpl_->flags_ & impl::has_handle) {
- LONG lDistanceToMove = static_cast<LONG>(off & 0xffffffff);
- LONG lDistanceToMoveHigh = static_cast<LONG>(off >> 32);
- DWORD dwResultLow =
- ::SetFilePointer( pimpl_->handle_,
- lDistanceToMove,
- &lDistanceToMoveHigh,
- way == BOOST_IOS::beg ?
- FILE_BEGIN :
- way == BOOST_IOS::cur ?
- FILE_CURRENT :
- FILE_END );
- if ( dwResultLow == INVALID_SET_FILE_POINTER &&
- ::GetLastError() != NO_ERROR )
- {
- throw detail::bad_seek();
- } else {
- return offset_to_position(
- (stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow
- );
- }
+ LONG lDistanceToMove = static_cast<LONG>(off & 0xffffffff);
+ LONG lDistanceToMoveHigh = static_cast<LONG>(off >> 32);
+ DWORD dwResultLow =
+ ::SetFilePointer( pimpl_->handle_,
+ lDistanceToMove,
+ &lDistanceToMoveHigh,
+ way == BOOST_IOS::beg ?
+ FILE_BEGIN :
+ way == BOOST_IOS::cur ?
+ FILE_CURRENT :
+ FILE_END );
+ if ( dwResultLow == INVALID_SET_FILE_POINTER &&
+ ::GetLastError() != NO_ERROR )
+ {
+ throw detail::bad_seek();
+ } else {
+ return offset_to_position(
+ (stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow
+ );
     }
-#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
     if ( off > integer_traits<BOOST_IOSTREAMS_FD_OFFSET>::const_max ||
          off < integer_traits<BOOST_IOSTREAMS_FD_OFFSET>::const_min )
     {
@@ -214,7 +228,7 @@
     }
     stream_offset result =
         BOOST_IOSTREAMS_FD_SEEK(
- pimpl_->fd_,
+ pimpl_->handle_,
             static_cast<BOOST_IOSTREAMS_FD_OFFSET>(off),
             ( way == BOOST_IOS::beg ?
                   SEEK_SET :
@@ -225,6 +239,7 @@
     if (result == -1)
         throw detail::bad_seek();
     return offset_to_position(result);
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
 void file_descriptor::close() { close_impl(*pimpl_); }
@@ -232,20 +247,28 @@
 void file_descriptor::close_impl(impl& i)
 {
 #ifdef BOOST_IOSTREAMS_WINDOWS
- if (i.flags_ & impl::has_handle) {
+ if (i.handle_ != reinterpret_cast<handle_type>(-1)) {
         if (!::CloseHandle(i.handle_))
             throw BOOST_IOSTREAMS_FAILURE("bad close");
- i.fd_ = -1;
+ i.handle_ = reinterpret_cast<handle_type>(-1);
         i.flags_ = 0;
         return;
     }
-#endif
- if (i.fd_ != -1) {
- if (BOOST_IOSTREAMS_FD_CLOSE(i.fd_) == -1)
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
+ if (i.handle_ != -1) {
+ if (BOOST_IOSTREAMS_FD_CLOSE(i.handle_) == -1)
             throw BOOST_IOSTREAMS_FAILURE("bad close");
- i.fd_ = -1;
+ i.handle_ = -1;
         i.flags_ = 0;
     }
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+}
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+file_descriptor::handle_type file_descriptor::int_to_handle(int fd)
+{
+ return reinterpret_cast<handle_type>(_get_osfhandle(fd));
 }
+#endif
 
 } } // End namespaces iostreams, boost.


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk