sl@0
|
1 |
// (C) Copyright Jonathan Turkanis 2003-5.
|
sl@0
|
2 |
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
sl@0
|
3 |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
sl@0
|
4 |
|
sl@0
|
5 |
// See http://www.boost.org/libs/iostreams for documentation.
|
sl@0
|
6 |
|
sl@0
|
7 |
#ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
|
sl@0
|
8 |
#define BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
|
sl@0
|
9 |
|
sl@0
|
10 |
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
sl@0
|
11 |
# pragma once
|
sl@0
|
12 |
#endif
|
sl@0
|
13 |
|
sl@0
|
14 |
#include <algorithm> // swap.
|
sl@0
|
15 |
#include <memory> // allocator.
|
sl@0
|
16 |
#include <boost/config.hpp> // member templates.
|
sl@0
|
17 |
#include <boost/iostreams/char_traits.hpp>
|
sl@0
|
18 |
#include <boost/iostreams/detail/ios.hpp> // streamsize.
|
sl@0
|
19 |
#include <boost/iostreams/read.hpp>
|
sl@0
|
20 |
#include <boost/iostreams/traits.hpp> // int_type_of.
|
sl@0
|
21 |
#include <boost/iostreams/checked_operations.hpp>
|
sl@0
|
22 |
#include <boost/mpl/if.hpp>
|
sl@0
|
23 |
#include <boost/type_traits/is_same.hpp>
|
sl@0
|
24 |
|
sl@0
|
25 |
namespace boost { namespace iostreams { namespace detail {
|
sl@0
|
26 |
|
sl@0
|
27 |
//----------------Buffers-----------------------------------------------------//
|
sl@0
|
28 |
|
sl@0
|
29 |
//
|
sl@0
|
30 |
// Template name: buffer
|
sl@0
|
31 |
// Description: Character buffer.
|
sl@0
|
32 |
// Template paramters:
|
sl@0
|
33 |
// Ch - The character type.
|
sl@0
|
34 |
// Alloc - The Allocator type.
|
sl@0
|
35 |
//
|
sl@0
|
36 |
template< typename Ch,
|
sl@0
|
37 |
typename Alloc = std::allocator<Ch> >
|
sl@0
|
38 |
class basic_buffer {
|
sl@0
|
39 |
private:
|
sl@0
|
40 |
#ifndef BOOST_NO_STD_ALLOCATOR
|
sl@0
|
41 |
typedef typename Alloc::template rebind<Ch>::other allocator_type;
|
sl@0
|
42 |
#else
|
sl@0
|
43 |
typedef std::allocator<Ch> allocator_type;
|
sl@0
|
44 |
#endif
|
sl@0
|
45 |
public:
|
sl@0
|
46 |
basic_buffer();
|
sl@0
|
47 |
basic_buffer(int buffer_size);
|
sl@0
|
48 |
~basic_buffer();
|
sl@0
|
49 |
void resize(int buffer_size);
|
sl@0
|
50 |
Ch* begin() const { return buf_; }
|
sl@0
|
51 |
Ch* end() const { return buf_ + size_; }
|
sl@0
|
52 |
Ch* data() const { return buf_; }
|
sl@0
|
53 |
std::streamsize size() const { return size_; }
|
sl@0
|
54 |
void swap(basic_buffer& rhs);
|
sl@0
|
55 |
private:
|
sl@0
|
56 |
// Disallow copying and assignment.
|
sl@0
|
57 |
basic_buffer(const basic_buffer&);
|
sl@0
|
58 |
basic_buffer& operator=(const basic_buffer&);
|
sl@0
|
59 |
Ch* buf_;
|
sl@0
|
60 |
std::streamsize size_;
|
sl@0
|
61 |
};
|
sl@0
|
62 |
|
sl@0
|
63 |
template<typename Ch, typename Alloc>
|
sl@0
|
64 |
void swap(basic_buffer<Ch, Alloc>& lhs, basic_buffer<Ch, Alloc>& rhs)
|
sl@0
|
65 |
{ lhs.swap(rhs); }
|
sl@0
|
66 |
|
sl@0
|
67 |
//
|
sl@0
|
68 |
// Template name: buffer
|
sl@0
|
69 |
// Description: Character buffer with two pointers accessible via ptr() and
|
sl@0
|
70 |
// eptr().
|
sl@0
|
71 |
// Template paramters:
|
sl@0
|
72 |
// Ch - A character type.
|
sl@0
|
73 |
//
|
sl@0
|
74 |
template< typename Ch,
|
sl@0
|
75 |
typename Alloc = std::allocator<Ch> >
|
sl@0
|
76 |
class buffer : public basic_buffer<Ch, Alloc> {
|
sl@0
|
77 |
private:
|
sl@0
|
78 |
typedef basic_buffer<Ch, Alloc> base;
|
sl@0
|
79 |
public:
|
sl@0
|
80 |
typedef iostreams::char_traits<Ch> traits_type;
|
sl@0
|
81 |
using base::resize;
|
sl@0
|
82 |
using base::data;
|
sl@0
|
83 |
using base::size;
|
sl@0
|
84 |
typedef Ch* const const_pointer;
|
sl@0
|
85 |
buffer(int buffer_size);
|
sl@0
|
86 |
Ch* & ptr() { return ptr_; }
|
sl@0
|
87 |
const_pointer& ptr() const { return ptr_; }
|
sl@0
|
88 |
Ch* & eptr() { return eptr_; }
|
sl@0
|
89 |
const_pointer& eptr() const { return eptr_; }
|
sl@0
|
90 |
void set(std::streamsize ptr, std::streamsize end);
|
sl@0
|
91 |
void swap(buffer& rhs);
|
sl@0
|
92 |
|
sl@0
|
93 |
// Returns an int_type as a status code.
|
sl@0
|
94 |
template<typename Source>
|
sl@0
|
95 |
typename int_type_of<Source>::type fill(Source& src)
|
sl@0
|
96 |
{
|
sl@0
|
97 |
using namespace std;
|
sl@0
|
98 |
streamsize keep;
|
sl@0
|
99 |
if ((keep = static_cast<streamsize>(eptr_ - ptr_)) > 0)
|
sl@0
|
100 |
traits_type::move(this->data(), ptr_, keep);
|
sl@0
|
101 |
set(0, keep);
|
sl@0
|
102 |
streamsize result =
|
sl@0
|
103 |
iostreams::read(src, this->data() + keep, this->size() - keep);
|
sl@0
|
104 |
if (result != -1)
|
sl@0
|
105 |
this->set(0, keep + result);
|
sl@0
|
106 |
//return result == this->size() - keep ?
|
sl@0
|
107 |
// traits_type::good() :
|
sl@0
|
108 |
// keep == -1 ?
|
sl@0
|
109 |
// traits_type::eof() :
|
sl@0
|
110 |
// traits_type::would_block();
|
sl@0
|
111 |
return result == -1 ?
|
sl@0
|
112 |
traits_type::eof() :
|
sl@0
|
113 |
result == 0 ?
|
sl@0
|
114 |
traits_type::would_block() :
|
sl@0
|
115 |
traits_type::good();
|
sl@0
|
116 |
|
sl@0
|
117 |
}
|
sl@0
|
118 |
|
sl@0
|
119 |
// Returns true if one or more characters were written.
|
sl@0
|
120 |
template<typename Sink>
|
sl@0
|
121 |
bool flush(Sink& dest)
|
sl@0
|
122 |
{
|
sl@0
|
123 |
using namespace std;
|
sl@0
|
124 |
streamsize amt = static_cast<std::streamsize>(eptr_ - ptr_);
|
sl@0
|
125 |
streamsize result = iostreams::write_if(dest, ptr_, amt);
|
sl@0
|
126 |
if (result < amt) {
|
sl@0
|
127 |
traits_type::move( this->data(),
|
sl@0
|
128 |
ptr_ + result,
|
sl@0
|
129 |
amt - result );
|
sl@0
|
130 |
}
|
sl@0
|
131 |
this->set(0, amt - result);
|
sl@0
|
132 |
return result != 0;
|
sl@0
|
133 |
}
|
sl@0
|
134 |
private:
|
sl@0
|
135 |
Ch *ptr_, *eptr_;
|
sl@0
|
136 |
};
|
sl@0
|
137 |
|
sl@0
|
138 |
template<typename Ch, typename Alloc>
|
sl@0
|
139 |
void swap(buffer<Ch, Alloc>& lhs, buffer<Ch, Alloc>& rhs)
|
sl@0
|
140 |
{ lhs.swap(rhs); }
|
sl@0
|
141 |
|
sl@0
|
142 |
//--------------Implementation of basic_buffer--------------------------------//
|
sl@0
|
143 |
|
sl@0
|
144 |
template<typename Ch, typename Alloc>
|
sl@0
|
145 |
basic_buffer<Ch, Alloc>::basic_buffer() : buf_(0), size_(0) { }
|
sl@0
|
146 |
|
sl@0
|
147 |
template<typename Ch, typename Alloc>
|
sl@0
|
148 |
basic_buffer<Ch, Alloc>::basic_buffer(int buffer_size)
|
sl@0
|
149 |
: buf_(static_cast<Ch*>(allocator_type().allocate(buffer_size, 0))),
|
sl@0
|
150 |
size_(buffer_size) // Cast for SunPro 5.3.
|
sl@0
|
151 |
{ }
|
sl@0
|
152 |
|
sl@0
|
153 |
template<typename Ch, typename Alloc>
|
sl@0
|
154 |
inline basic_buffer<Ch, Alloc>::~basic_buffer()
|
sl@0
|
155 |
{ if (buf_) allocator_type().deallocate(buf_, size_); }
|
sl@0
|
156 |
|
sl@0
|
157 |
template<typename Ch, typename Alloc>
|
sl@0
|
158 |
inline void basic_buffer<Ch, Alloc>::resize(int buffer_size)
|
sl@0
|
159 |
{
|
sl@0
|
160 |
if (size_ != buffer_size) {
|
sl@0
|
161 |
basic_buffer<Ch, Alloc> temp(buffer_size);
|
sl@0
|
162 |
std::swap(size_, temp.size_);
|
sl@0
|
163 |
std::swap(buf_, temp.buf_);
|
sl@0
|
164 |
}
|
sl@0
|
165 |
}
|
sl@0
|
166 |
|
sl@0
|
167 |
template<typename Ch, typename Alloc>
|
sl@0
|
168 |
void basic_buffer<Ch, Alloc>::swap(basic_buffer& rhs)
|
sl@0
|
169 |
{
|
sl@0
|
170 |
std::swap(buf_, rhs.buf_);
|
sl@0
|
171 |
std::swap(size_, rhs.size_);
|
sl@0
|
172 |
}
|
sl@0
|
173 |
|
sl@0
|
174 |
//--------------Implementation of buffer--------------------------------------//
|
sl@0
|
175 |
|
sl@0
|
176 |
template<typename Ch, typename Alloc>
|
sl@0
|
177 |
buffer<Ch, Alloc>::buffer(int buffer_size)
|
sl@0
|
178 |
: basic_buffer<Ch, Alloc>(buffer_size) { }
|
sl@0
|
179 |
|
sl@0
|
180 |
template<typename Ch, typename Alloc>
|
sl@0
|
181 |
inline void buffer<Ch, Alloc>::set(std::streamsize ptr, std::streamsize end)
|
sl@0
|
182 |
{
|
sl@0
|
183 |
ptr_ = data() + ptr;
|
sl@0
|
184 |
eptr_ = data() + end;
|
sl@0
|
185 |
}
|
sl@0
|
186 |
|
sl@0
|
187 |
template<typename Ch, typename Alloc>
|
sl@0
|
188 |
inline void buffer<Ch, Alloc>::swap(buffer& rhs)
|
sl@0
|
189 |
{
|
sl@0
|
190 |
base::swap(rhs);
|
sl@0
|
191 |
std::swap(ptr_, rhs.ptr_);
|
sl@0
|
192 |
std::swap(eptr_, rhs.eptr_);
|
sl@0
|
193 |
}
|
sl@0
|
194 |
|
sl@0
|
195 |
//----------------------------------------------------------------------------//
|
sl@0
|
196 |
|
sl@0
|
197 |
} } } // End namespaces detail, iostreams, boost.
|
sl@0
|
198 |
|
sl@0
|
199 |
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
|