Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62934 - in trunk: boost/iostreams/device libs/iostreams/src libs/iostreams/test libs/iostreams/test/detail
From: steven_at_[hidden]
Date: 2010-06-14 11:56:01


Author: steven_watanabe
Date: 2010-06-14 11:56:00 EDT (Mon, 14 Jun 2010)
New Revision: 62934
URL: http://svn.boost.org/trac/boost/changeset/62934

Log:
Rejigger file_descriptors handling of std::ios_base::openmode to match std::fstream. In particular, truncate existing files, if std::ios_base::trunc is passed. Refs #3323.
Text files modified:
   trunk/boost/iostreams/device/file_descriptor.hpp | 2
   trunk/libs/iostreams/src/file_descriptor.cpp | 35 +++-
   trunk/libs/iostreams/test/detail/verification.hpp | 7
   trunk/libs/iostreams/test/file_descriptor_test.cpp | 315 +++++++++++++++++++++++++++++++++++++++
   4 files changed, 347 insertions(+), 12 deletions(-)

Modified: trunk/boost/iostreams/device/file_descriptor.hpp
==============================================================================
--- trunk/boost/iostreams/device/file_descriptor.hpp (original)
+++ trunk/boost/iostreams/device/file_descriptor.hpp 2010-06-14 11:56:00 EDT (Mon, 14 Jun 2010)
@@ -115,7 +115,7 @@
     // open overload taking a detail::path
     void open( const detail::path& path,
                BOOST_IOS::openmode,
- BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out );
+ BOOST_IOS::openmode = BOOST_IOS::openmode(0) );
 
     typedef detail::file_descriptor_impl impl_type;
     shared_ptr<impl_type> pimpl_;

Modified: trunk/libs/iostreams/src/file_descriptor.cpp
==============================================================================
--- trunk/libs/iostreams/src/file_descriptor.cpp (original)
+++ trunk/libs/iostreams/src/file_descriptor.cpp 2010-06-14 11:56:00 EDT (Mon, 14 Jun 2010)
@@ -113,18 +113,26 @@
         dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
         dwCreationDisposition =
             (mode & BOOST_IOS::trunc) ?
- OPEN_ALWAYS :
+ CREATE_ALWAYS :
                 OPEN_EXISTING;
     } else if (mode & BOOST_IOS::in) {
- if (mode & (BOOST_IOS::app |BOOST_IOS::trunc))
+ if (mode & (BOOST_IOS::app | BOOST_IOS::trunc))
             boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
         dwDesiredAccess = GENERIC_READ;
         dwCreationDisposition = OPEN_EXISTING;
     } else if (mode & BOOST_IOS::out) {
+ if ( (mode & (BOOST_IOS::app | BOOST_IOS::trunc))
+ ==
+ (BOOST_IOS::app | BOOST_IOS::trunc) )
+ boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
         dwDesiredAccess = GENERIC_WRITE;
         dwCreationDisposition = OPEN_ALWAYS;
- if (mode & BOOST_IOS::app)
+ if (mode & BOOST_IOS::app) {
+ dwCreationDisposition = OPEN_ALWAYS;
             flags_ |= append;
+ } else {
+ dwCreationDisposition = CREATE_ALWAYS;
+ }
     } else {
         boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
     }
@@ -160,19 +168,30 @@
              ==
          (BOOST_IOS::in | BOOST_IOS::out) )
     {
- assert(!(mode & BOOST_IOS::app));
+ if( mode & BOOST_IOS::app )
+ boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
         oflag |= O_RDWR;
+ if( mode & BOOST_IOS::trunc ) {
+ oflag |= O_TRUNC;
+ oflag |= O_CREAT;
+ }
     } else if (mode & BOOST_IOS::in) {
- assert(!(mode & (BOOST_IOS::app |BOOST_IOS::trunc)));
+ if( mode & (BOOST_IOS::app | BOOST_IOS::trunc) )
+ boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
         oflag |= O_RDONLY;
     } else if (mode & BOOST_IOS::out) {
+ if( mode & (BOOST_IOS::app | BOOST_IOS::trunc)
+ ==
+ (BOOST_IOS::app | BOOST_IOS::trunc) )
+ boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode"));
         oflag |= O_WRONLY;
- mode |= BOOST_IOS::trunc;
         if (mode & BOOST_IOS::app)
             oflag |= O_APPEND;
+ else {
+ oflag |= O_CREAT;
+ oflag |= O_TRUNC;
+ }
     }
- if (mode & BOOST_IOS::trunc)
- oflag |= O_CREAT;
     #ifdef _LARGEFILE64_SOURCE
         oflag |= O_LARGEFILE;
     #endif

Modified: trunk/libs/iostreams/test/detail/verification.hpp
==============================================================================
--- trunk/libs/iostreams/test/detail/verification.hpp (original)
+++ trunk/libs/iostreams/test/detail/verification.hpp 2010-06-14 11:56:00 EDT (Mon, 14 Jun 2010)
@@ -100,6 +100,13 @@
     return true;
 }
 
+template<typename Container>
+bool compare_container_and_file(Container& cnt, const std::string& file)
+{
+ std::ifstream fstrm(file.c_str(), BOOST_IOS::in | BOOST_IOS::binary);
+ return compare_container_and_stream(cnt, fstrm);
+}
+
 BOOST_TEMPLATE_DECL
 void write_data_in_chars(BOOST_OSTREAM& os)
 {

Modified: trunk/libs/iostreams/test/file_descriptor_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/file_descriptor_test.cpp (original)
+++ trunk/libs/iostreams/test/file_descriptor_test.cpp 2010-06-14 11:56:00 EDT (Mon, 14 Jun 2010)
@@ -80,9 +80,41 @@
         first->close();
         BOOST_CHECK(!first->is_open());
     }
+
+ // test illegal flag combinations
+ {
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::app | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::out),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::out | BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::out | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_source(test1.name(),
+ BOOST_IOS::out | BOOST_IOS::app | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ }
 
     //--------------Test file_descriptor_sink---------------------------------//
-
+
     {
         temp_file temp;
         file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
@@ -142,11 +174,78 @@
         file.close();
         BOOST_CHECK(!file.is_open());
     }
+
+ {
+ temp_file temp;
+ // set up the tests
+ {
+ file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
+ fdostream out(file);
+ write_data_in_chunks(out);
+ out.close();
+ file.close();
+ }
+ // test std::ios_base::app
+ {
+ file_descriptor_sink file(temp.name(), BOOST_IOS::app);
+ fdostream out(file);
+ BOOST_CHECK(out->is_open());
+ write_data_in_chars(out);
+ out.close();
+ std::string expected(narrow_data());
+ expected += narrow_data();
+ BOOST_CHECK_MESSAGE(
+ compare_container_and_file(expected, temp.name()),
+ "failed writing to file_descriptor_sink in append mode"
+ );
+ file.close();
+ BOOST_CHECK(!file.is_open());
+ }
+ // test std::ios_base::trunc
+ {
+ file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
+ fdostream out(file);
+ BOOST_CHECK(out->is_open());
+ write_data_in_chars(out);
+ out.close();
+ BOOST_CHECK_MESSAGE(
+ compare_files(test1.name(), temp.name()),
+ "failed writing to file_descriptor_sink in trunc mode"
+ );
+ file.close();
+ BOOST_CHECK(!file.is_open());
+ }
+
+ // test illegal flag combinations
+ {
+ BOOST_CHECK_THROW(
+ file_descriptor_sink(temp.name(),
+ BOOST_IOS::trunc | BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_sink(temp.name(),
+ BOOST_IOS::in),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_sink(temp.name(),
+ BOOST_IOS::in | BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_sink(temp.name(),
+ BOOST_IOS::in | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor_sink(temp.name(),
+ BOOST_IOS::in | BOOST_IOS::trunc | BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ }
+ }
 
     //--Test seeking with file_descriptor_source and file_descriptor_sink-----//
 
+ test_file test3;
     {
- file_descriptor_sink sink(test1.name());
+ file_descriptor_sink sink(test3.name());
         fdostream out(sink);
         BOOST_CHECK(out->is_open());
         BOOST_CHECK_MESSAGE(
@@ -156,7 +255,7 @@
         out->close();
         BOOST_CHECK(!out->is_open());
 
- file_descriptor_source source(test1.name());
+ file_descriptor_source source(test3.name());
         fdistream in(source);
         BOOST_CHECK(in->is_open());
         BOOST_CHECK_MESSAGE(
@@ -196,6 +295,216 @@
             "failed seeking within a file_descriptor, in chunks"
         );
     }
+
+ //--------------Test read-only file_descriptor----------------------------//
+
+ {
+ fdstream first(file_descriptor(test1.name(), BOOST_IOS::in), 0);
+ ifstream second(test2.name().c_str());
+ BOOST_CHECK(first->is_open());
+ write_data_in_chars(first);
+ BOOST_CHECK(first.fail());
+ first.clear();
+ BOOST_CHECK_MESSAGE(
+ compare_streams_in_chars(first, second),
+ "failed reading from file_descriptor in chars with no buffer"
+ );
+ first->close();
+ BOOST_CHECK(!first->is_open());
+ }
+
+ {
+ fdstream first(file_descriptor(test1.name(), BOOST_IOS::in), 0);
+ ifstream second(test2.name().c_str());
+ BOOST_CHECK(first->is_open());
+ write_data_in_chunks(first);
+ BOOST_CHECK(first.fail());
+ first.clear();
+ BOOST_CHECK_MESSAGE(
+ compare_streams_in_chunks(first, second),
+ "failed reading from file_descriptor in chunks with no buffer"
+ );
+ first->close();
+ BOOST_CHECK(!first->is_open());
+ }
+
+ {
+ file_descriptor file(test1.name(), BOOST_IOS::in);
+ fdstream first(file);
+ ifstream second(test2.name().c_str());
+ BOOST_CHECK(first->is_open());
+ write_data_in_chars(first);
+ BOOST_CHECK(first.fail());
+ first.clear();
+ first.seekg(0, BOOST_IOS::beg);
+ BOOST_CHECK_MESSAGE(
+ compare_streams_in_chars(first, second),
+ "failed reading from file_descriptor in chars with buffer"
+ );
+ first->close();
+ BOOST_CHECK(!first->is_open());
+ }
+
+ {
+ file_descriptor file(test1.name(), BOOST_IOS::in);
+ fdstream first(file);
+ ifstream second(test2.name().c_str());
+ BOOST_CHECK(first->is_open());
+ write_data_in_chunks(first);
+ BOOST_CHECK(first.fail());
+ first.clear();
+ first.seekg(0, BOOST_IOS::beg);
+ BOOST_CHECK_MESSAGE(
+ compare_streams_in_chunks(first, second),
+ "failed reading from file_descriptor in chunks with buffer"
+ );
+ first->close();
+ BOOST_CHECK(!first->is_open());
+ }
+
+ //--------------Test write-only file_descriptor---------------------------//
+ {
+ temp_file temp;
+ file_descriptor file( temp.name(),
+ BOOST_IOS::out |
+ BOOST_IOS::trunc );
+ fdstream out(file, 0);
+ BOOST_CHECK(out->is_open());
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ write_data_in_chars(out);
+ out.seekg(0, BOOST_IOS::beg);
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ out.close();
+ BOOST_CHECK_MESSAGE(
+ compare_files(test1.name(), temp.name()),
+ "failed writing to file_descriptor in chars with no buffer"
+ );
+ file.close();
+ BOOST_CHECK(!file.is_open());
+ }
+
+ {
+ temp_file temp;
+ file_descriptor file( temp.name(),
+ BOOST_IOS::out |
+ BOOST_IOS::trunc );
+ fdstream out(file, 0);
+ BOOST_CHECK(out->is_open());
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ write_data_in_chunks(out);
+ out.seekg(0, BOOST_IOS::beg);
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ out.close();
+ BOOST_CHECK_MESSAGE(
+ compare_files(test1.name(), temp.name()),
+ "failed writing to file_descriptor_sink in chunks with no buffer"
+ );
+ file.close();
+ BOOST_CHECK(!file.is_open());
+ }
+
+ {
+ temp_file temp;
+ file_descriptor file( temp.name(),
+ BOOST_IOS::out |
+ BOOST_IOS::trunc );
+ fdstream out(file);
+ BOOST_CHECK(out->is_open());
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ write_data_in_chars(out);
+ out.seekg(0, BOOST_IOS::beg);
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ out.close();
+ BOOST_CHECK_MESSAGE(
+ compare_files(test1.name(), temp.name()),
+ "failed writing to file_descriptor_sink in chars with buffer"
+ );
+ file.close();
+ BOOST_CHECK(!file.is_open());
+ }
+
+ {
+ temp_file temp;
+ file_descriptor file( temp.name(),
+ BOOST_IOS::out |
+ BOOST_IOS::trunc );
+ fdstream out(file);
+ BOOST_CHECK(out->is_open());
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ write_data_in_chunks(out);
+ out.seekg(0, BOOST_IOS::beg);
+ out.get();
+ BOOST_CHECK(out.fail());
+ out.clear();
+ out.close();
+ BOOST_CHECK_MESSAGE(
+ compare_files(test1.name(), temp.name()),
+ "failed writing to file_descriptor_sink in chunks with buffer"
+ );
+ file.close();
+ BOOST_CHECK(!file.is_open());
+ }
+
+ // test illegal flag combinations
+ {
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::openmode(0)),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::app | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::in | BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::in | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::in | BOOST_IOS::app | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::out | BOOST_IOS::app | BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::in | BOOST_IOS::out | BOOST_IOS::app),
+ BOOST_IOSTREAMS_FAILURE);
+ BOOST_CHECK_THROW(
+ file_descriptor(test1.name(),
+ BOOST_IOS::in |
+ BOOST_IOS::out |
+ BOOST_IOS::app |
+ BOOST_IOS::trunc),
+ BOOST_IOSTREAMS_FAILURE);
+ }
 }
 
 test_suite* init_unit_test_suite(int, char* [])


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