1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2003-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_DETAIL_BUFFERS_HPP_INCLUDED
9 #define BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
11 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
15 #include <algorithm> // swap.
16 #include <memory> // allocator.
17 #include <boost/config.hpp> // member templates.
18 #include <boost/iostreams/char_traits.hpp>
19 #include <boost/iostreams/detail/ios.hpp> // streamsize.
20 #include <boost/iostreams/read.hpp>
21 #include <boost/iostreams/traits.hpp> // int_type_of.
22 #include <boost/iostreams/checked_operations.hpp>
23 #include <boost/mpl/if.hpp>
24 #include <boost/type_traits/is_same.hpp>
26 namespace boost
{ namespace iostreams
{ namespace detail
{
28 //----------------Buffers-----------------------------------------------------//
31 // Template name: buffer
32 // Description: Character buffer.
33 // Template paramters:
34 // Ch - The character type.
35 // Alloc - The Allocator type.
37 template< typename Ch
,
38 typename Alloc
= std::allocator
<Ch
> >
41 #ifndef BOOST_NO_STD_ALLOCATOR
42 typedef typename
Alloc::template rebind
<Ch
>::other allocator_type
;
44 typedef std::allocator
<Ch
> allocator_type
;
48 basic_buffer(int buffer_size
);
50 void resize(int buffer_size
);
51 Ch
* begin() const { return buf_
; }
52 Ch
* end() const { return buf_
+ size_
; }
53 Ch
* data() const { return buf_
; }
54 std::streamsize
size() const { return size_
; }
55 void swap(basic_buffer
& rhs
);
57 // Disallow copying and assignment.
58 basic_buffer(const basic_buffer
&);
59 basic_buffer
& operator=(const basic_buffer
&);
61 std::streamsize size_
;
64 template<typename Ch
, typename Alloc
>
65 void swap(basic_buffer
<Ch
, Alloc
>& lhs
, basic_buffer
<Ch
, Alloc
>& rhs
)
69 // Template name: buffer
70 // Description: Character buffer with two pointers accessible via ptr() and
72 // Template paramters:
73 // Ch - A character type.
75 template< typename Ch
,
76 typename Alloc
= std::allocator
<Ch
> >
77 class buffer
: public basic_buffer
<Ch
, Alloc
> {
79 typedef basic_buffer
<Ch
, Alloc
> base
;
81 typedef iostreams::char_traits
<Ch
> traits_type
;
85 typedef Ch
* const const_pointer
;
86 buffer(int buffer_size
);
87 Ch
* & ptr() { return ptr_
; }
88 const_pointer
& ptr() const { return ptr_
; }
89 Ch
* & eptr() { return eptr_
; }
90 const_pointer
& eptr() const { return eptr_
; }
91 void set(std::streamsize ptr
, std::streamsize end
);
92 void swap(buffer
& rhs
);
94 // Returns an int_type as a status code.
95 template<typename Source
>
96 typename int_type_of
<Source
>::type
fill(Source
& src
)
100 if ((keep
= static_cast<std::streamsize
>(eptr_
- ptr_
)) > 0)
101 traits_type::move(this->data(), ptr_
, keep
);
103 std::streamsize result
=
104 iostreams::read(src
, this->data() + keep
, this->size() - keep
);
106 this->set(0, keep
+ result
);
107 return result
== -1 ?
110 traits_type::would_block() :
115 // Returns true if one or more characters were written.
116 template<typename Sink
>
117 bool flush(Sink
& dest
)
120 std::streamsize amt
= static_cast<std::streamsize
>(eptr_
- ptr_
);
121 std::streamsize result
= iostreams::write_if(dest
, ptr_
, amt
);
123 traits_type::move( this->data(),
127 this->set(0, amt
- result
);
134 template<typename Ch
, typename Alloc
>
135 void swap(buffer
<Ch
, Alloc
>& lhs
, buffer
<Ch
, Alloc
>& rhs
)
138 //--------------Implementation of basic_buffer--------------------------------//
140 template<typename Ch
, typename Alloc
>
141 basic_buffer
<Ch
, Alloc
>::basic_buffer() : buf_(0), size_(0) { }
143 template<typename Ch
, typename Alloc
>
144 basic_buffer
<Ch
, Alloc
>::basic_buffer(int buffer_size
)
145 : buf_(static_cast<Ch
*>(allocator_type().allocate(buffer_size
, 0))),
146 size_(buffer_size
) // Cast for SunPro 5.3.
149 template<typename Ch
, typename Alloc
>
150 inline basic_buffer
<Ch
, Alloc
>::~basic_buffer()
151 { if (buf_
) allocator_type().deallocate(buf_
, size_
); }
153 template<typename Ch
, typename Alloc
>
154 inline void basic_buffer
<Ch
, Alloc
>::resize(int buffer_size
)
156 if (size_
!= buffer_size
) {
157 basic_buffer
<Ch
, Alloc
> temp(buffer_size
);
158 std::swap(size_
, temp
.size_
);
159 std::swap(buf_
, temp
.buf_
);
163 template<typename Ch
, typename Alloc
>
164 void basic_buffer
<Ch
, Alloc
>::swap(basic_buffer
& rhs
)
166 std::swap(buf_
, rhs
.buf_
);
167 std::swap(size_
, rhs
.size_
);
170 //--------------Implementation of buffer--------------------------------------//
172 template<typename Ch
, typename Alloc
>
173 buffer
<Ch
, Alloc
>::buffer(int buffer_size
)
174 : basic_buffer
<Ch
, Alloc
>(buffer_size
) { }
176 template<typename Ch
, typename Alloc
>
177 inline void buffer
<Ch
, Alloc
>::set(std::streamsize ptr
, std::streamsize end
)
180 eptr_
= data() + end
;
183 template<typename Ch
, typename Alloc
>
184 inline void buffer
<Ch
, Alloc
>::swap(buffer
& rhs
)
187 std::swap(ptr_
, rhs
.ptr_
);
188 std::swap(eptr_
, rhs
.eptr_
);
191 //----------------------------------------------------------------------------//
193 } } } // End namespaces detail, iostreams, boost.
195 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED