|
Boost-Commit : |
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"
);
}
}
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