$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: technews_at_[hidden]
Date: 2007-12-25 03:49:38
Author: turkanis
Date: 2007-12-25 03:49:37 EST (Tue, 25 Dec 2007)
New Revision: 42294
URL: http://svn.boost.org/trac/boost/changeset/42294
Log:
fixed issues #786 and (duplicate) #1070
Text files modified: 
   branches/iostreams_dev/boost/iostreams/copy.hpp          |    41 +++++++----                             
   branches/iostreams_dev/libs/iostreams/test/copy_test.cpp |   137 +++++++++++++++++++++++++++++++-------- 
   2 files changed, 132 insertions(+), 46 deletions(-)
Modified: branches/iostreams_dev/boost/iostreams/copy.hpp
==============================================================================
--- branches/iostreams_dev/boost/iostreams/copy.hpp	(original)
+++ branches/iostreams_dev/boost/iostreams/copy.hpp	2007-12-25 03:49:37 EST (Tue, 25 Dec 2007)
@@ -18,7 +18,9 @@
 # pragma once
 #endif              
 
-#include <algorithm>                        // copy.
+#include <boost/config.hpp>                 // Make sure ptrdiff_t is in std.
+#include <algorithm>                        // copy, min.
+#include <cstddef>                          // ptrdiff_t.
 #include <utility>                          // pair.
 #include <boost/bind.hpp>
 #include <boost/detail/workaround.hpp>
@@ -57,12 +59,12 @@
     typedef pair<char_type*, char_type*>         pair_type;
     pair_type p1 = iostreams::input_sequence(src);
     pair_type p2 = iostreams::output_sequence(snk);
-    if (p1.second - p1.first < p2.second - p2.first) {
-        std::copy(p1.first, p1.second, p2.first);
-        return static_cast<streamsize>(p1.second - p1.first);
-    } else {
-        throw BOOST_IOSTREAMS_FAILURE("destination too small");
-    }
+    streamsize total = 
+        static_cast<streamsize>(
+            (std::min)(p1.second - p1.first, p2.second - p2.first)
+        );
+    std::copy(p1.first, p1.first + total, p2.first);
+    return total;
 }
 
 // Copy from a direct source to an indirect sink
@@ -83,7 +85,7 @@
             iostreams::write(snk, p.first + total, size - total); 
         total += amt;
     }
-    return size;
+    return total;
 }
 
 // Copy from an indirect source to a direct sink
@@ -98,23 +100,28 @@
     detail::basic_buffer<char_type>  buf(buffer_size);
     pair_type                        p = snk.output_sequence();
     streamsize                       total = 0;
-    bool                             done  = false;
-    while (!done) {
-        streamsize amt;
-        done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1;
+    ptrdiff_t                        capacity = p.second - p.first;
+    while (true) {
+        streamsize amt = 
+            iostreams::read(
+                src, 
+                buf.data(),
+                (std::min)(buffer_size, capacity - total)
+            );
+        if (amt == -1)
+            break;
         std::copy(buf.data(), buf.data() + amt, p.first + total);
-        if (amt != -1)
-            total += amt;
+        total += amt;
     }
     return total;
 }
 
-// Copy from an indirect source to a direct sink
+// Copy from an indirect source to an indirect sink
 template<typename Source, typename Sink>
 std::streamsize copy_impl( Source& src, Sink& snk, 
                            std::streamsize buffer_size,
                            mpl::false_, mpl::false_ )
-{   // This algorithm can be improved by eliminating the non_blocking_adapter.
+{ 
     typedef typename char_type_of<Source>::type char_type;
     detail::basic_buffer<char_type>  buf(buffer_size);
     non_blocking_adapter<Sink>       nb(snk);
@@ -221,7 +228,7 @@
 { 
     typedef typename char_type_of<Source>::type char_type;
     return detail::copy_impl( detail::resolve<input, char_type>(src), 
-                              detail::wrap(snk), buffer_size);
+                              detail::wrap(snk), buffer_size );
 }
 
 // Overload of copy() for the case where neither the source nor the sink is
Modified: branches/iostreams_dev/libs/iostreams/test/copy_test.cpp
==============================================================================
--- branches/iostreams_dev/libs/iostreams/test/copy_test.cpp	(original)
+++ branches/iostreams_dev/libs/iostreams/test/copy_test.cpp	2007-12-25 03:49:37 EST (Tue, 25 Dec 2007)
@@ -4,68 +4,147 @@
 
 // See http://www.boost.org/libs/iostreams for documentation.
 
-#include <fstream>
+#include <algorithm>         // Equal
+#include <vector>
 #include <boost/config.hpp>  // MSVC.
 #include <boost/detail/workaround.hpp>
+#include <boost/iostreams/concepts.hpp>  // sink
 #include <boost/iostreams/copy.hpp>
+#include <boost/iostreams/device/array.hpp>
 #include <boost/iostreams/device/file.hpp>
+#include <boost/iostreams/stream.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
-#include "detail/temp_file.hpp"
-#include "detail/verification.hpp"
+#include "../example/container_device.hpp"
+#include "detail/sequence.hpp"
 
 using namespace std;
 using namespace boost;
 using namespace boost::iostreams;
+using namespace boost::iostreams::example;
 using namespace boost::iostreams::test;
 using boost::unit_test::test_suite;
+                    
+//------------------Definition of fixed_sink----------------------------------//
+
+/*class fixed_sink : public sink {
+public:
+    fixed_sink(vector<char>& storage)
+        : storage_(storage), pos_(0)
+        { }
+    std::streamsize write(const char_type* s, std::streamsize n)
+    {
+        streamsize capacity = static_cast<streamsize>(storage_.size() - pos_);
+        streamsize result = (min)(n, capacity);
+        std::copy(s, s + result, storage_.begin() + pos_);
+        pos_ += result;
+        return result;
+    }
+private:
+    fixed_sink operator=(const fixed_sink&);
+    typedef vector<char>::size_type size_type;
+    vector<char>&  storage_;
+    size_type      pos_;
+};*/
+
+//------------------Definition of stream types--------------------------------//
+
+typedef container_source< vector<char> >  vector_source;
+typedef container_sink< vector<char> >    vector_sink;
+typedef stream<vector_source>             vector_istream;
+typedef stream<vector_sink>               vector_ostream;
+//typedef stream<fixed_sink>              fixed_ostream;
+
+//------------------Definition of copy_test-----------------------------------//
 
 void copy_test()
 {
-    test_file test;         
-
+    // Stream to stream
     {
-        temp_file  dest;
-        ifstream   first(test.name().c_str(), in_mode);
-        ofstream   second(dest.name().c_str(), out_mode);
-        boost::iostreams::copy(first, second);
-        first.close();
-        second.close();
+        test_sequence<>  src;
+        vector<char>     dest;
+        vector_istream   first;
+        vector_ostream   second;
+        first.open(vector_source(src));
+        second.open(vector_sink(dest));
         BOOST_CHECK_MESSAGE(
-            compare_files(test.name(), dest.name()),
+            boost::iostreams::copy(first, second) == src.size() && src == dest,
             "failed copying from stream to stream"
         );
     }
 
+    // Stream to indirect sink
+    {
+        test_sequence<>  src;
+        vector<char>     dest;
+        vector_istream   in;
+        vector_sink      out(dest);
+        in.open(vector_source(src));
+        BOOST_CHECK_MESSAGE(
+            boost::iostreams::copy(in, out) == src.size() && src == dest,
+            "failed copying from stream to indirect sink"
+        );
+    }
+
+    // Indirect source to stream
+    {
+        test_sequence<>  src;
+        vector<char>     dest;
+        vector_source    in(src);
+        vector_ostream   out;
+        out.open(vector_sink(dest));
+        BOOST_CHECK_MESSAGE(
+            boost::iostreams::copy(in, out) == src.size() && src == dest,
+            "failed copying from indirect source to stream"
+        );
+    }
+
+    // Indirect source to indirect sink
+    {
+        test_sequence<>  src;
+        vector<char>     dest;
+        vector_source    in(src);
+        vector_sink      out(dest);
+        BOOST_CHECK_MESSAGE(
+            boost::iostreams::copy(in, out) == src.size() && src == dest,
+            "failed copying from indirect source to indirect sink"
+        );
+    }
+
+    // Direct source to direct sink
     {
-        temp_file  dest;
-        ifstream   first(test.name().c_str(), in_mode);
-        boost::iostreams::copy(first, file_sink(dest.name(), out_mode));
-        first.close();
+        test_sequence<>  src;
+        vector<char>     dest(src.size(), '?');
+        array_source     in(&src[0], &src[0] + src.size());
+        array_sink       out(&dest[0], &dest[0] + dest.size());
         BOOST_CHECK_MESSAGE(
-            compare_files(test.name(), dest.name()),
-            "failed copying from stream to file_sink"
+            boost::iostreams::copy(in, out) == src.size() && src == dest,
+            "failed copying from direct source to direct sink"
         );
     }
 
+    // Direct source to indirect sink
     {
-        temp_file  dest;
-        ofstream   second(dest.name().c_str(), out_mode);
-        boost::iostreams::copy(file_source(test.name(), in_mode), second);
-        second.close();
+        test_sequence<>  src;
+        vector<char>     dest;
+        array_source     in(&src[0], &src[0] + src.size());
+        vector_ostream   out(dest);
         BOOST_CHECK_MESSAGE(
-            compare_files(test.name(), dest.name()),
-            "failed copying from file_source to stream"
+            boost::iostreams::copy(in, out) == src.size() && src == dest,
+            "failed copying from direct source to indirect sink"
         );
     }
 
+    // Indirect source to direct sink
     {
-        temp_file dest;
-        boost::iostreams::copy( file_source(test.name(), in_mode),
-                                file_sink(dest.name(), out_mode) );
+        test_sequence<>  src;
+        vector<char>     dest(src.size(), '?');
+        vector_istream   in;
+        array_sink       out(&dest[0], &dest[0] + dest.size());
+        in.open(vector_source(src));
         BOOST_CHECK_MESSAGE(
-            compare_files(test.name(), dest.name()),
-            "failed copying from file_source to file_sink"
+            boost::iostreams::copy(in, out) == src.size() && src == dest,
+            "failed copying from indirect source to direct sink"
         );
     }
 }