| // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) |
| // (C) Copyright 2003-2007 Jonathan Turkanis |
| // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) |
| |
| // See http://www.boost.org/libs/iostreams for documentation. |
| |
| #ifndef NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED |
| #define NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| # pragma once |
| #endif |
| |
| #include <algorithm> // swap. |
| #include <memory> // allocator. |
| #include <ndnboost/config.hpp> // member templates. |
| #include <ndnboost/iostreams/char_traits.hpp> |
| #include <ndnboost/iostreams/detail/ios.hpp> // streamsize. |
| #include <ndnboost/iostreams/read.hpp> |
| #include <ndnboost/iostreams/traits.hpp> // int_type_of. |
| #include <ndnboost/iostreams/checked_operations.hpp> |
| #include <ndnboost/mpl/if.hpp> |
| #include <ndnboost/type_traits/is_same.hpp> |
| |
| namespace ndnboost { namespace iostreams { namespace detail { |
| |
| //----------------Buffers-----------------------------------------------------// |
| |
| // |
| // Template name: buffer |
| // Description: Character buffer. |
| // Template parameters: |
| // Ch - The character type. |
| // Alloc - The Allocator type. |
| // |
| template< typename Ch, |
| typename Alloc = std::allocator<Ch> > |
| class basic_buffer { |
| private: |
| #ifndef NDNBOOST_NO_STD_ALLOCATOR |
| typedef typename Alloc::template rebind<Ch>::other allocator_type; |
| #else |
| typedef std::allocator<Ch> allocator_type; |
| #endif |
| public: |
| basic_buffer(); |
| basic_buffer(int buffer_size); |
| ~basic_buffer(); |
| void resize(int buffer_size); |
| Ch* begin() const { return buf_; } |
| Ch* end() const { return buf_ + size_; } |
| Ch* data() const { return buf_; } |
| std::streamsize size() const { return size_; } |
| void swap(basic_buffer& rhs); |
| private: |
| // Disallow copying and assignment. |
| basic_buffer(const basic_buffer&); |
| basic_buffer& operator=(const basic_buffer&); |
| Ch* buf_; |
| std::streamsize size_; |
| }; |
| |
| template<typename Ch, typename Alloc> |
| void swap(basic_buffer<Ch, Alloc>& lhs, basic_buffer<Ch, Alloc>& rhs) |
| { lhs.swap(rhs); } |
| |
| // |
| // Template name: buffer |
| // Description: Character buffer with two pointers accessible via ptr() and |
| // eptr(). |
| // Template parameters: |
| // Ch - A character type. |
| // |
| template< typename Ch, |
| typename Alloc = std::allocator<Ch> > |
| class buffer : public basic_buffer<Ch, Alloc> { |
| private: |
| typedef basic_buffer<Ch, Alloc> base; |
| public: |
| typedef iostreams::char_traits<Ch> traits_type; |
| using base::resize; |
| using base::data; |
| using base::size; |
| typedef Ch* const const_pointer; |
| buffer(int buffer_size); |
| Ch* & ptr() { return ptr_; } |
| const_pointer& ptr() const { return ptr_; } |
| Ch* & eptr() { return eptr_; } |
| const_pointer& eptr() const { return eptr_; } |
| void set(std::streamsize ptr, std::streamsize end); |
| void swap(buffer& rhs); |
| |
| // Returns an int_type as a status code. |
| template<typename Source> |
| typename int_type_of<Source>::type fill(Source& src) |
| { |
| using namespace std; |
| std::streamsize keep; |
| if ((keep = static_cast<std::streamsize>(eptr_ - ptr_)) > 0) |
| traits_type::move(this->data(), ptr_, keep); |
| set(0, keep); |
| std::streamsize result = |
| iostreams::read(src, this->data() + keep, this->size() - keep); |
| if (result != -1) |
| this->set(0, keep + result); |
| return result == -1 ? |
| traits_type::eof() : |
| result == 0 ? |
| traits_type::would_block() : |
| traits_type::good(); |
| |
| } |
| |
| // Returns true if one or more characters were written. |
| template<typename Sink> |
| bool flush(Sink& dest) |
| { |
| using namespace std; |
| std::streamsize amt = static_cast<std::streamsize>(eptr_ - ptr_); |
| std::streamsize result = iostreams::write_if(dest, ptr_, amt); |
| if (result < amt) { |
| traits_type::move( this->data(), |
| ptr_ + result, |
| amt - result ); |
| } |
| this->set(0, amt - result); |
| return result != 0; |
| } |
| private: |
| Ch *ptr_, *eptr_; |
| }; |
| |
| template<typename Ch, typename Alloc> |
| void swap(buffer<Ch, Alloc>& lhs, buffer<Ch, Alloc>& rhs) |
| { lhs.swap(rhs); } |
| |
| //--------------Implementation of basic_buffer--------------------------------// |
| |
| template<typename Ch, typename Alloc> |
| basic_buffer<Ch, Alloc>::basic_buffer() : buf_(0), size_(0) { } |
| |
| template<typename Ch, typename Alloc> |
| basic_buffer<Ch, Alloc>::basic_buffer(int buffer_size) |
| : buf_(static_cast<Ch*>(allocator_type().allocate(buffer_size, 0))), |
| size_(buffer_size) // Cast for SunPro 5.3. |
| { } |
| |
| template<typename Ch, typename Alloc> |
| inline basic_buffer<Ch, Alloc>::~basic_buffer() |
| { |
| if (buf_) { |
| allocator_type().deallocate(buf_, |
| static_cast<NDNBOOST_DEDUCED_TYPENAME Alloc::size_type>(size_)); |
| } |
| } |
| |
| template<typename Ch, typename Alloc> |
| inline void basic_buffer<Ch, Alloc>::resize(int buffer_size) |
| { |
| if (size_ != buffer_size) { |
| basic_buffer<Ch, Alloc> temp(buffer_size); |
| std::swap(size_, temp.size_); |
| std::swap(buf_, temp.buf_); |
| } |
| } |
| |
| template<typename Ch, typename Alloc> |
| void basic_buffer<Ch, Alloc>::swap(basic_buffer& rhs) |
| { |
| std::swap(buf_, rhs.buf_); |
| std::swap(size_, rhs.size_); |
| } |
| |
| //--------------Implementation of buffer--------------------------------------// |
| |
| template<typename Ch, typename Alloc> |
| buffer<Ch, Alloc>::buffer(int buffer_size) |
| : basic_buffer<Ch, Alloc>(buffer_size) { } |
| |
| template<typename Ch, typename Alloc> |
| inline void buffer<Ch, Alloc>::set(std::streamsize ptr, std::streamsize end) |
| { |
| ptr_ = data() + ptr; |
| eptr_ = data() + end; |
| } |
| |
| template<typename Ch, typename Alloc> |
| inline void buffer<Ch, Alloc>::swap(buffer& rhs) |
| { |
| base::swap(rhs); |
| std::swap(ptr_, rhs.ptr_); |
| std::swap(eptr_, rhs.eptr_); |
| } |
| |
| //----------------------------------------------------------------------------// |
| |
| } } } // End namespaces detail, iostreams, boost. |
| |
| #endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED |