diff --git a/include/boost/iostreams/detail/adapter/basic_adapter.hpp b/include/boost/iostreams/detail/adapter/basic_adapter.hpp new file mode 100755 index 0000000..6135890 --- /dev/null +++ b/include/boost/iostreams/detail/adapter/basic_adapter.hpp @@ -0,0 +1,69 @@ +// (C) Copyright Jonathan Turkanis 2005. +// 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 BOOST_IOSTREAMS_DETAIL_BASIC_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BASIC_ADAPTER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class basic_adapter { +private: + typedef typename detail::value_type::type value_type; + typedef typename detail::param_type::type param_type; +public: + explicit basic_adapter(param_type t) : t_(t) { } + T& component() { return t_; } + + void close(BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out) + { + BOOST_STATIC_ASSERT(is_device::value); + iostreams::close(t_, which); + } + + template + void close( Device& dev, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ) + { + BOOST_STATIC_ASSERT(is_filter::value); + iostreams::close(t_, dev, which); + } + + bool flush() + { + BOOST_STATIC_ASSERT(is_device::value); + return iostreams::flush(t_); + } + + template + void flush(Device& dev) + { + BOOST_STATIC_ASSERT(is_filter::value); + return iostreams::flush(t_, dev); + } + + template // Avoid dependency on + void imbue(const Locale& loc) { iostreams::imbue(t_, loc); } + + std::streamsize optimal_buffer_size() const + { return iostreams::optimal_buffer_size(t_); } +public: + value_type t_; +}; + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BASIC_ADAPTER_HPP_INCLUDED diff --git a/include/boost/iostreams/detail/adapter/forward_container.hpp b/include/boost/iostreams/detail/adapter/forward_container.hpp new file mode 100755 index 0000000..a7e0221 --- /dev/null +++ b/include/boost/iostreams/detail/adapter/forward_container.hpp @@ -0,0 +1,80 @@ +// (C) Copyright Jonathan Turkanis 2003. +// 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 BOOST_IOSTREAMS_DETAIL_FORWARD_CONTAINER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FORWARD_CONTAINER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class forward_container { +public: + BOOST_STATIC_ASSERT((!is_convertible::value)); + typedef Container container_type; + typedef typename Container::value_type char_type; + struct io_category + : device_tag, + Mode + { }; + forward_container(Container* cnt, bool owns) + : pimpl_(new impl(cnt, owns)) + { } + std::streamsize read(char_type* s, std::streamsize n) + { + BOOST_STATIC_ASSERT((is_convertible::value)); + iterator last = cnt().end(); + std::streamsize result = 0; + while (pimpl_->ptr_ != last && result < n) { + *s++ = *pimpl_->ptr_++; + ++result; + } + return result; + } + void write(const char_type* s, std::streamsize n) + { + BOOST_STATIC_ASSERT((is_convertible::value)); + const char_type* s_end = s + n; + iterator p_end = cnt().end(); + while (pimpl_->ptr_ != p_end && s != s_end) + *pimpl_->ptr_++ = *s++; + if (s != s_end) { + cnt().insert(cnt().end(), s, s_end); + pimpl_->ptr_ = cnt().end(); + } + } + Container container() const { return *pimpl_->cnt_; } + void container(const Container& cnt) + { + shared_ptr pimpl(new impl(new Container(cnt), true)); + pimpl_.swap(pimpl); + } +private: + Container& cnt() { return *pimpl_->cnt_; } + typedef typename Container::iterator iterator; + struct impl { + impl(Container* cnt, bool owns) + : cnt_(cnt), owns_(owns), ptr_(cnt->begin()) { } + ~impl() { if (owns_) delete cnt_; } + Container* cnt_; + bool owns_; + iterator ptr_; + }; + shared_ptr pimpl_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FORWARD_CONTAINER_HPP_INCLUDED diff --git a/include/boost/iostreams/detail/adapter/random_access_container.hpp b/include/boost/iostreams/detail/adapter/random_access_container.hpp new file mode 100755 index 0000000..4315a41 --- /dev/null +++ b/include/boost/iostreams/detail/adapter/random_access_container.hpp @@ -0,0 +1,175 @@ +// (C) Copyright Jonathan Turkanis 2003. +// 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 BOOST_IOSTREAMS_DETAIL_RANDOM_ACCESS_CONTAINER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_RANDOM_ACCESS_CONTAINER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // streamoff. +#include // make sure size_t is in std. +#include // copy, min. +#include // size_t. +#include +#include +#include // openmode, seekdir, int types. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +struct one_file_pointer { + one_file_pointer() : ptr_(0) { } + std::size_t& gptr() { return ptr_; } + std::size_t& pptr() { return ptr_; } + std::size_t ptr_; +}; + +struct two_file_pointers { + two_file_pointers() : gptr_(0), pptr_(0) { } + std::size_t& gptr() { return gptr_; } + std::size_t& pptr() { return pptr_; } + std::size_t gptr_; + std::size_t pptr_; +}; + +template +struct file_pointers + : mpl::if_< + is_convertible, + two_file_pointers, + one_file_pointer + >::type + { }; + +template +class random_access_container { +public: + typedef Container container_type; + typedef typename Container::value_type char_type; + struct io_category + : device_tag, + Mode + { }; + random_access_container(Container* cnt, bool owns) + : pimpl_(new impl(cnt, owns)) + { } + std::streamsize read(char_type* s, std::streamsize n); + void write(const char_type* s, std::streamsize n); + std::streamoff seek( std::streamoff, BOOST_IOS::seekdir, + BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out ); + Container container() const { return *pimpl_->cnt_; } + void container(const Container& cnt) + { + shared_ptr pimpl(new impl(new Container(cnt), true)); + pimpl_.swap(pimpl); + } +private: + Container& cnt() { return *pimpl_->cnt_; } + typedef typename Container::size_type size_type; + struct impl : file_pointers { + impl(Container* cnt, bool owns) : cnt_(cnt), owns_(owns) { } + ~impl() { if (owns_) delete cnt_; } + Container* cnt_; + bool owns_; + }; + shared_ptr pimpl_; +}; + +//------------------Implementation of random_access_container-----------------// + +template +std::streamsize random_access_container::read + (char_type* s, std::streamsize n) +{ + BOOST_STATIC_ASSERT((is_convertible::value)); + using namespace std; + streamsize avail = + static_cast(cnt().size() - pimpl_->gptr()); + streamsize result = (std::min)(n, avail); + copy( cnt().begin() + pimpl_->gptr(), // Loop might be safer. + cnt().begin() + pimpl_->gptr() + result, + s ); + pimpl_->gptr() += result; + return result; +} + +template +void random_access_container::write + (const char_type* s, std::streamsize n) +{ + BOOST_STATIC_ASSERT((is_convertible::value)); + using namespace std; + streamsize capacity = + static_cast(cnt().size() - pimpl_->pptr()); + streamsize amt = (std::min)(n, capacity); + copy(s, s + amt, cnt().begin() + pimpl_->pptr()); // Loop might be safer. + pimpl_->pptr() += amt; + if (amt < n) { + cnt().insert(cnt().end(), s + amt, s + n); + pimpl_->pptr() = static_cast(cnt().size()); + } +} + +template +std::streamoff random_access_container::seek + (std::streamoff off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ + using namespace std; + if (way == BOOST_IOS::cur && pimpl_->gptr() != pimpl_->pptr()) + bad_seek(); + bool dual = is_convertible::value; + if ((which & BOOST_IOS::in) || !dual) { + std::size_t next; + switch (way) { + case BOOST_IOS::beg: + next = off; + break; + case BOOST_IOS::cur: + next = pimpl_->gptr() + off; + break; + case BOOST_IOS::end: + next = cnt().size() + off; + break; + } + if (next >= 0 && next < cnt().size()) + pimpl_->gptr() = next; + else + bad_seek(); + } + if ((which & BOOST_IOS::out) && dual) { + std::size_t next; + switch (way) { + case BOOST_IOS::beg: + next = off; + break; + case BOOST_IOS::cur: + next = pimpl_->pptr() + off; + break; + case BOOST_IOS::end: + next = cnt().size() + off; + break; + } + if (next >= 0 && next < cnt().size()) + pimpl_->pptr() = next; + else + bad_seek(); + } + return static_cast( + (which & BOOST_IOS::in) ? + pimpl_->gptr() : + pimpl_->pptr() + ); +} + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_RANDOM_ACCESS_CONTAINER_HPP_INCLUDED