Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / iostreams / detail / streambuf / direct_streambuf.hpp
1 // (C) Copyright Jonathan Turkanis 2003.
2 // Distributed under the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5 // See http://www.boost.org/libs/iostreams for documentation.
6
7 #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED
8 #define BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED
9
10 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
11 # pragma once
12 #endif              
13
14 #include <cassert>
15 #include <cstddef>
16 #include <typeinfo>
17 #include <utility>                              // pair.
18 #include <boost/config.hpp>                     // BOOST_DEDUCED_TYPENAME.
19 #include <boost/iostreams/detail/char_traits.hpp>
20 #include <boost/iostreams/detail/config/wide_streams.hpp>
21 #include <boost/iostreams/detail/ios.hpp>
22 #include <boost/iostreams/detail/optional.hpp>
23 #include <boost/iostreams/detail/streambuf.hpp>
24 #include <boost/iostreams/detail/streambuf/linked_streambuf.hpp>
25 #include <boost/iostreams/detail/error.hpp>
26 #include <boost/iostreams/operations.hpp>
27 #include <boost/iostreams/positioning.hpp>
28 #include <boost/iostreams/traits.hpp>
29
30 // Must come last.
31 #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
32
33 namespace boost { namespace iostreams { 
34     
35 namespace detail {
36
37 template< typename T,
38           typename Tr = 
39               BOOST_IOSTREAMS_CHAR_TRAITS(
40                  BOOST_DEDUCED_TYPENAME char_type_of<T>::type 
41               ) >
42 class direct_streambuf 
43     : public linked_streambuf<BOOST_DEDUCED_TYPENAME char_type_of<T>::type, Tr>
44 {
45 public:
46     typedef typename char_type_of<T>::type                char_type;
47     BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
48 private:
49     typedef linked_streambuf<char_type, traits_type>      base_type;
50     typedef typename category_of<T>::type                 category;
51     typedef BOOST_IOSTREAMS_BASIC_STREAMBUF(
52                 char_type, traits_type
53             )                                             streambuf_type;
54 public: // stream needs access.
55     void open(const T& t, int buffer_size, int pback_size);
56     bool is_open() const;
57     void close();
58     bool auto_close() const { return auto_close_; }
59     void set_auto_close(bool close) { auto_close_ = close; }
60     bool strict_sync() { return true; }
61
62     // Declared in linked_streambuf.
63     T* component() { return storage_.get(); }
64 protected:
65 #if !BOOST_WORKAROUND(__GNUC__, == 2)
66     BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type)
67 #endif
68     direct_streambuf();
69
70     //--------------Virtual functions-----------------------------------------//
71
72     // Declared in linked_streambuf.
73     void close(BOOST_IOS::openmode m);
74     const std::type_info& component_type() const { return typeid(T); }
75     void* component_impl() { return component(); } 
76
77 #ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
78     public:
79 #endif
80
81     // Declared in basic_streambuf.
82     int_type underflow();
83     int_type pbackfail(int_type c);
84     int_type overflow(int_type c);
85     pos_type seekoff( off_type off, BOOST_IOS::seekdir way,
86                       BOOST_IOS::openmode which );
87     pos_type seekpos(pos_type sp, BOOST_IOS::openmode which);
88 private:
89     pos_type seek_impl( stream_offset off, BOOST_IOS::seekdir way,
90                         BOOST_IOS::openmode which );
91     void init_input(any_tag) { }
92     void init_input(input);
93     void init_output(any_tag) { }
94     void init_output(output);
95     void init_get_area();
96     void init_put_area();
97     bool one_head() const;
98     bool two_head() const;
99     optional<T>  storage_;
100     char_type   *ibeg_, *iend_, *obeg_, *oend_;
101     bool         auto_close_;
102 };
103                     
104 //------------------Implementation of direct_streambuf------------------------//
105
106 template<typename T, typename Tr>
107 direct_streambuf<T, Tr>::direct_streambuf() 
108     : ibeg_(0), iend_(0), obeg_(0), oend_(0), auto_close_(true) 
109 { this->set_true_eof(true); }
110
111 template<typename T, typename Tr>
112 void direct_streambuf<T, Tr>::open(const T& t, int, int)
113 {
114     storage_.reset(t);
115     init_input(category());
116     init_output(category());
117     setg(0, 0, 0);
118     setp(0, 0);
119 }
120
121 template<typename T, typename Tr>
122 bool direct_streambuf<T, Tr>::is_open() const 
123 { return ibeg_ != 0 && !obeg_ != 0; }
124
125 template<typename T, typename Tr>
126 void direct_streambuf<T, Tr>::close() 
127
128     using namespace std;
129     try { close(BOOST_IOS::in); } catch (std::exception&) { }
130     try { close(BOOST_IOS::out); } catch (std::exception&) { }
131     storage_.reset();
132 }
133
134 template<typename T, typename Tr>
135 typename direct_streambuf<T, Tr>::int_type 
136 direct_streambuf<T, Tr>::underflow()
137 {
138     if (!ibeg_) 
139         throw cant_read();
140     if (!gptr()) 
141         init_get_area();
142     return gptr() != iend_ ? 
143         traits_type::to_int_type(*gptr()) : 
144         traits_type::eof();
145 }
146
147 template<typename T, typename Tr>
148 typename direct_streambuf<T, Tr>::int_type 
149 direct_streambuf<T, Tr>::pbackfail(int_type c)
150 {
151     using namespace std;
152     if (!ibeg_) 
153         throw cant_read();
154     if (gptr() != 0 && gptr() != ibeg_) {
155         gbump(-1);
156         if (!traits_type::eq_int_type(c, traits_type::eof()))
157             *gptr() = traits_type::to_char_type(c);
158         return traits_type::not_eof(c);
159     }
160     throw bad_putback();
161 }
162
163 template<typename T, typename Tr>
164 typename direct_streambuf<T, Tr>::int_type 
165 direct_streambuf<T, Tr>::overflow(int_type c)
166 {
167     using namespace std;
168     if (!obeg_) throw BOOST_IOSTREAMS_FAILURE("no write access");
169     if (!pptr()) init_put_area();
170     if (!traits_type::eq_int_type(c, traits_type::eof())) {
171         if (pptr() == oend_)
172             throw BOOST_IOSTREAMS_FAILURE("write area exhausted");
173         *pptr() = traits_type::to_char_type(c);
174         pbump(1);
175         return c;
176     }
177     return traits_type::not_eof(c);
178 }
179
180 template<typename T, typename Tr>
181 inline typename direct_streambuf<T, Tr>::pos_type
182 direct_streambuf<T, Tr>::seekoff
183     (off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
184 { return seek_impl(off, way, which); }
185
186 template<typename T, typename Tr>
187 inline typename direct_streambuf<T, Tr>::pos_type
188 direct_streambuf<T, Tr>::seekpos
189     (pos_type sp, BOOST_IOS::openmode)
190
191     return seek_impl( position_to_offset(sp), BOOST_IOS::beg, 
192                       BOOST_IOS::in | BOOST_IOS::out );
193 }
194
195 template<typename T, typename Tr>
196 void direct_streambuf<T, Tr>::close(BOOST_IOS::openmode which)
197 {
198     if (which == BOOST_IOS::in && ibeg_ != 0) {
199         setg(0, 0, 0);
200         ibeg_ = iend_ = 0;
201     }
202     if (which == BOOST_IOS::out && obeg_ != 0) {
203         sync();
204         setp(0, 0);
205         obeg_ = oend_ = 0;
206     }
207     boost::iostreams::close(*storage_, which);
208 }
209
210 template<typename T, typename Tr>
211 typename direct_streambuf<T, Tr>::pos_type direct_streambuf<T, Tr>::seek_impl
212     (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
213 {
214     using namespace std;
215     BOOST_IOS::openmode both = BOOST_IOS::in | BOOST_IOS::out;
216     if (two_head() && (which & both) == both)
217         throw bad_seek();
218     stream_offset result = -1;
219     bool one = one_head();
220     if (one && (pptr() != 0 || gptr()== 0))
221         init_get_area(); // Switch to input mode, for code reuse.
222     if (one || (which & BOOST_IOS::in) != 0 && ibeg_ != 0) {
223         if (!gptr()) setg(ibeg_, ibeg_, iend_);
224         ptrdiff_t next = 0;
225         switch (way) {
226         case BOOST_IOS::beg: next = off; break;
227         case BOOST_IOS::cur: next = (gptr() - ibeg_) + off; break;
228         case BOOST_IOS::end: next = (iend_ - ibeg_) + off; break;
229         default: assert(0);
230         }
231         if (next < 0 || next > (iend_ - ibeg_))
232             throw bad_seek();
233         setg(ibeg_, ibeg_ + next, iend_);
234         result = next;
235     }
236     if (!one && (which & BOOST_IOS::out) != 0 && obeg_ != 0) {
237         if (!pptr()) setp(obeg_, oend_);
238         ptrdiff_t next = 0;
239         switch (way) {
240         case BOOST_IOS::beg: next = off; break;
241         case BOOST_IOS::cur: next = (pptr() - obeg_) + off; break;
242         case BOOST_IOS::end: next = (oend_ - obeg_) + off; break;
243         default: assert(0);
244         }
245         if (next < 0 || next > (oend_ - obeg_))
246             throw bad_seek();
247         pbump(static_cast<int>(next - (pptr() - obeg_)));
248         result = next;
249     }
250     return offset_to_position(result);
251 }
252
253 template<typename T, typename Tr>
254 void direct_streambuf<T, Tr>::init_input(input)
255 {
256     std::pair<char_type*, char_type*> p = input_sequence(*storage_);
257     ibeg_ = p.first;
258     iend_ = p.second;
259 }
260
261 template<typename T, typename Tr>
262 void direct_streambuf<T, Tr>::init_output(output)
263 {
264     std::pair<char_type*, char_type*> p = output_sequence(*storage_);
265     obeg_ = p.first;
266     oend_ = p.second;
267 }
268
269 template<typename T, typename Tr>
270 void direct_streambuf<T, Tr>::init_get_area()
271 {
272     setg(ibeg_, ibeg_, iend_);
273     if (one_head() && pptr()) {
274         gbump(static_cast<int>(pptr() - obeg_));
275         setp(0, 0);
276     }
277 }
278
279 template<typename T, typename Tr>
280 void direct_streambuf<T, Tr>::init_put_area()
281 {
282     setp(obeg_, oend_);
283     if (one_head() && gptr()) {
284         pbump(static_cast<int>(gptr() - ibeg_));
285         setg(0, 0, 0);
286     }
287 }
288
289 template<typename T, typename Tr>
290 inline bool direct_streambuf<T, Tr>::one_head() const
291 { return ibeg_ && obeg_ && ibeg_ == obeg_; }
292
293 template<typename T, typename Tr>
294 inline bool direct_streambuf<T, Tr>::two_head() const
295 { return ibeg_ && obeg_ && ibeg_ != obeg_; }
296
297 //----------------------------------------------------------------------------//
298
299 } // End namespace detail.
300
301 } } // End namespaces iostreams, boost.
302
303 #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC
304
305 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED