source: NonGTP/Boost/boost/iostreams/detail/buffer.hpp @ 857

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