File indexing completed on 2025-01-18 09:38:49
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
0010
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif
0014
0015 #include <algorithm> // swap.
0016 #include <memory> // allocator.
0017 #include <boost/config.hpp> // member templates.
0018 #include <boost/iostreams/char_traits.hpp>
0019 #include <boost/iostreams/detail/ios.hpp> // streamsize.
0020 #include <boost/iostreams/read.hpp>
0021 #include <boost/iostreams/traits.hpp> // int_type_of.
0022 #include <boost/iostreams/checked_operations.hpp>
0023 #include <boost/mpl/if.hpp>
0024 #include <boost/type_traits/is_same.hpp>
0025
0026 namespace boost { namespace iostreams { namespace detail {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 template< typename Ch,
0038 typename Alloc = std::allocator<Ch> >
0039 class basic_buffer {
0040 private:
0041 #ifndef BOOST_NO_STD_ALLOCATOR
0042 #if defined(BOOST_NO_CXX11_ALLOCATOR)
0043 typedef typename Alloc::template rebind<Ch>::other allocator_type;
0044 #else
0045 typedef typename std::allocator_traits<Alloc>::template rebind_alloc<Ch> allocator_type;
0046 typedef std::allocator_traits<allocator_type> allocator_traits;
0047 #endif
0048 #else
0049 typedef std::allocator<Ch> allocator_type;
0050 #endif
0051 static Ch* allocate(std::streamsize buffer_size);
0052 public:
0053 basic_buffer();
0054 basic_buffer(std::streamsize buffer_size);
0055 ~basic_buffer();
0056 void resize(std::streamsize buffer_size);
0057 Ch* begin() const { return buf_; }
0058 Ch* end() const { return buf_ + size_; }
0059 Ch* data() const { return buf_; }
0060 std::streamsize size() const { return size_; }
0061 void swap(basic_buffer& rhs);
0062 private:
0063
0064 basic_buffer(const basic_buffer&);
0065 basic_buffer& operator=(const basic_buffer&);
0066 Ch* buf_;
0067 std::streamsize size_;
0068 };
0069
0070 template<typename Ch, typename Alloc>
0071 void swap(basic_buffer<Ch, Alloc>& lhs, basic_buffer<Ch, Alloc>& rhs)
0072 { lhs.swap(rhs); }
0073
0074
0075
0076
0077
0078
0079
0080
0081 template< typename Ch,
0082 typename Alloc = std::allocator<Ch> >
0083 class buffer : public basic_buffer<Ch, Alloc> {
0084 private:
0085 typedef basic_buffer<Ch, Alloc> base;
0086 public:
0087 typedef iostreams::char_traits<Ch> traits_type;
0088 using base::resize;
0089 using base::data;
0090 using base::size;
0091 typedef Ch* const const_pointer;
0092 buffer(std::streamsize buffer_size);
0093 Ch* & ptr() { return ptr_; }
0094 const_pointer& ptr() const { return ptr_; }
0095 Ch* & eptr() { return eptr_; }
0096 const_pointer& eptr() const { return eptr_; }
0097 void set(std::streamsize ptr, std::streamsize end);
0098 void swap(buffer& rhs);
0099
0100
0101 template<typename Source>
0102 typename int_type_of<Source>::type fill(Source& src)
0103 {
0104 using namespace std;
0105 std::streamsize keep;
0106 if ((keep = static_cast<std::streamsize>(eptr_ - ptr_)) > 0)
0107 traits_type::move(
0108 this->data(),
0109 ptr_,
0110 static_cast<size_t>(keep)
0111 );
0112 set(0, keep);
0113 std::streamsize result =
0114 iostreams::read(src, this->data() + keep, this->size() - keep);
0115 if (result != -1)
0116 this->set(0, keep + result);
0117 return result == -1 ?
0118 traits_type::eof() :
0119 result == 0 ?
0120 traits_type::would_block() :
0121 traits_type::good();
0122
0123 }
0124
0125
0126 template<typename Sink>
0127 bool flush(Sink& dest)
0128 {
0129 using namespace std;
0130 std::streamsize amt = static_cast<std::streamsize>(eptr_ - ptr_);
0131 std::streamsize result = iostreams::write_if(dest, ptr_, amt);
0132 if (result < amt) {
0133 traits_type::move( this->data(),
0134 ptr_ + static_cast<size_t>(result),
0135 static_cast<size_t>(amt - result) );
0136 }
0137 this->set(0, amt - result);
0138 return result != 0;
0139 }
0140 private:
0141 Ch *ptr_, *eptr_;
0142 };
0143
0144 template<typename Ch, typename Alloc>
0145 void swap(buffer<Ch, Alloc>& lhs, buffer<Ch, Alloc>& rhs)
0146 { lhs.swap(rhs); }
0147
0148
0149
0150 template<typename Ch, typename Alloc>
0151 basic_buffer<Ch, Alloc>::basic_buffer() : buf_(0), size_(0) { }
0152
0153 template<typename Ch, typename Alloc>
0154 inline Ch* basic_buffer<Ch, Alloc>::allocate(std::streamsize buffer_size)
0155 {
0156 #if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR)
0157 return static_cast<Ch*>(allocator_type().allocate(
0158 static_cast<BOOST_DEDUCED_TYPENAME Alloc::size_type>(buffer_size), 0));
0159 #else
0160 allocator_type alloc;
0161 return static_cast<Ch*>(allocator_traits::allocate(alloc,
0162 static_cast<BOOST_DEDUCED_TYPENAME allocator_traits::size_type>(buffer_size)));
0163 #endif
0164 }
0165
0166 template<typename Ch, typename Alloc>
0167 basic_buffer<Ch, Alloc>::basic_buffer(std::streamsize buffer_size)
0168 : buf_(allocate(buffer_size)),
0169 size_(buffer_size)
0170 { }
0171
0172 template<typename Ch, typename Alloc>
0173 inline basic_buffer<Ch, Alloc>::~basic_buffer()
0174 {
0175 if (buf_) {
0176 #if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR)
0177 allocator_type().deallocate(buf_,
0178 static_cast<BOOST_DEDUCED_TYPENAME Alloc::size_type>(size_));
0179 #else
0180 allocator_type alloc;
0181 allocator_traits::deallocate(alloc, buf_,
0182 static_cast<BOOST_DEDUCED_TYPENAME allocator_traits::size_type>(size_));
0183 #endif
0184 }
0185 }
0186
0187 template<typename Ch, typename Alloc>
0188 inline void basic_buffer<Ch, Alloc>::resize(std::streamsize buffer_size)
0189 {
0190 if (size_ != buffer_size) {
0191 basic_buffer<Ch, Alloc> temp(buffer_size);
0192 std::swap(size_, temp.size_);
0193 std::swap(buf_, temp.buf_);
0194 }
0195 }
0196
0197 template<typename Ch, typename Alloc>
0198 void basic_buffer<Ch, Alloc>::swap(basic_buffer& rhs)
0199 {
0200 std::swap(buf_, rhs.buf_);
0201 std::swap(size_, rhs.size_);
0202 }
0203
0204
0205
0206 template<typename Ch, typename Alloc>
0207 buffer<Ch, Alloc>::buffer(std::streamsize buffer_size)
0208 : basic_buffer<Ch, Alloc>(buffer_size), ptr_(data()), eptr_(data() + buffer_size) { }
0209
0210 template<typename Ch, typename Alloc>
0211 inline void buffer<Ch, Alloc>::set(std::streamsize ptr, std::streamsize end)
0212 {
0213 ptr_ = data() + ptr;
0214 eptr_ = data() + end;
0215 }
0216
0217 template<typename Ch, typename Alloc>
0218 inline void buffer<Ch, Alloc>::swap(buffer& rhs)
0219 {
0220 base::swap(rhs);
0221 std::swap(ptr_, rhs.ptr_);
0222 std::swap(eptr_, rhs.eptr_);
0223 }
0224
0225
0226
0227 } } }
0228
0229 #endif