1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2005-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
6 // See http://www.boost.org/libs/iostreams for documentation.
8 #ifndef BOOST_IOSTREAMS_CONTAINTER_DEVICE_HPP_INCLUDED
9 #define BOOST_IOSTREAMS_CONTAINTER_DEVICE_HPP_INCLUDED
11 #include <algorithm> // copy, min.
13 #include <boost/config.hpp> // BOOST_NO_STDC_NAMESPACE.
14 #include <boost/iostreams/categories.hpp>
15 #include <boost/iostreams/detail/ios.hpp> // failure.
17 namespace boost
{ namespace iostreams
{ namespace example
{
20 // Model of Source which reads from an STL-compatible sequence
21 // whose iterators are random-access iterators.
23 template<typename Container
>
24 class container_source
{
26 typedef typename
Container::value_type char_type
;
27 typedef source_tag category
;
28 container_source(Container
& container
)
29 : container_(container
), pos_(0)
31 std::streamsize
read(char_type
* s
, std::streamsize n
)
35 static_cast<std::streamsize
>(container_
.size() - pos_
);
36 std::streamsize result
= (min
)(n
, amt
);
38 std::copy( container_
.begin() + pos_
,
39 container_
.begin() + pos_
+ result
,
47 Container
& container() { return container_
; }
49 container_source
operator=(const container_source
&);
50 typedef typename
Container::size_type size_type
;
51 Container
& container_
;
56 // Model of Sink which appends to an STL-compatible sequence.
58 template<typename Container
>
59 class container_sink
{
61 typedef typename
Container::value_type char_type
;
62 typedef sink_tag category
;
63 container_sink(Container
& container
) : container_(container
) { }
64 std::streamsize
write(const char_type
* s
, std::streamsize n
)
66 container_
.insert(container_
.end(), s
, s
+ n
);
69 Container
& container() { return container_
; }
71 container_sink
operator=(const container_sink
&);
72 Container
& container_
;
76 // Model of SeekableDevice which accessS an TL-compatible sequence
77 // whose iterators are random-access iterators.
79 template<typename Container
>
80 class container_device
{
82 typedef typename
Container::value_type char_type
;
83 typedef seekable_device_tag category
;
84 container_device(Container
& container
)
85 : container_(container
), pos_(0)
88 std::streamsize
read(char_type
* s
, std::streamsize n
)
92 static_cast<std::streamsize
>(container_
.size() - pos_
);
93 std::streamsize result
= (min
)(n
, amt
);
95 std::copy( container_
.begin() + pos_
,
96 container_
.begin() + pos_
+ result
,
104 std::streamsize
write(const char_type
* s
, std::streamsize n
)
107 std::streamsize result
= 0;
108 if (pos_
!= container_
.size()) {
109 std::streamsize amt
=
110 static_cast<std::streamsize
>(container_
.size() - pos_
);
111 result
= (min
)(n
, amt
);
112 std::copy(s
, s
+ result
, container_
.begin() + pos_
);
116 container_
.insert(container_
.end(), s
, s
+ n
);
117 pos_
= container_
.size();
121 stream_offset
seek(stream_offset off
, BOOST_IOS::seekdir way
)
125 // Determine new value of pos_
127 if (way
== BOOST_IOS::beg
) {
129 } else if (way
== BOOST_IOS::cur
) {
131 } else if (way
== BOOST_IOS::end
) {
132 next
= container_
.size() + off
- 1;
134 throw BOOST_IOSTREAMS_FAILURE("bad seek direction");
138 if (next
< 0 || next
>= container_
.size())
139 throw BOOST_IOSTREAMS_FAILURE("bad seek offset");
145 Container
& container() { return container_
; }
147 container_device
operator=(const container_device
&);
148 typedef typename
Container::size_type size_type
;
149 Container
& container_
;
153 } } } // End namespaces example, iostreams, boost.
155 #endif // #ifndef BOOST_IOSTREAMS_CONTAINTER_DEVICE_HPP_INCLUDED