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