PageRenderTime 107ms CodeModel.GetById 77ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/iostreams/detail/streambuf/direct_streambuf.hpp

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