$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: technews_at_[hidden]
Date: 2008-01-07 18:13:27
Author: turkanis
Date: 2008-01-07 18:13:26 EST (Mon, 07 Jan 2008)
New Revision: 42596
URL: http://svn.boost.org/trac/boost/changeset/42596
Log:
merged changes from branches/iostreams_dev, revisions 42565-42595:
- 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
- fixed the bug described in ticket Ticket #1551 (stream_buffer::seekpos ignores openmode parameter)
- fixed test/operation_sequence_test.cpp file description
Text files modified: 
   trunk/boost/iostreams/detail/streambuf/direct_streambuf.hpp   |     5                                         
   trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp |     5                                         
   trunk/boost/iostreams/device/file_descriptor.hpp              |    66 +++++++++----------                     
   trunk/libs/iostreams/src/file_descriptor.cpp                  |   131 +++++++++++++++++++++++---------------- 
   trunk/libs/iostreams/test/operation_sequence_test.cpp         |     5                                         
   5 files changed, 113 insertions(+), 99 deletions(-)
Modified: trunk/boost/iostreams/detail/streambuf/direct_streambuf.hpp
==============================================================================
--- trunk/boost/iostreams/detail/streambuf/direct_streambuf.hpp	(original)
+++ trunk/boost/iostreams/detail/streambuf/direct_streambuf.hpp	2008-01-07 18:13:26 EST (Mon, 07 Jan 2008)
@@ -187,10 +187,9 @@
 template<typename T, typename Tr>
 inline typename direct_streambuf<T, Tr>::pos_type
 direct_streambuf<T, Tr>::seekpos
-    (pos_type sp, BOOST_IOS::openmode)
+    (pos_type sp, BOOST_IOS::openmode which)
 { 
-    return seek_impl( position_to_offset(sp), BOOST_IOS::beg, 
-                      BOOST_IOS::in | BOOST_IOS::out );
+    return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which);
 }
 
 template<typename T, typename Tr>
Modified: trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp
==============================================================================
--- trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp	(original)
+++ trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp	2008-01-07 18:13:26 EST (Mon, 07 Jan 2008)
@@ -332,10 +332,9 @@
 template<typename T, typename Tr, typename Alloc, typename Mode>
 inline typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
 indirect_streambuf<T, Tr, Alloc, Mode>::seekpos
-    (pos_type sp, BOOST_IOS::openmode)
+    (pos_type sp, BOOST_IOS::openmode which)
 { 
-    return seek_impl( position_to_offset(sp), BOOST_IOS::beg, 
-                      BOOST_IOS::in | BOOST_IOS::out ); 
+    return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which); 
 }
 
 template<typename T, typename Tr, typename Alloc, typename Mode>
Modified: trunk/boost/iostreams/device/file_descriptor.hpp
==============================================================================
--- trunk/boost/iostreams/device/file_descriptor.hpp	(original)
+++ trunk/boost/iostreams/device/file_descriptor.hpp	2008-01-07 18:13:26 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: trunk/libs/iostreams/src/file_descriptor.cpp
==============================================================================
--- trunk/libs/iostreams/src/file_descriptor.cpp	(original)
+++ trunk/libs/iostreams/src/file_descriptor.cpp	2008-01-07 18:13:26 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.
Modified: trunk/libs/iostreams/test/operation_sequence_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/operation_sequence_test.cpp	(original)
+++ trunk/libs/iostreams/test/operation_sequence_test.cpp	2008-01-07 18:13:26 EST (Mon, 07 Jan 2008)
@@ -4,9 +4,8 @@
  * 
  * See http://www.boost.org/libs/iostreams for documentation.
  *
- * Verifies that the close() member functions of filters and devices
- * are called with the correct arguments in the correct order when 
- * they are combined using chains or adapters.
+ * Tests the facilities defined in the header
+ * libs/iostreams/test/detail/operation_sequence.hpp
  *
  * File:        libs/iostreams/test/operation_sequence_test.cpp
  * Date:        Mon Dec 10 18:58:19 MST 2007