1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2005-2007 Jonathan Turkanis
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
// See http://www.boost.org/libs/iostreams for documentation.
#ifndef BOOST_IOSTREAMS_EXAMPLE_CONTAINTER_DEVICE_HPP_INCLUDED
#define BOOST_IOSTREAMS_EXAMPLE_CONTAINTER_DEVICE_HPP_INCLUDED
#include <algorithm> // copy, min.
#include <cassert>
#include <boost/config.hpp> // BOOST_NO_STDC_NAMESPACE.
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/detail/ios.hpp> // failure.
// Must come last.
#include <boost/iostreams/detail/config/disable_warnings.hpp>
namespace boost { namespace iostreams { namespace example {
//
// Model of Source which reads from an STL-compatible sequence
// whose iterators are random-access iterators.
//
template<typename Container>
class container_source {
public:
typedef typename Container::value_type char_type;
typedef source_tag category;
container_source(Container& container)
: container_(container), pos_(0)
{ }
std::streamsize read(char_type* s, std::streamsize n)
{
using namespace std;
std::streamsize amt =
static_cast<std::streamsize>(container_.size() - pos_);
std::streamsize result = (min)(n, amt);
if (result != 0) {
std::copy( container_.begin() + pos_,
container_.begin() + pos_ + result,
s );
pos_ += result;
return result;
} else {
return -1; // EOF
}
}
Container& container() { return container_; }
private:
container_source operator=(const container_source&);
typedef typename Container::size_type size_type;
Container& container_;
size_type pos_;
};
//
// Model of Sink which appends to an STL-compatible sequence.
//
template<typename Container>
class container_sink {
public:
typedef typename Container::value_type char_type;
typedef sink_tag category;
container_sink(Container& container) : container_(container) { }
std::streamsize write(const char_type* s, std::streamsize n)
{
container_.insert(container_.end(), s, s + n);
return n;
}
Container& container() { return container_; }
private:
container_sink operator=(const container_sink&);
Container& container_;
};
//
// Model of SeekableDevice which accessS an TL-compatible sequence
// whose iterators are random-access iterators.
//
template<typename Container>
class container_device {
public:
typedef typename Container::value_type char_type;
typedef seekable_device_tag category;
container_device(Container& container)
: container_(container), pos_(0)
{ }
std::streamsize read(char_type* s, std::streamsize n)
{
using namespace std;
std::streamsize amt =
static_cast<std::streamsize>(container_.size() - pos_);
std::streamsize result = (min)(n, amt);
if (result != 0) {
std::copy( container_.begin() + pos_,
container_.begin() + pos_ + result,
s );
pos_ += result;
return result;
} else {
return -1; // EOF
}
}
std::streamsize write(const char_type* s, std::streamsize n)
{
using namespace std;
std::streamsize result = 0;
if (pos_ != container_.size()) {
std::streamsize amt =
static_cast<std::streamsize>(container_.size() - pos_);
result = (min)(n, amt);
std::copy(s, s + result, container_.begin() + pos_);
pos_ += result;
}
if (result < n) {
container_.insert(container_.end(), s, s + n);
pos_ = container_.size();
}
return n;
}
stream_offset seek(stream_offset off, BOOST_IOS::seekdir way)
{
using namespace std;
// Determine new value of pos_
stream_offset next;
if (way == BOOST_IOS::beg) {
next = off;
} else if (way == BOOST_IOS::cur) {
next = pos_ + off;
} else if (way == BOOST_IOS::end) {
next = container_.size() + off - 1;
} else {
throw BOOST_IOSTREAMS_FAILURE("bad seek direction");
}
// Check for errors
if (next < 0 || next > static_cast<stream_offset>(container_.size()))
throw BOOST_IOSTREAMS_FAILURE("bad seek offset");
pos_ = next;
return pos_;
}
Container& container() { return container_; }
private:
container_device operator=(const container_device&);
typedef typename Container::size_type size_type;
Container& container_;
size_type pos_;
};
} } } // End namespaces example, iostreams, boost.
#include <boost/iostreams/detail/config/enable_warnings.hpp>
#endif // #ifndef BOOST_IOSTREAMS_EXAMPLE_CONTAINTER_DEVICE_HPP_INCLUDED
|