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