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_BUFFERS_HPP_INCLUDED
9    	#define BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
10   	
11   	#if defined(_MSC_VER)
12   	# pragma once
13   	#endif              
14   	
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>
25   	
26   	namespace boost { namespace iostreams { namespace detail {
27   	
28   	//----------------Buffers-----------------------------------------------------//
29   	
30   	//
31   	// Template name: buffer
32   	// Description: Character buffer.
33   	// Template parameters:
34   	//     Ch - The character type.
35   	//     Alloc - The Allocator type.
36   	//
37   	template< typename Ch,
38   	          typename Alloc = std::allocator<Ch> >
39   	class basic_buffer {
40   	private:
41   	#ifndef BOOST_NO_STD_ALLOCATOR
42   	#if defined(BOOST_NO_CXX11_ALLOCATOR)
43   	    typedef typename Alloc::template rebind<Ch>::other allocator_type;
44   	#else
45   	    typedef typename std::allocator_traits<Alloc>::template rebind_alloc<Ch> allocator_type;
46   	    typedef std::allocator_traits<allocator_type> allocator_traits;
47   	#endif
48   	#else
49   	    typedef std::allocator<Ch> allocator_type;
50   	#endif
51   	    static Ch* allocate(std::streamsize buffer_size);
52   	public:
53   	    basic_buffer();
54   	    basic_buffer(std::streamsize buffer_size);
55   	    ~basic_buffer();
56   	    void resize(std::streamsize buffer_size);
57   	    Ch* begin() const { return buf_; }
58   	    Ch* end() const { return buf_ + size_; }
59   	    Ch* data() const { return buf_; }
60   	    std::streamsize size() const { return size_; }
61   	    void swap(basic_buffer& rhs);
62   	private:
63   	    // Disallow copying and assignment.
64   	    basic_buffer(const basic_buffer&);
65   	    basic_buffer& operator=(const basic_buffer&);
66   	    Ch*              buf_;
67   	    std::streamsize  size_;
68   	};
69   	
70   	template<typename Ch, typename Alloc>
71   	void swap(basic_buffer<Ch, Alloc>& lhs, basic_buffer<Ch, Alloc>& rhs)
72   	{ lhs.swap(rhs); }
73   	
74   	//
75   	// Template name: buffer
76   	// Description: Character buffer with two pointers accessible via ptr() and
77   	//      eptr().
78   	// Template parameters:
79   	//     Ch - A character type.
80   	//
81   	template< typename Ch,
82   	          typename Alloc = std::allocator<Ch> >
83   	class buffer : public basic_buffer<Ch, Alloc> {
84   	private:
85   	    typedef basic_buffer<Ch, Alloc> base;
86   	public:
87   	    typedef iostreams::char_traits<Ch> traits_type;
88   	    using base::resize; 
89   	    using base::data; 
90   	    using base::size;
91   	    typedef Ch* const const_pointer;
92   	    buffer(std::streamsize buffer_size);
93   	    Ch* & ptr() { return ptr_; }
94   	    const_pointer& ptr() const { return ptr_; }
95   	    Ch* & eptr() { return eptr_; }
96   	    const_pointer& eptr() const { return eptr_; }
97   	    void set(std::streamsize ptr, std::streamsize end);
98   	    void swap(buffer& rhs);
99   	
100  	    // Returns an int_type as a status code.
101  	    template<typename Source>
102  	    typename int_type_of<Source>::type fill(Source& src) 
103  	    {
104  	        using namespace std;
105  	        std::streamsize keep;
106  	        if ((keep = static_cast<std::streamsize>(eptr_ - ptr_)) > 0)
107  	            traits_type::move(
108  	                this->data(),
109  	                ptr_, 
110  	                static_cast<size_t>(keep)
111  	            );
112  	        set(0, keep);
113  	        std::streamsize result = 
114  	            iostreams::read(src, this->data() + keep, this->size() - keep);
115  	        if (result != -1)
116  	            this->set(0, keep + result);
117  	        return result == -1 ?
118  	            traits_type::eof() :
119  	                result == 0 ?
120  	                    traits_type::would_block() :
121  	                    traits_type::good();
122  	
123  	    }
124  	
125  	    // Returns true if one or more characters were written.
126  	    template<typename Sink>
127  	    bool flush(Sink& dest) 
128  	    {
129  	        using namespace std;
130  	        std::streamsize amt = static_cast<std::streamsize>(eptr_ - ptr_);
131  	        std::streamsize result = iostreams::write_if(dest, ptr_, amt);
132  	        if (result < amt) {
133  	            traits_type::move( this->data(), 
134  	                               ptr_ + static_cast<size_t>(result), 
135  	                               static_cast<size_t>(amt - result) );
136  	        }
137  	        this->set(0, amt - result);
138  	        return result != 0;
139  	    }
140  	private:
(1) Event member_decl: Class member declaration for "ptr_".
(3) Event member_decl: Class member declaration for "eptr_".
Also see events: [uninit_member][uninit_member]
141  	    Ch *ptr_, *eptr_;
142  	};
143  	
144  	template<typename Ch, typename Alloc>
145  	void swap(buffer<Ch, Alloc>& lhs, buffer<Ch, Alloc>& rhs)
146  	{ lhs.swap(rhs); }
147  	
148  	//--------------Implementation of basic_buffer--------------------------------//
149  	
150  	template<typename Ch, typename Alloc>
151  	basic_buffer<Ch, Alloc>::basic_buffer() : buf_(0), size_(0) { }
152  	
153  	template<typename Ch, typename Alloc>
154  	inline Ch* basic_buffer<Ch, Alloc>::allocate(std::streamsize buffer_size)
155  	{
156  	#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR)
157  	    return static_cast<Ch*>(allocator_type().allocate(
158  	           static_cast<BOOST_DEDUCED_TYPENAME Alloc::size_type>(buffer_size), 0));
159  	#else
160  	    allocator_type alloc;
161  	    return static_cast<Ch*>(allocator_traits::allocate(alloc,
162  	           static_cast<BOOST_DEDUCED_TYPENAME allocator_traits::size_type>(buffer_size)));
163  	#endif
164  	}
165  	
166  	template<typename Ch, typename Alloc>
167  	basic_buffer<Ch, Alloc>::basic_buffer(std::streamsize buffer_size)
168  	    : buf_(allocate(buffer_size)),
169  	      size_(buffer_size) // Cast for SunPro 5.3.
170  	    { }
171  	
172  	template<typename Ch, typename Alloc>
173  	inline basic_buffer<Ch, Alloc>::~basic_buffer()
174  	{
175  	    if (buf_) {
176  	#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR)
177  	        allocator_type().deallocate(buf_,
178  	            static_cast<BOOST_DEDUCED_TYPENAME Alloc::size_type>(size_));
179  	#else
180  	        allocator_type alloc;
181  	        allocator_traits::deallocate(alloc, buf_,
182  	            static_cast<BOOST_DEDUCED_TYPENAME allocator_traits::size_type>(size_));
183  	#endif
184  	    }
185  	}
186  	
187  	template<typename Ch, typename Alloc>
188  	inline void basic_buffer<Ch, Alloc>::resize(std::streamsize buffer_size)
189  	{
190  	    if (size_ != buffer_size) {
191  	        basic_buffer<Ch, Alloc> temp(buffer_size);
192  	        std::swap(size_, temp.size_);
193  	        std::swap(buf_, temp.buf_);
194  	    }
195  	}
196  	
197  	template<typename Ch, typename Alloc>
198  	void basic_buffer<Ch, Alloc>::swap(basic_buffer& rhs) 
199  	{ 
200  	    std::swap(buf_, rhs.buf_); 
201  	    std::swap(size_, rhs.size_); 
202  	}
203  	
204  	//--------------Implementation of buffer--------------------------------------//
205  	
206  	template<typename Ch, typename Alloc>
207  	buffer<Ch, Alloc>::buffer(std::streamsize buffer_size)
(2) Event uninit_member: Non-static class member "ptr_" is not initialized in this constructor nor in any functions that it calls.
(4) Event uninit_member: Non-static class member "eptr_" is not initialized in this constructor nor in any functions that it calls.
Also see events: [member_decl][member_decl]
208  	    : basic_buffer<Ch, Alloc>(buffer_size) { }
209  	
210  	template<typename Ch, typename Alloc>
211  	inline void buffer<Ch, Alloc>::set(std::streamsize ptr, std::streamsize end)
212  	{ 
213  	    ptr_ = data() + ptr; 
214  	    eptr_ = data() + end; 
215  	}
216  	
217  	template<typename Ch, typename Alloc>
218  	inline void buffer<Ch, Alloc>::swap(buffer& rhs) 
219  	{ 
220  	    base::swap(rhs); 
221  	    std::swap(ptr_, rhs.ptr_); 
222  	    std::swap(eptr_, rhs.eptr_); 
223  	}
224  	
225  	//----------------------------------------------------------------------------//
226  	
227  	} } } // End namespaces detail, iostreams, boost.
228  	
229  	#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
230